You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bluesky-commits@incubator.apache.org by tp...@apache.org on 2008/06/04 02:48:20 UTC

svn commit: r662948 [25/31] - in /incubator/bluesky/NCstu-2.0: ./ autom4te.cache/ include/ intl/ po/ src/ src/.deps/ src/ffmpeg/ src/pic/

Added: incubator/bluesky/NCstu-2.0/src/en_de_video.cpp
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/en_de_video.cpp?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/en_de_video.cpp (added)
+++ incubator/bluesky/NCstu-2.0/src/en_de_video.cpp Tue Jun  3 19:48:16 2008
@@ -0,0 +1,5068 @@
+/*version
+*/
+static char *primary_version = "";
+static char *video_version_ = "1.2.0";
+
+
+#ifdef HAVE_1394_CONFIG_H
+#include "1394_config.h"
+#endif // HAVE_1394_CONFIG_H
+
+
+//V4l classes.
+#include <deque>
+#include <unistd.h>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+/*
+using std::ostringstream;
+using std::setw;
+using std::setfill;
+*/
+#include <pthread.h>
+
+#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "en_de_video.h"
+
+extern int v4l_dev_num = 0;
+extern int delay_time = 0;
+
+extern "C"
+{
+//#include "support.h"
+#include <sys/types.h>
+#include <sys/soundcard.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+//	pthread_t v4lthread;
+}
+
+static int ENCODE_YUV = 0;
+
+/** Send a request to the v4l device associated to a V4LStruct object.
+*/
+
+bool V4LDevice::request( int req, V4LStruct *v4l )
+{
+	ENCODE_YUV = getenv( "KINO_V4L_PATCHED" ) != NULL;
+	return request( req, v4l->getStruct() );
+}
+
+/** Send a request to the v4l device associated to an arbitrary address.
+*/
+
+bool V4LDevice::request( int req, void *addr )
+{
+	return ioctl( getHandle(), req, addr ) != -1;
+}
+
+V4LCapability::V4LCapability( V4LDevice *device )
+{
+	device->request( VIDIOCGCAP, this );
+}
+
+V4LCapability::~V4LCapability()
+{
+//	cout << "Closing Capability" << endl;
+}
+
+void *V4LCapability::getStruct()
+{
+	return & capability;
+}
+
+char *V4LCapability::getName()
+{
+	return capability.name;
+}
+
+int V4LCapability::getNumberOfChannels()
+{
+	return capability.channels;
+}
+
+int V4LCapability::getNumberOfAudioDevices()
+{
+	return capability.audios;
+}
+
+int V4LCapability::getMinWidth()
+{
+	return capability.minwidth;
+}
+
+int V4LCapability::getMinHeight()
+{
+	return capability.minheight;
+}
+
+int V4LCapability::getMaxWidth()
+{
+	return capability.maxwidth;
+}
+
+int V4LCapability::getMaxHeight()
+{
+	return capability.maxheight;
+}
+
+bool V4LCapability::canCapture()
+{
+	return capability.type & VID_TYPE_CAPTURE;
+}
+
+bool V4LCapability::hasTuner()
+{
+	return capability.type & VID_TYPE_TUNER;
+}
+
+bool V4LCapability::hasChromakey()
+{
+	return capability.type & VID_TYPE_CHROMAKEY;
+}
+
+bool V4LCapability::hasClipping()
+{
+	return capability.type & VID_TYPE_CLIPPING;
+}
+
+bool V4LCapability::hasOverwrite()
+{
+	return capability.type & VID_TYPE_FRAMERAM;
+}
+
+bool V4LCapability::hasScaling()
+{
+	return capability.type & VID_TYPE_SCALES;
+}
+
+bool V4LCapability::isMonochrome()
+{
+	return capability.type & VID_TYPE_MONOCHROME;
+}
+
+bool V4LCapability::canSubCapture()
+{
+	return capability.type & VID_TYPE_SUBCAPTURE;
+}
+
+void V4LCapability::report()
+{
+
+/*	cout << ">>> Name     : " << this->getName() << endl;
+	cout << ">>> Channels : " << this->getNumberOfChannels() << endl;
+	cout << ">>> Audio    : " << this->getNumberOfAudioDevices() << endl;
+	cout << ">>> Min Size : " << this->getMinWidth() << "," << this->getMinHeight() << endl;
+	cout << ">>> Max Size : " << this->getMaxWidth() << "," << this->getMaxHeight() << endl;
+	cout << ">>> Functions: " << endl;
+	if ( this->canCapture() )
+		cout << "     + Can capture to memory" << endl;
+	if ( this->hasTuner() )
+		cout << "     + Has a Tuner" << endl;
+	if ( this->hasChromakey() )
+		cout << "       with Chromakey" << endl;
+	if ( this->hasClipping() )
+		cout << "       with Clipping" << endl;
+	if ( this->hasOverwrite() )
+		cout << "       overwrites buffer memory" << endl;
+	if ( this->hasScaling() )
+		cout << "     + Has hardware support for image scaling" << endl;
+	if ( this->isMonochrome() )
+		cout << "     - Monochrome only" << endl;
+	if ( this->canSubCapture() )
+		cout << "     + Can capture part of the image" << endl;
+*/
+}
+
+V4LTuner::V4LTuner( V4LDevice *device, int index )
+{
+	this->device = device;
+	this->tuner.tuner = index;
+	this->device->request( VIDIOCGTUNER, this );
+}
+
+void *V4LTuner::getStruct()
+{
+	return & tuner;
+}
+
+void V4LTuner::report()
+{}
+
+int V4LTuner::getRangeLow()
+{
+	return tuner.rangelow;
+}
+
+void V4LTuner::setRangeLow( int low )
+{
+	tuner.rangelow = low;
+}
+
+int V4LTuner::getRangeHigh()
+{
+	return tuner.rangehigh;
+}
+
+void V4LTuner::setRangeHigh( int high )
+{
+	tuner.rangehigh = high;
+}
+
+int V4LTuner::getFlags()
+{
+	return tuner.flags;
+}
+
+void V4LTuner::setFlags( int flags )
+{
+	tuner.flags = flags;
+}
+
+int V4LTuner::getMode()
+{
+	return tuner.mode;
+}
+
+void V4LTuner::setMode( int mode )
+{
+	tuner.mode = mode;
+}
+
+int V4LTuner::getSignal()
+{
+	return tuner.signal;
+}
+
+V4LChannel::V4LChannel( V4LDevice *device, int index )
+{
+	memset( &channel, 0, sizeof( struct video_channel ) );
+	this->device = device;
+	this->channel.channel = index;
+	device->request( VIDIOCGCHAN, this );
+	device->request( VIDIOCSCHAN, this );
+	for ( unsigned int i = 0; i < getNumberOfTuners(); i ++ )
+	{
+		V4LTuner *tuner = new V4LTuner( this->device, i );
+		tuners.insert( tuners.end(), tuner );
+	}
+}
+
+V4LChannel::~V4LChannel()
+{
+//	cout << "Channel destroyed" << endl;
+}
+
+void *V4LChannel::getStruct()
+{
+	return & channel;
+}
+
+char *V4LChannel::getName()
+{
+	return channel.name;
+}
+
+bool V4LChannel::setTuner( unsigned int index )
+{
+	if ( index >= 0 && index < tuners.size() )
+	{
+		current = tuners[ index ];
+		// FIXME: Hardcoded tuner settings
+		current->setRangeLow( 0 );
+		current->setRangeHigh( 0xffff );
+		return device->request( VIDIOCSTUNER, current );
+	}
+	else
+	{
+		return false;
+	}
+}
+
+unsigned int V4LChannel::getNumberOfTuners()
+{
+	return channel.tuners;
+}
+
+V4LTuner *V4LChannel::getTuner( unsigned int index )
+{
+	if ( index >= 0 && index < tuners.size() )
+	{
+		return tuners[ index ];
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+int V4LChannel::getSignal()
+{
+	device->request( VIDIOCGTUNER, current );
+	return current->getSignal();
+}
+
+void V4LChannel::report()
+{
+/*	
+	cout << ">>>> Channel # " << channel.channel << endl;
+	cout << ">>>> Name    : " << this->getName() << endl;
+	cout << ">>>> Tuners  : " << this->getNumberOfTuners() << endl;
+	cout << ">>>> Flags   : " << endl;
+	if ( channel.flags & VIDEO_VC_TUNER )
+		cout << "     Channel has tuners" << endl;
+	if ( channel.flags & VIDEO_VC_AUDIO )
+		cout << "     Channel has audio" << endl;
+	cout << ">>>> Type    : " << endl;
+	if ( channel.type & VIDEO_TYPE_TV )
+		cout << "     TV" << endl;
+	if ( channel.type & VIDEO_TYPE_CAMERA )
+		cout << "     Camera" << endl;
+*/	
+}
+
+/** Constructor for the V4L class.
+*/
+
+V4L::V4L()
+{
+//	cout << "Opening V4L" << endl;
+}
+
+void V4L::setInfo( char *device, char *input, char *audio, int sample )
+{
+	this->device = device;
+	this->input = input;
+	this->audio = audio;
+	this->sample = sample;
+}
+
+bool V4L::openDevice()
+{
+	bool ret = true;
+
+	if ( !strcmp( this->input, "PAL" ) )
+	{
+//		this->width = 720;
+//		this->height = 576;
+		this->width = VideoWidth;
+		this->height = VideoHeight;
+		this->fps = 25;
+		this->frameSample = this->sample / this->fps;
+	}
+	else if ( !strcmp( this->input, "NTSC" ) )
+	{
+		this->width = 720;
+		this->height = 480;
+		this->fps = 30;
+		this->frameSample = this->sample / this->fps;
+	}
+
+	this->current = NULL;
+	this->fd = open( device, O_RDWR );
+	if(fd == -1){
+		perror( "Unable to open video device" );
+		return false;
+	}
+
+	
+/*refer to old CVEncoder::InitCapture*/	
+{	
+	video_capability capability;
+	if (ioctl (fd, VIDIOCGCAP, &capability) != -1){
+		printf(" query was successful\n");
+	}
+	else{
+		perror("query");
+	}
+	
+	if ((capability.type & VID_TYPE_CAPTURE) != 0){
+		printf("this device can capture video to memory\n");
+	}
+	else{
+		perror("can't capture video to memtory");
+	}
+	
+	struct video_channel queryChannel;
+	int i = 0;
+	while (i < capability.channels)
+	{
+		queryChannel.channel = i;
+		if (ioctl (fd, VIDIOCGCHAN, &queryChannel) != -1)
+		{       // ioctl success, queryChannel contains information about this channel
+			printf (" information about this channel:%d, %s\n", queryChannel.channel, queryChannel.name);
+		}
+		else
+		{      // PErrorText("querychannel");
+		}
+		++ i;
+	}
+	
+	struct video_channel selectedChannel;
+	selectedChannel.channel = 0;
+	selectedChannel.norm = VIDEO_MODE_PAL;
+	if (ioctl (fd, VIDIOCSCHAN, &selectedChannel) == -1)
+	{       
+			return false;
+	}
+	
+	
+   struct video_window captureWindow;
+   memset(&captureWindow, 0, sizeof(captureWindow));
+   captureWindow.width = VideoWidth;
+   captureWindow.height = VideoHeight;
+    if (ioctl (fd, VIDIOCSWIN, &captureWindow) == -1)
+    {
+//			return false;
+    }
+	
+   memset(&captureWindow, 0, sizeof(captureWindow));
+   if (ioctl (fd, VIDIOCGWIN, &captureWindow) == -1)
+    {
+			return false;
+    }
+	
+	width = captureWindow.width;
+	height = captureWindow.height;
+	printf("width=%d,height=%d\n",width,height);
+	
+}
+
+	
+    int depth;
+    int palette;
+    struct video_picture imageProperties;
+   	
+    if (ioctl (fd, VIDIOCGPICT, &imageProperties) == -1)
+    {       // failed to retrieve default image properties
+		return false;
+    }
+    depth = imageProperties.depth;
+    palette = imageProperties.palette;
+	printf("\nVideo:depth=%d,palette=%d\n",depth,palette);
+    if (ioctl (fd, VIDIOCSPICT, &imageProperties) == -1)
+    {       // failed to retrieve default image properties
+		return false;
+    }
+	
+/*	refer to V4L::openDevice in kino program.*/
+/*	
+	this->capability = new V4LCapability( this );
+	for ( int index = 0; index < capability->getNumberOfChannels(); index ++ )
+	{
+		V4LChannel *channel = new V4LChannel( this, index );
+		channels.insert( channels.end(), channel );
+	}
+    setCaptureResolution( this->width, this->height );
+
+*/
+	
+		
+	return ret;
+}
+
+/** Destructor for the V4L device.
+*/
+
+V4L::~V4L()
+{
+//	cout << "Closing V4L" << endl;
+	if ( fd != -1 )
+	{
+		close( fd );
+		for ( unsigned int index = 0; index < channels.size(); index ++ )
+			delete channels[ index ];
+		delete this->capability;
+	}
+}
+
+/** Indicate if the device is available.
+ 
+  	\return true if available, false otherwise
+*/
+
+bool V4L::deviceAvailable()
+{
+	return fd != -1;
+}
+
+/** Return the handle associated to the device.
+ 
+  	\return the file descriptor of the open device.
+*/
+
+int V4L::getHandle()
+{
+	return fd;
+}
+
+/** Set specified channel.
+ 
+  	\param channel		channel to use
+	\return true if successful, false otherwise
+*/
+
+bool V4L::setChannel( unsigned int channel )
+{
+	if ( channel >= 0 && channel < channels.size() )
+	{
+		current = channels[ channel ];
+		return this->request( VIDIOCSCHAN, current );
+	}
+	else
+	{
+		return false;
+	}
+}
+
+/**	Get the number of channels available.
+ 
+  	\return the number of channels
+*/
+
+unsigned int V4L::getNumberOfChannels()
+{
+	return channels.size();
+}
+
+/**	Get the specified channel.
+ 
+  	\param	channel 	channel to obtain
+  	\return the number of channels
+*/
+
+V4LChannel *V4L::getChannel( unsigned int channel )
+{
+	if ( channel >= 0 && channel < channels.size() )
+		return channels[ channel ];
+	else
+		return NULL;
+}
+
+/** Set specified tuner.
+ 
+	\param	tuner		tuner to use
+	\return true if successful, false otherwise
+*/
+
+bool V4L::setTuner( unsigned int tuner )
+{
+	if ( current != NULL )
+		return current->setTuner( tuner );
+	else
+		return false;
+}
+
+/** Get the number of tuners associated to the current channel.
+ 
+  	\return	the number of tuners associated to the current channel
+*/
+
+unsigned int V4L::getNumberOfTuners( )
+{
+	if ( current != NULL )
+		return current->getNumberOfTuners();
+	else
+		return 0;
+}
+
+/** Get a tuner associated to the current channel.
+ 
+  	\param	tuner	tuner object to obtain
+	\return a tuner object 
+*/
+
+V4LTuner *V4L::getTuner( unsigned int tuner )
+{
+	if ( current != NULL )
+		return current->getTuner( tuner );
+	else
+		return NULL;
+}
+
+/** Set user defined resolution (where applicable).
+ 
+  	\param	width		width of capture
+	\param	height		height of capture
+*/
+
+bool V4L::setCaptureResolution( int width, int height )
+{
+	if ( width > capability->getMaxWidth() ||
+	        width < capability->getMinWidth() )
+		return false;
+	if ( height > capability->getMaxHeight() ||
+	        height < capability->getMinHeight() )
+		return false;
+	if ( !capability->hasScaling() && (
+	            width != capability->getMaxWidth() ||
+	            height != capability->getMaxHeight() ) )
+		return false;
+	this->width = width;
+	this->height = height;
+//	cout << "Capture resolution set to " << width << ", " << height << endl;
+	return true;
+}
+
+/** Get the capture width.
+ 
+  	\return	the width of the captured image
+*/
+
+int V4L::getWidth()
+{
+	return width;
+}
+
+/** Get the capture height.
+ 
+  	\return	the height of the captured image
+*/
+
+int V4L::getHeight()
+{
+	return height;
+}
+
+/** Turn on audio.
+*/
+
+void V4L::startAudio()
+{
+	struct video_audio audio;
+	ioctl( fd, VIDIOCGAUDIO, &audio );
+	if ( audio.flags & VIDEO_AUDIO_MUTE )
+		audio.flags ^= VIDEO_AUDIO_MUTE;
+//	cout << "Volume : " << audio.volume << endl;
+	audio.volume = 65535;
+	ioctl( fd, VIDIOCSAUDIO, &audio );
+}
+
+/** Turn off audio.
+*/
+
+void V4L::stopAudio()
+{
+	struct video_audio audio;
+	ioctl( fd, VIDIOCGAUDIO, &audio );
+	audio.flags |= VIDEO_AUDIO_MUTE;
+//	cout << "Volume : " << audio.volume << endl;
+	audio.volume = 0;
+	ioctl( fd, VIDIOCSAUDIO, &audio );
+}
+
+int V4L::mappedMemorySize( bool init )
+{
+	static video_mbuf buf;
+	if ( init == true )
+	{
+		init = 1;
+		ioctl( fd, VIDIOCGMBUF, &buf );
+//		cout << ">>> Mapped Memory Size = " << buf.size << " frames are " << buf.frames << endl;
+		frame_maps = buf.frames;
+	}
+	return buf.size;
+}
+
+/** Initialise capture.
+ 
+  	\param	format	v4l frame format (VIDEO_PALETTE_)
+	\return true if successful, false otherwise
+*/
+
+bool V4L::initialiseCapture( int format )
+{
+	size = width * height * 4;
+
+	map = mmap( 0, mappedMemorySize( true ), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
+
+	if ( map != NULL )
+	{
+		for ( int i = 0; i < frame_maps; i ++ )
+		{
+			frame[ i ].frame = i;
+			frame[ i ].width = getWidth();
+			frame[ i ].height = getHeight();
+			frame[ i ].format = format;
+		}
+		
+		struct timeval tv;
+		gettimeofday( &tv, NULL );
+		starttime = tv.tv_sec * 1000000 + tv.tv_usec;
+		frames = 0;
+		frame_next = 0;
+		
+		int retry = 0;
+		while ( ioctl( fd, VIDIOCMCAPTURE, &frame[ 0 ] ) == -1 && retry ++ < frame_maps + 1 ) ;
+		
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+/** Get the next frame.
+ 
+  	\return	the adress of the frame in the format specified
+*/
+
+void *V4L::getNextFrame()
+{
+	unsigned char * ret = NULL;
+
+	int current = frame_next;
+	frame_next = ( frame_next + 1 ) % frame_maps;
+	
+	if ( ioctl( fd, VIDIOCMCAPTURE, &frame[ frame_next ] ) == -1 )
+		; //cout << "Frame 1 Failed to initialise" << endl;
+	if ( ioctl( fd, VIDIOCSYNC, &frame[ current ].frame ) == -1 )
+		; //cout << "Frame 0 Failed to sync" << endl;
+	ret = ( unsigned char * ) map + current * ( mappedMemorySize( ) / frame_maps );
+	
+	frames ++;
+
+	return ( void * ) ret;
+}
+
+/** Turn off capture.
+*/
+
+void V4L::stopCapture()
+{
+	if ( map != NULL )
+	{
+		struct timeval tv;
+		gettimeofday( &tv, NULL );
+		long long endtime = tv.tv_sec * 1000000 + tv.tv_usec;
+		double fps = ( frames ) / ( ( ( double ) ( endtime - starttime ) ) / 1000000 );
+//		cout << "fps: " << fps << endl;
+		munmap( map, mappedMemorySize() );
+		map = NULL;
+		int enable = 0;
+		ioctl( getHandle(), VIDIOCCAPTURE, &enable );
+	}
+}
+
+/** Get the current frequency of the tuner.
+ 
+  	\return	the current tuned in frequency.
+*/
+
+int V4L::getFrequency()
+{
+	unsigned long current;
+	ioctl( fd, VIDIOCGFREQ, &current );
+	return ( int ) current;
+}
+
+/** Set the current frequency of the tuner.
+ 
+  	\param	frequency	frequency to set
+  	\return	the current tuned in frequency.
+*/
+
+bool V4L::setFrequency( int frequency )
+{
+	unsigned long val = ( unsigned long ) frequency & 0xffff;
+	return ioctl( fd, VIDIOCSFREQ, &val ) != -1;
+}
+
+/** Get the signal of the current tuned in frequency.
+*/
+
+int V4L::getSignal()
+{
+	return current->getSignal();
+}
+
+/** Gimme some info
+*/
+
+void V4L::report()
+{
+	capability->report();
+
+	for ( unsigned int index = 0; index < channels.size(); index ++ )
+	{
+		channels[ index ] ->report();
+	}
+}
+
+//V4l classes.
+
+
+
+
+
+extern void PErrorText(const char* error);
+
+int CVDecoder::input_pixfmt=PIX_FMT_RGBA32;
+
+
+#define STARTTIME { static int MaxTime=0;                         \
+	                static int MinTime=1000;                      \
+	                static int largecount=0;                      \
+	                int IntervalTime=0;                           \
+	                int64_t start_time=av_gettime();
+	
+#define ENDTIME     IntervalTime = av_gettime()-start_time;       \
+	                if(IntervalTime>40000)                         \
+	                    largecount++;                             \
+	                if(MaxTime<IntervalTime)                      \
+	                    MaxTime=IntervalTime;                     \
+	                if(MinTime>IntervalTime)                      \
+	                    MinTime=IntervalTime;                     \
+	                printf("\nMaxTime=%d, MinTime=%d, largecount=%d, IntervalTime=%d\n", MaxTime, MinTime, largecount, IntervalTime);}
+
+CVEncoder::CVEncoder()
+{
+	m_pFrameBuf = 0;
+	m_pFrame = 0;
+    m_pCodec  = 0;
+	m_pCodecCtx  = 0;
+	m_memoryMap = (char*)-1;
+	m_pmemoryBuffer = 0;
+	m_mmaps = 0;
+	m_hDevice = -1;
+	m_bufferIndex = 0;
+	m_bInitCap = false;
+	m_bInit = false;
+}
+
+CVEncoder::~CVEncoder()
+{	
+	CloseCap();
+	
+	if(m_pFrameBuf){
+		free(m_pFrameBuf);
+		m_pFrameBuf = 0;
+	}
+
+
+	if(m_pFrame){
+		free(m_pFrame);
+		m_pFrame = 0;
+	}
+	if(m_pCodecCtx){
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+	m_bInitCap = false;
+	m_bInit = false;
+}
+
+bool CVEncoder::Init(enum CodecID nCodecID /*=CODEC_ID_MPEG1*/)
+{
+	m_bInit = false;
+	int width, height;
+	
+	/*Init for encode*/
+	avcodec_init();
+    avcodec_register_all();
+	
+	if(!InitCapture(width, height))
+		return false;
+//	CloseCap();
+//	if(!InitCapture(width, height))
+//		return false;
+
+	m_width = width;
+	m_height = height;
+
+	//new a frame object.
+	if(m_pFrame){
+		free(m_pFrame);
+		m_pFrame = 0;
+	}
+	m_pFrame = avcodec_alloc_frame();
+
+	/* find the mpeg1 video encoder */
+	m_pCodec = avcodec_find_encoder(nCodecID);
+	if (!m_pCodec) {
+		PErrorText("codec not found");
+		return false;
+	}
+	
+	if(m_pCodecCtx){
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+
+	m_pCodecCtx = avcodec_alloc_context();
+	/* resolution must be a multiple of two */
+	m_pCodecCtx->width = m_width;  
+	m_pCodecCtx->height = m_height;
+	/* frames per second */
+	m_pCodecCtx->frame_rate = V_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= V_CODEC_frame_rate_base;
+	m_pCodecCtx->gop_size = V_CODEC_gop_size; /* emit one intra frame every ten frames */
+	m_pCodecCtx->bit_rate = 1128*1024;          //1128kbps.
+	
+	/* open it */
+	if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) {
+		PErrorText("could not open codec");
+		return false;
+	}
+	
+	//	c->pix_fmt = PIX_FMT_YUV420P;	// wy
+	//	c->codec_type = CODEC_TYPE_VIDEO;
+
+	//malloc outbuf.
+	if(m_pFrameBuf){
+		free(m_pFrameBuf);
+		m_pFrameBuf = 0;
+	}
+	
+	int image_size = avpicture_get_size (PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+
+	m_pFrameBuf = (uint8_t*)malloc(image_size);
+	if(m_pFrameBuf == 0){
+		PErrorText("FrameBuf malloc failed!");
+		return false;
+	}
+	/*Init for encode*/
+	
+
+	avpicture_fill ((AVPicture*)m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+	m_pFrame->type = FF_BUFFER_TYPE_SHARED;
+	
+
+	m_bInit = true;
+	return true;
+}
+
+//	for test encode.
+//void SaveVideoFile(char* buf, int bufsize)
+//{
+//	fwrite(buf, bufsize, 1, pFile);
+//	return;
+//}
+
+int CVEncoder::EncodeProcess(char *frameaddress, uint8_t *pOutBuf, int nOutsize)
+{
+	int iii;
+	if(!m_bInit)
+		return -2;
+
+	if(nOutsize<V_En_OutBufSize){
+		return -3;
+	}
+//	STARTTIME
+	avpicture_fill(&m_pic_rgb, (uint8_t *)frameaddress, PIX_FMT_BGR24, m_pCodecCtx->width, m_pCodecCtx->height);
+	avpicture_fill((AVPicture*)m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+	if (img_convert ((AVPicture*)m_pFrame, PIX_FMT_YUV420P,
+		&m_pic_rgb, PIX_FMT_BGR24, m_pCodecCtx->width, m_pCodecCtx->height) < 0) {
+		fprintf (stderr, "xtoffmpeg.XImageToFFMPEG(): pixel format conversion not handled ... aborting\n");
+		return -4;
+	}
+	
+	m_VideoHeader.width=m_width;
+	m_VideoHeader.height=m_height;
+	memcpy((char *)pOutBuf,&m_VideoHeader, sizeof(VideoHeader));
+
+	iii = avcodec_encode_video(m_pCodecCtx, pOutBuf+sizeof(VideoHeader), nOutsize, m_pFrame);
+//	printf("iii = %d, key_frame = %d, pict_type = %d\n", 
+//				iii, m_pFrame->key_frame, m_pFrame->pict_type);
+	//	for test encode.	
+	if(iii<=0)
+		return iii;
+//	ENDTIME
+	return iii+sizeof(VideoHeader);
+}
+
+bool CVEncoder::InitCapture(int &width, int &height)
+{
+	CloseCap();
+    m_hDevice = open ("/dev/video0", O_RDWR);
+    if (m_hDevice != -1){
+		printf("\nopen successful\n");
+	}
+	else{
+		PErrorText("open video device: /dev/video0");
+		return false;
+	}	 
+	
+	video_capability capability;
+	if (ioctl (m_hDevice, VIDIOCGCAP, &capability) != -1){
+		printf(" query was successful\n");
+	}
+	else{
+		perror("query");
+	}
+	
+	if ((capability.type & VID_TYPE_CAPTURE) != 0){
+		printf("this device can capture video to memory\n");
+	}
+	else{
+		perror("can't capture video to memtory");
+	}
+	
+	struct video_channel queryChannel;
+	int i = 0;
+	while (i < capability.channels)
+	{
+		queryChannel.channel = i;
+		if (ioctl (m_hDevice, VIDIOCGCHAN, &queryChannel) != -1)
+		{       // ioctl success, queryChannel contains information about this channel
+			printf (" information about this channel:%d, %s\n", queryChannel.channel, queryChannel.name);
+		}
+		else
+		{       PErrorText("querychannel");
+		}
+		++ i;
+	}
+	
+	struct video_channel selectedChannel;
+	selectedChannel.channel = 0;
+	selectedChannel.norm = VIDEO_MODE_PAL;
+	if (ioctl (m_hDevice, VIDIOCSCHAN, &selectedChannel) == -1)
+	{       
+			PErrorText("could not set the selected channel");
+			return false;
+	}
+	
+	
+   struct video_window captureWindow;
+ memset(&captureWindow, 0, sizeof(captureWindow));
+   captureWindow.width = V_CODEC_width;
+   captureWindow.height = V_CODEC_height;
+    if (ioctl (m_hDevice, VIDIOCSWIN, &captureWindow) == -1)
+    {
+			PErrorText("Video Open Error: Could not set standar video size");
+//			return false;
+    }
+	
+   memset(&captureWindow, 0, sizeof(captureWindow));
+   if (ioctl (m_hDevice, VIDIOCGWIN, &captureWindow) == -1)
+    {
+			PErrorText("Video Open Error: Could not get video size");
+			return false;
+    }
+	
+	width = captureWindow.width;
+	height = captureWindow.height;
+	printf("width=%d,height=%d\n",width,height);
+//	if(width!=V_CODEC_width || height!=V_CODEC_height){
+//			printf("\nVideo Open Error: Video size is not %d, %d\n", V_CODEC_width, V_CODEC_height);
+//			return false;
+//	}
+	
+    int depth;
+    int palette;
+    struct video_picture imageProperties;
+   	
+    if (ioctl (m_hDevice, VIDIOCGPICT, &imageProperties) == -1)
+    {       // failed to retrieve default image properties
+		return false;
+    }
+    depth = imageProperties.depth;
+    palette = imageProperties.palette;
+	printf("\nVideo:depth=%d,palette=%d\n",depth,palette);
+    if (ioctl (m_hDevice, VIDIOCSPICT, &imageProperties) == -1)
+    {       // failed to retrieve default image properties
+		return false;
+    }
+	
+//	sleep(10);
+	m_pmemoryBuffer  = new (struct video_mbuf);
+    if (ioctl (m_hDevice, VIDIOCGMBUF, m_pmemoryBuffer) == -1)
+    {       
+		PErrorText("retrieve information about capture memory space");
+		return false;
+    }
+	
+	
+	// obtain memory mapped area
+
+	m_memoryMap = (char*)mmap (0, m_pmemoryBuffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, m_hDevice, 0);
+	if ((int)m_memoryMap == -1)
+	{       
+		PErrorText("retrieve pointer to memory mapped area");
+		return false;
+    }
+	
+	
+	// allocate structures
+	
+	m_mmaps = (struct video_mmap*)(malloc (m_pmemoryBuffer->frames * sizeof (struct video_mmap)));
+	// fill out the fields
+	i = 0;
+	printf("\nmemoryBuffer.frames = %d\n", m_pmemoryBuffer->frames);
+	//	sleep(100);
+	while (i < m_pmemoryBuffer->frames)
+	{
+		m_mmaps[i].frame = i;
+		m_mmaps[i].width = width;
+		m_mmaps[i].height = height;
+		m_mmaps[i].format = palette;
+		printf("frame%d=%d\n",i,m_mmaps[i].frame);
+		++ i;
+	}
+	
+
+	i = 0;
+    while (i < (m_pmemoryBuffer->frames-1))
+    {
+        if (ioctl (m_hDevice, VIDIOCMCAPTURE, &m_mmaps[i]) == -1)
+            {       
+					PErrorText("capture request");
+					return false;
+
+            }			
+        ++ i;
+    }
+
+    m_bufferIndex = m_pmemoryBuffer->frames-1;
+	
+	m_bInitCap = true;
+	printf("\nVideo device open success!\n");
+	return true;
+}
+
+void CVEncoder::CloseCap()
+{
+
+	m_bInitCap = false;
+	m_bInit = false;
+	
+	if(m_pmemoryBuffer){
+		if((int)m_memoryMap != -1){
+		    // unmap the capture memory
+		    munmap (m_memoryMap, m_pmemoryBuffer->size);
+			m_memoryMap = (char*)-1;
+		}
+		delete m_pmemoryBuffer;
+		m_pmemoryBuffer = 0;
+	}
+	if(m_mmaps){
+	   free (m_mmaps);
+		m_mmaps = 0;
+	}
+
+	if(m_hDevice != -1){
+		close (m_hDevice);
+		m_hDevice = -1;
+	}
+	
+//	printf("\nVideo device closed.\n");
+}
+
+bool CVEncoder::GetCapSize(int &width, int &height)
+{
+	if(!m_bInit)
+		return false;
+	
+	width = m_width;
+	height = m_height;
+	
+	return true;
+}
+
+
+bool CVEncoder::Capture(char **frameaddress)
+{
+	if(!m_bInit)
+		return false;
+	STARTTIME
+	// send a request to begin capturing to the currently indexed buffer
+	if (ioctl (m_hDevice, VIDIOCMCAPTURE, &m_mmaps[m_bufferIndex]) == -1)
+	{       perror("capture request failed");
+	} 
+	
+	// move bufferIndex to the next frame
+	++ m_bufferIndex;
+	if (m_bufferIndex == m_pmemoryBuffer->frames)
+	{       // bufferIndex is indexing beyond the last buffer
+		// set it to index the first buffer
+		m_bufferIndex = 0;
+	}
+	
+	// wait for the currently indexed frame to complete capture
+	if (ioctl (m_hDevice, VIDIOCSYNC, &m_mmaps[m_bufferIndex]) == -1)
+	{       perror(" sync request failed");
+	}
+	
+	*frameaddress=m_memoryMap + m_pmemoryBuffer->offsets[m_bufferIndex];
+	ENDTIME
+	return true;
+}
+
+void CVEncoder::GetColorInfo (XImage *image, ColorInfo *ci /* return struct */)
+{
+	unsigned long red_mask, green_mask, blue_mask, alpha_mask;
+	// the shifts are unsigned longs as well
+
+	if (!ci)
+		return;
+
+	// setting shifts and bit_depths to zero
+	ci->red_shift = ci->green_shift = ci->blue_shift = ci->alpha_shift = 0;
+	ci->red_bit_depth = ci->green_bit_depth = ci->blue_bit_depth =
+		ci->alpha_bit_depth = 0;
+
+	red_mask = image->red_mask;
+	if (red_mask > 0) {
+		// shift red_mask to the right till all empty bits have been
+		// shifted out and count how many they were
+		while ((red_mask & 0x01) == 0) {
+			red_mask >>= 1;
+			ci->red_shift++;
+		}
+		// count how many bits are set in the mask = depth
+		while ((red_mask & 0x01) == 1) {
+			red_mask >>= 1;
+			ci->red_bit_depth++;
+		}
+	}
+
+	ci->red_max_val = (1 << ci->red_bit_depth) - 1;
+
+	green_mask = image->green_mask;
+	if (green_mask > 0) {
+		while ((green_mask & 0x01) == 0) {
+			green_mask >>= 1;
+			ci->green_shift++;
+		}
+		while ((green_mask & 0x01) == 1) {
+			green_mask >>= 1;
+			ci->green_bit_depth++;
+		}
+	}
+	ci->green_max_val = (1 << ci->green_bit_depth) - 1;
+
+	blue_mask = image->blue_mask;
+	if (blue_mask > 0) {
+		while ((blue_mask & 0x01) == 0) {
+			blue_mask >>= 1;
+			ci->blue_shift++;
+		}
+		while ((blue_mask & 0x01) == 1) {
+			blue_mask >>= 1;
+			ci->blue_bit_depth++;
+		}
+	}
+	ci->blue_max_val = (1 << ci->blue_bit_depth) - 1;
+
+	/* over all max values */
+	// whatever they are good for
+	ci->max_val = max (ci->red_max_val, ci->green_max_val);
+	ci->max_val = max (ci->blue_max_val, ci->max_val);
+	ci->bit_depth = max (ci->red_bit_depth, ci->green_bit_depth);
+	ci->bit_depth = max (ci->blue_bit_depth, ci->bit_depth);
+	if (image->bits_per_pixel > image->depth) {
+		/* alpha? */
+		// this seems to not reflect X's ignorance of alpha in its
+		// masks
+		ci->alpha_mask = ~
+			(image->red_mask | image->blue_mask | image->green_mask); 
+		alpha_mask = ci->alpha_mask;
+		if (alpha_mask > 0) {
+			while ((alpha_mask & 0x01) == 0) {
+				alpha_mask >>= 1;
+				ci->alpha_shift++;
+			}
+			while ((alpha_mask & 0x01) == 1) {
+				alpha_mask >>= 1;
+				ci->alpha_bit_depth++;
+			}
+		}
+		ci->alpha_max_val = (1 << ci->alpha_bit_depth) - 1;
+	}
+}
+
+
+//CVDecoder class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CVDecoder::CVDecoder()
+{
+    m_pCodec  = 0;
+	m_pCodecCtx = 0;
+	m_pOutFrame = 0;
+	m_bInit = false;
+
+	m_display = 0;
+	m_win = 0;
+	m_image = 0;
+		
+}
+
+CVDecoder::~CVDecoder()
+{
+	m_bInit = false;
+
+	if(m_pOutFrame){
+		free(m_pOutFrame);
+		m_pOutFrame = 0;
+	}
+	if(m_pCodecCtx){
+		if(m_pCodecCtx->extradata){
+			free(m_pCodecCtx->extradata);
+			m_pCodecCtx->extradata = 0;
+			m_pCodecCtx->extradata_size = 0;
+		}
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+
+	if(m_image){
+		XDestroyImage(m_image);
+		//m_image->f.destroy_image(m_image);
+		m_image = 0;
+	}
+	
+	
+	if(m_display){
+		if(m_win){
+			XClearWindow(m_display, m_win);
+			m_win = 0;
+		}
+		if(m_d){
+			XClearWindow(m_display, m_d);
+			m_d = 0;
+		}
+		
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+	
+}
+
+bool CVDecoder::CreateXImage(Drawable parent, int x, int y, int width, int height)
+{
+	int screen_num;
+    
+	GdkPixbuf *original_pixbuf;
+	
+    gint original_width, original_height;
+	GdkColorspace original_color;
+	gboolean original_alpha;
+	gboolean pixbuf_has_alpha;
+	XSetWindowAttributes win_attr;
+	XImage *p_image = NULL;
+	if(!m_bInit)
+		return false;
+	
+
+	CloseXImage();
+
+	m_imagemutex.Lock();
+	
+	m_display = XOpenDisplay(NULL);
+	screen_num = DefaultScreen(m_display);
+	m_gc = DefaultGC(m_display, screen_num);
+	m_d = RootWindow(m_display,screen_num);
+	
+	m_win = XCreateWindow(m_display, parent,
+    x, y, width, height, 1, XDefaultDepth(m_display, screen_num),
+    InputOutput, CopyFromParent, 0, &win_attr);	
+	
+	if(gdk_pixbuf_new_from_file ("pic/teacher2.bmp", NULL)==NULL)
+	{
+      XSetWindowBackgroundPixmap(m_display,m_win,ParentRelative);
+	  XMapWindow(m_display, m_win);	
+	}
+	
+	else
+	{	
+	original_pixbuf = gdk_pixbuf_new_from_file ("pic/teacher2.bmp", NULL);
+	pixbuf_has_alpha = gdk_pixbuf_get_has_alpha (original_pixbuf);
+	original_color = gdk_pixbuf_get_colorspace(original_pixbuf);
+	original_alpha = gdk_pixbuf_get_has_alpha(original_pixbuf);
+    original_width = gdk_pixbuf_get_width (original_pixbuf);
+    original_height = gdk_pixbuf_get_height (original_pixbuf);
+	printf("original_alpha = %d\n", original_alpha);
+	printf("original_color = %d\n", original_color);
+	printf("original_width = %d\n", original_width);
+	printf("original_height = %d\n", original_height);
+	printf("n_channles = %d\n", gdk_pixbuf_get_n_channels(original_pixbuf));
+
+
+	
+	
+	Pixmap pixmap=XCreatePixmap(m_display,m_win, original_width, original_height, XDefaultDepth(m_display,screen_num));
+	XSetWindowBackgroundPixmap(m_display, m_win, pixmap);
+	
+	p_image = XGetImage(m_display, 	//获取当前屏幕所显示图像
+					     		m_d,
+    	  			      	    0, 0,
+   	  			     	     	original_width, 
+								original_height,
+				    	       AllPlanes, ZPixmap);
+	if(!p_image){
+	  	printf("error\n");
+		exit(10);
+	}
+	
+	
+	AVPicture pic_rgb24, pic_rgb32;
+		if(m_display && p_image && pixmap){
+			avpicture_fill(&pic_rgb32, (uint8_t*)p_image->data, PIX_FMT_RGBA32,
+					original_width, original_height);
+			avpicture_fill(&pic_rgb24, gdk_pixbuf_get_pixels(original_pixbuf), PIX_FMT_RGB24,
+					original_width, original_height);
+					
+			if(img_convert(&pic_rgb32, PIX_FMT_RGBA32, &pic_rgb24, PIX_FMT_RGB24, 
+					original_width, original_height) < 0){
+				printf("Error pixel format conversion");
+				return -1;
+			}
+			
+			XPutImage(m_display, pixmap, m_gc, p_image, 
+					0,0, 0, 0, 
+					original_width, original_height);
+	       
+	
+		}
+		
+		XMapWindow(m_display, m_win); 
+        XFreePixmap(m_display,pixmap);
+		gdk_pixbuf_unref(original_pixbuf);
+		XDestroyImage(p_image);
+	}
+
+	// Init GlobalVar.image
+	//
+	//m_d = RootWindow(m_display,screen_num);
+	
+	m_image = XGetImage(m_display, 	//ڎ·å–圓前屏幕ʉ€Ê˜Şç€ºå›Şåƒ„1€7
+					    m_d,
+    	  			    0, 0,
+   	  			     	m_width, m_height,
+				    	AllPlanes, ZPixmap);
+
+/*	
+	static Visual * visual = 0;
+	if(visual == 0){
+		visual = DefaultVisual(m_display, screen_num);
+	}
+	m_image = XCreateImage(m_display, visual, depth, ZPixmap, 0, data, width, height, bitmap_pad, 
+                        bytes_per_line)
+*/	
+	if(!m_image){
+		printf("XGetImage error\n");
+		m_imagemutex.Unlock();
+		return false;
+	}
+
+	m_imagemutex.Unlock();
+	return true;		
+}
+
+void CVDecoder::CloseXImage()
+{
+	if(!m_bInit)
+		return ;
+	
+	m_imagemutex.Lock();
+
+	if(m_image){
+		XDestroyImage(m_image);
+//		m_image->f.destroy_image(m_image);
+		m_image = 0;
+	}
+	
+	if(m_display){
+		if(m_win){
+			XUnmapWindow(m_display, m_win);
+			XClearWindow(m_display, m_win);
+			m_win = 0;
+		}
+		
+		if(m_d){
+			XClearWindow(m_display, m_d);
+			m_d = 0;
+		}
+		
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+
+	m_imagemutex.Unlock();
+	return ;
+}
+
+
+bool CVDecoder::Init(int width, int height, enum CodecID nCodecID)
+{
+	if(m_bInit)
+		return true;
+	
+	avcodec_init();
+    avcodec_register_all();
+	
+	
+	if(!m_imagemutex.IsInitialized()){
+		if(m_imagemutex.Init() < 0)
+			return false;
+	}
+	
+	m_width = width;
+	m_height = height;
+
+	
+	// find the video decoder
+	m_pCodec = avcodec_find_decoder(nCodecID);
+	if (!m_pCodec) {
+		PErrorText("Codec not found\n");
+		return false;
+	}
+	
+	if(m_pOutFrame){
+		free(m_pOutFrame);
+		m_pOutFrame = 0;
+	}
+	m_pOutFrame = avcodec_alloc_frame();
+	
+	if(m_pCodecCtx){
+		if(m_pCodecCtx->extradata){
+			free(m_pCodecCtx->extradata);
+			m_pCodecCtx->extradata = 0;
+			m_pCodecCtx->extradata_size = 0;
+		}
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+	m_pCodecCtx = avcodec_alloc_context();
+	m_pCodecCtx->extradata = 0;
+	m_pCodecCtx->extradata_size = 0;
+	
+	// put sample parameters
+	m_pCodecCtx->bit_rate = 512*1024;
+	// resolution must be a multiple of two 
+	m_pCodecCtx->width = m_width;  
+	m_pCodecCtx->height = m_height;
+	// frames per second
+	m_pCodecCtx->frame_rate = CVEncoder::V_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= CVEncoder::V_CODEC_frame_rate_base;
+	// emit one intra frame every ten frames
+	m_pCodecCtx->gop_size = CVEncoder::V_CODEC_gop_size; 
+
+	m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+	m_pCodecCtx->extradata = malloc(V_De_ExtraHeaderSize);
+	if(m_pCodecCtx->extradata == 0){
+		return false;
+	}
+	m_pCodecCtx->extradata_size = V_De_ExtraHeaderSize;
+	
+	//	pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
+	//	pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
+	
+	// we dont send complete frames
+	if(m_pCodec->capabilities&CODEC_CAP_TRUNCATED)
+        m_pCodecCtx->flags|= CODEC_FLAG_TRUNCATED; 
+	
+	// open it
+	if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) {
+		PErrorText("could not open codec");
+		return false;
+	}
+
+	m_bInit = true;
+	return true;
+}
+
+
+int CVDecoder::DecodeProcess(uint8_t *encodeddata_v, const int encodeddatasize_v)
+{
+	bool isPaintPic;
+	int realsize, i;
+	int got_picture ;
+	
+	if(!m_bInit){
+		return -1;
+	}
+	
+	int left = 0;
+	int len;
+	
+	m_imagemutex.Lock();
+	
+	for(i = 0 ; ; i++){
+		if(encodeddatasize_v - i * V_De_INBUF_SIZE >= V_De_INBUF_SIZE)
+			realsize = V_De_INBUF_SIZE;
+		else
+			realsize = encodeddatasize_v - i * V_De_INBUF_SIZE;
+		
+		if(realsize <= 0)
+			break;
+		
+		left = 0;
+		isPaintPic = false;
+		while(realsize > 0){
+	
+			m_pCodecCtx->width = m_width;
+			m_pCodecCtx->height = m_height;
+
+			len = avcodec_decode_video(m_pCodecCtx, m_pOutFrame, &got_picture, 
+				(encodeddata_v + i * V_De_INBUF_SIZE + left), realsize);
+			// printf("len = %d, got_picture = %d, linesize=%d\n", len, got_picture, m_pOutFrame->linesize[0]);
+			
+			if(len < 0){
+				PErrorText("Error while decoding");
+				m_imagemutex.Unlock();
+				return -2;
+			}
+			
+			if(m_image != 0){
+				
+			    m_encoder.GetColorInfo (m_image, &c_info);
+    			switch (m_image->bits_per_pixel) {
+                case 8:
+					input_pixfmt = PIX_FMT_PAL8;
+                    break;
+				case 16:
+					if ( m_image->red_mask == 0xF800 && m_image->green_mask == 0x07E0
+					&& m_image->blue_mask == 0x1F ) {
+						input_pixfmt = PIX_FMT_RGB565;
+					} else if ( m_image->red_mask == 0x7C00 && m_image->green_mask == 0x03E0
+						   && m_image->blue_mask == 0x1F ) {
+						input_pixfmt = PIX_FMT_RGB555;                    
+					} else {
+                    fprintf (stderr, "xtoffmpeg.XImageToFFMPEG(): rgb ordering at image depth %i not supported ... aborting\n", m_image->bits_per_pixel);
+                    fprintf (stderr, "xtoffmpeg.XImageToFFMPEG(): color masks: r 0x%.6lX g 0x%.6lX b 0x%.6lX\n", m_image->red_mask, m_image->green_mask, m_image->blue_mask);
+                    }
+                    break;
+                case 24:
+                    if ( m_image->red_mask == 0xFF0000 && m_image->green_mask == 0xFF00
+                    && m_image->blue_mask == 0xFF ) {
+                        input_pixfmt = PIX_FMT_BGR24;
+                    } else if ( m_image->red_mask == 0xFF && m_image->green_mask == 0xFF00
+                    && m_image->blue_mask == 0xFF0000 ) {
+                        input_pixfmt = PIX_FMT_RGB24;
+                    } else {
+                        PErrorText("xtoffmpeg.XImageToFFMPEG(): rgb ordering at image depth not supported ... aborting\n");
+                        PErrorText("xtoffmpeg.XImageToFFMPEG(): color masks");
+                        return false;
+                    }
+                    break;
+                case 32:
+                    if ( c_info.alpha_mask == 0xFF000000 && m_image->green_mask == 0xFF00 ) {
+                    // byte order is relevant here, not endianness
+                    // endianness is handled by avcodec, but atm no such thing
+                    // as having ABGR, instead of ARGB in a word. Since we
+                    // need this for Solaris/SPARC, but need to do the conversion
+                    // for every frame we do it outside of this loop, cf. below
+                    // this matches both ARGB32 and ABGR32
+                        input_pixfmt = PIX_FMT_RGBA32;
+                    } else {
+                        PErrorText("xtoffmpeg.XImageToFFMPEG(): image depth not supported ... aborting");
+                        return false;
+                    }
+                    break;
+                default:
+                    PErrorText("xtoffmpeg.XImageToFFMPEG(): image depth not supported ... aborting");
+                    return false;
+                }
+			}
+			
+			if(got_picture){
+				if(!isPaintPic){
+					if(m_display && m_image && m_win){
+						
+						avpicture_fill(&pic_rgb, (uint8_t*)m_image->data, input_pixfmt,
+							m_width, m_height);
+						
+						if(img_convert(&pic_rgb, input_pixfmt, (AVPicture*)m_pOutFrame, PIX_FMT_YUV420P, 
+							m_width, m_height) < 0){
+							PErrorText("Error pixel format conversion");
+							m_imagemutex.Unlock();
+							return -3;
+						}
+		
+						XPutImage(m_display, m_win, m_gc, m_image, 
+									0, 0, 0, 0,
+									m_width, m_height);
+		
+					}
+				}				
+				isPaintPic = true;	
+
+			}
+			realsize -= len;
+			left += len;
+		}				
+	}
+	
+	m_imagemutex.Unlock();
+	return 0;
+}
+
+void CVDecoder::CloseCodec()
+{
+	m_bInit = false;
+
+	if(m_pOutFrame){
+		free(m_pOutFrame);
+		m_pOutFrame = 0;
+	}
+	if(m_pCodecCtx){
+		if(m_pCodecCtx->extradata){
+			free(m_pCodecCtx->extradata);
+			m_pCodecCtx->extradata = 0;
+			m_pCodecCtx->extradata_size = 0;
+		}
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+		
+}
+
+bool CVDecoder::ResetCodec(const int width, const int height)
+{
+	CodecID nCodecID = m_pCodecCtx->codec_id;
+	CloseCodec();
+	m_bInit = false;
+	
+	m_width = width;
+	m_height = height;
+	
+	// find the video decoder
+	m_pCodec = avcodec_find_decoder(nCodecID);
+	if (!m_pCodec) {
+		PErrorText("Codec not found");
+		return false;
+	}
+	
+	if(m_pOutFrame){
+		free(m_pOutFrame);
+		m_pOutFrame = 0;
+	}
+	m_pOutFrame = avcodec_alloc_frame();
+	
+	if(m_pCodecCtx){
+		if(m_pCodecCtx->extradata){
+			free(m_pCodecCtx->extradata);
+			m_pCodecCtx->extradata = 0;
+			m_pCodecCtx->extradata_size = 0;
+		}
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+	m_pCodecCtx = avcodec_alloc_context();
+	m_pCodecCtx->extradata = 0;
+	m_pCodecCtx->extradata_size = 0;
+	
+	// put sample parameters
+	m_pCodecCtx->bit_rate = 512*1024;
+	// resolution must be a multiple of two 
+	m_pCodecCtx->width = m_width;  
+	m_pCodecCtx->height = m_height;
+	// frames per second
+	m_pCodecCtx->frame_rate = CVEncoder::V_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= CVEncoder::V_CODEC_frame_rate_base;
+	// emit one intra frame every ten frames
+	m_pCodecCtx->gop_size = CVEncoder::V_CODEC_gop_size; 
+
+	m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+	m_pCodecCtx->extradata = malloc(V_De_ExtraHeaderSize);
+	if(m_pCodecCtx->extradata == 0){
+		return false;
+	}
+	m_pCodecCtx->extradata_size = V_De_ExtraHeaderSize;
+	
+	//	pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
+	//	pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
+	
+	// we dont send complete frames
+	if(m_pCodec->capabilities&CODEC_CAP_TRUNCATED)
+        m_pCodecCtx->flags|= CODEC_FLAG_TRUNCATED; 
+	
+	// open it
+	if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) {
+		PErrorText("could not open codec");
+		return false;
+	}
+
+	m_bInit = true;
+	return true;
+
+}
+
+//CVideoSender class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CVideoSender::CVideoSender() : m_sendthread(SendBufSize)
+{
+	stop = false;
+	m_bIsRecord = false;
+	m_bInit = 0;
+	
+	m_hFile = 0;
+	m_mode = ModeNone;
+//	m_playback = 0;
+
+	if(!m_initmutex.IsInitialized()){
+		m_initmutex.Init();
+	}
+
+}
+
+CVideoSender::~CVideoSender()
+{
+	//first stop thread, because  m_pOutBuf is being used by Thread();
+	Stop();
+	
+	//close file.
+	if(m_hFile){
+		fclose(m_hFile);
+		m_hFile = 0;
+	} 
+
+	//free buffer.
+	if(m_pOutBuf!=0)
+		free(m_pOutBuf);
+}
+
+#define MAX_PACKET_SIZE 10*1024
+bool CVideoSender::Init(int nHostPort)
+{
+	if(IsInitialized())
+		return true;
+
+	if(!m_imagemutex.IsInitialized()){
+		if(m_imagemutex.Init() < 0)
+			return false;
+	}
+	
+	if(!m_sendthread.Init(nHostPort))
+		return false;
+
+	if(m_pOutBuf==0){
+		m_pOutBuf = (uint8_t*)malloc(CVEncoder::V_En_OutBufSize);
+		if(m_pOutBuf==0){
+			return false;
+		}
+
+	}
+
+	//Init sencoder.
+	if(!m_vencoder.Init(CODEC_ID_MPEG1VIDEO)){
+		return false;
+	}
+
+	if (!m_modemutex.IsInitialized())
+	{
+		if (m_modemutex.Init() < 0)
+			return -2;
+	}
+	
+	
+	m_bIsRecord = false;
+	m_bInit = true;
+	return m_bInit;
+}
+
+bool CVideoSender::IsInitialized()
+{
+	bool b;
+	
+	m_initmutex.Lock();
+	b = m_bInit;
+	m_initmutex.Unlock();
+	
+	return b;
+}
+
+bool CVideoSender::CreateXImage(Drawable parent, int x, int y, int width, int height)
+{
+	int screen_num;
+
+	if(!IsInitialized())
+		return false;
+	
+
+	CloseXImage();
+
+	m_imagemutex.Lock();
+	
+	m_display = XOpenDisplay(NULL);
+	screen_num = DefaultScreen(m_display);
+	
+	m_win = XCreateSimpleWindow(m_display, //display
+       	                   		parent, //父窗口
+       	                  	    x, y, width, height, //Àœçœ®å’Œå€§å°„1€7
+			  	                0, //ÚŞ¹ç•Œå®œåºŠ
+				  	            BlackPixel(m_display, screen_num), //前ʙ¯Ú‰²
+			  	                65535/20);//ڃŒÊ™¯Ú‰²
+
+	XMapWindow(m_display, m_win);
+	m_gc = DefaultGC(m_display, screen_num);
+
+	// Init GlobalVar.image
+	//
+	int imagewidth, imageheight;
+	m_vencoder.GetCapSize(imagewidth, imageheight);
+	
+	m_image = XGetImage(m_display, 	//ڎ·å–圓前屏幕ʉ€Ê˜Şç€ºå›Şåƒ„1€7
+					    m_win,
+    	  			    0, 0,
+   	  			     	imagewidth, imageheight,
+				    	AllPlanes, ZPixmap);
+	if(!m_image){
+		PErrorText("XGetImage error\n");
+		m_imagemutex.Unlock();
+		return false;
+	}
+
+	m_imagemutex.Unlock();
+	return true;		
+}
+
+void CVideoSender::CloseXImage()
+{
+	if(!IsInitialized())
+		return ;
+	
+	m_imagemutex.Lock();
+	
+	if(m_image){
+		XDestroyImage(m_image);
+//		m_image->f.destroy_image(m_image);
+		m_image = 0;
+	}
+
+	if(m_display){
+		if(m_win){
+			XUnmapWindow(m_display, m_win);
+			XClearWindow(m_display, m_win);
+			m_win = 0;
+		}
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+
+	m_imagemutex.Unlock();
+}
+
+void CVideoSender::Playback(uint8_t* videodata, int width, int height)
+{
+	AVPicture pic_rgb24, pic_rgb32;
+	
+	if(!IsInitialized())
+		return;
+	
+	m_imagemutex.Lock();
+	
+// printf("****************%d\n",CVDecoder::input_pixfmt);
+	if(m_display && m_image && m_win){
+		
+		avpicture_fill(&pic_rgb32, (uint8_t*)m_image->data, CVDecoder::input_pixfmt,
+					width, height);
+		avpicture_fill(&pic_rgb24, videodata, PIX_FMT_BGR24,
+					width, height);
+					
+		if(img_convert(&pic_rgb32, CVDecoder::input_pixfmt, &pic_rgb24, PIX_FMT_BGR24, 
+			width, height) < 0){
+			PErrorText("Error pixel format conversion");
+			m_imagemutex.Unlock();
+			return ;
+		}
+	
+	
+		XPutImage(m_display, m_win, m_gc, m_image, 
+					0, 0, 0, 0,
+					width, height);
+	}
+	
+	m_imagemutex.Unlock();
+	return;
+}
+
+
+int CVideoSender::Start(char* szFile /* =0 */, bool bIsRecord /* =false */)
+{
+	if(!IsInitialized())
+		return -1;
+
+	if (JThread::IsRunning())
+		return 0;
+
+	if (!stopmutex.IsInitialized())
+	{
+		if (stopmutex.Init() < 0)
+			return -2;
+	}
+	
+	stop = false;
+	
+	if (!m_recordmutex.IsInitialized())
+	{
+		if (m_recordmutex.Init() < 0)
+			return -2;
+	}
+
+	m_bIsRecord = bIsRecord;	
+
+	if(bIsRecord && szFile != 0){
+		if(m_hFile){
+			fclose(m_hFile);
+			m_hFile = 0;
+		} 
+		
+		m_hFile = fopen(szFile, "wb");
+		if(m_hFile==0){
+			return -3;
+		}
+
+		m_bIsRecord = true;
+	}
+
+	if(m_sendthread.Start() < 0){
+		return -6;
+	}
+	
+	if (JThread::Start() < 0){
+		m_bIsRecord = false;
+		return -6;
+	}
+
+	return 0;
+}
+
+void CVideoSender::Stop()
+{	
+	if (!IsRunning())
+		return;
+	
+	stopmutex.Lock();
+	stop = true;
+	stopmutex.Unlock();
+	
+	//wait for two minute;
+	sleep(1);
+	if (JThread::IsRunning())
+	{
+#ifndef _WIN32_WCE
+		std::cerr << "RTPPollThread: Warning! Having to kill thread!" << std::endl;
+#endif // _WIN32_WCE
+		JThread::Kill();
+	}
+	stop = false;
+
+	
+	//close file.
+	if(m_hFile){
+		fclose(m_hFile);
+		m_hFile = 0;
+	} 
+
+	m_sendthread.Stop();
+	
+	m_bIsRecord = false;
+}
+
+void CVideoSender::SetMode(VIDEOSENDERMODE mode)
+{
+	if(!IsInitialized())
+		return;
+	
+	if(mode==ModeCapture || mode==ModeTransmit || mode==ModeNone){
+
+		m_modemutex.Lock();
+		m_mode = mode;
+		m_modemutex.Unlock();
+	}
+
+
+}
+
+void CVideoSender::Record(bool bInRecord /* =true */)
+{
+	if(!IsInitialized())
+		return ;
+	
+	m_recordmutex.Lock();
+	m_bIsRecord = bInRecord;
+	m_recordmutex.Unlock();
+	
+}
+
+
+
+void *CVideoSender::Thread()
+{
+	char * data;
+	int OutBufSzie;
+	int status;
+
+	JThread::ThreadStarted();
+	
+	bool stopthread;
+	VIDEOSENDERMODE mode;
+//	VideoPlayback fun;
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+	
+	bool isrecord;
+	m_recordmutex.Lock();
+	isrecord = m_bIsRecord;
+	m_recordmutex.Unlock();
+	
+	
+	int64_t pre_time, cur_time;
+	useconds_t delay1;	
+	pre_time =  av_gettime();
+	if(m_vencoder.m_pCodecCtx->frame_rate!=0){
+		if(m_vencoder.m_pCodecCtx->frame_rate_base!=0)
+			delay1 = 1000000*m_vencoder.m_pCodecCtx->frame_rate_base/m_vencoder.m_pCodecCtx->frame_rate;
+		else
+			delay1 = 1000000/m_vencoder.m_pCodecCtx->frame_rate;
+	}
+	else{
+		delay1 = 40000;
+	}
+
+	delay1 = 40000;
+	cur_time = pre_time = av_gettime();
+	pre_time -= delay1;
+	
+	
+	int64_t nFrame;
+	int64_t rec_time,rec_start;
+	rec_start = cur_time;
+	rec_time = 0;
+	nFrame = 0;
+	while (!stopthread)
+	{
+	if(cur_time-pre_time>=delay1){
+/*		cur_time = av_gettime();
+		delay = cur_time-pre_time;
+		if(delay < delay1){
+			usleep(delay1-delay);
+			pre_time = av_gettime();
+		}
+*/
+		pre_time = av_gettime();
+		
+		m_modemutex.Lock();
+		mode = m_mode;
+		m_modemutex.Unlock();
+
+		if(mode==ModeNone){
+			stopmutex.Lock();
+			stopthread = stop;
+			stopmutex.Unlock();
+			
+			cur_time = av_gettime();
+			continue;
+		}
+//		STARTTIME
+		status = m_vencoder.Capture(&data);
+//		ENDTIME
+		if ((status) < 0)
+		{
+			printf("\nvideo: capture vital error.");
+			stopthread = true;
+		}
+		else{
+			if(mode==ModeCapture||mode==ModeTransmit){
+				int width, height;
+				m_vencoder.GetCapSize(width, height);
+				Playback((uint8_t*)data, width, height);		
+				
+				if(mode==ModeCapture){
+					stopmutex.Lock();
+					stopthread = stop;
+					stopmutex.Unlock();
+			
+					cur_time = av_gettime();
+					continue;
+				}
+			}
+
+			OutBufSzie = CVEncoder::V_En_OutBufSize;
+			if ((status = m_vencoder.EncodeProcess(data, m_pOutBuf, OutBufSzie)) < 0)
+			{
+				printf("\nvideo: encode vital error.");
+				stopthread = true;
+			}
+			else{
+				nFrame++;
+				if(status>0 && mode==ModeTransmit){
+//					STARTTIME
+					m_sendthread.SendData(m_pOutBuf, status);
+//					ENDTIME
+//					printf("\n***************video send*************:  %d bytes encoded.", status);
+					if(m_hFile!=0 && isrecord)
+						fwrite(m_pOutBuf+sizeof(VideoHeader), status-sizeof(VideoHeader), 1, m_hFile);
+				}
+	
+				m_recordmutex.Lock();
+				isrecord = m_bIsRecord;
+				m_recordmutex.Unlock();
+
+				stopmutex.Lock();
+				stopthread = stop;
+				stopmutex.Unlock();
+			}
+		}
+	}
+	
+	cur_time = av_gettime();
+//	printf("\nnFrame=%d,time=%d\n", nFrame, cur_time-rec_start);
+		
+	}
+	printf("\nvideo capture thread stoped.\n");
+	return 0;
+}
+
+bool CVideoSender::AddDestination(const RTPIPv4Address &des)
+{
+	if(!IsInitialized())
+		return false;
+
+	if(m_sendthread.AddDestination(des)<0)
+		return false;
+
+	return true;
+}
+void CVideoSender::ClearDestinations()
+{
+	if(!IsInitialized())
+		return ;
+	m_sendthread.ClearDestinations();
+}
+
+
+
+//CStuVideoSender class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CStuVideoSender::CStuVideoSender()
+{
+	stop = false;
+	m_bInit = 0;
+	
+	m_mode = ModeNone;
+
+#if (defined(WIN32) || defined(_WIN32_WCE))
+	timeinit.Dummy();
+#endif // WIN32 || _WIN32_WCE
+}
+
+CStuVideoSender::~CStuVideoSender()
+{
+	//first stop thread, because  m_pOutBuf is being used by Thread();
+	Stop();
+	
+
+	//free buffer.
+	if(m_pOutBuf!=0)
+		free(m_pOutBuf);
+}
+
+bool CStuVideoSender::Init(int nHostPort)
+{
+	if(m_bInit)
+		return true;
+
+	if(!m_imagemutex.IsInitialized()){
+		if(m_imagemutex.Init() < 0)
+			return false;
+	}
+	
+	//init rtpsession.
+	RTPSessionParams sessParams1;
+	sessParams1.SetOwnTimestampUnit(1.0 / 30.0); //30 video frames per second
+	sessParams1.SetUsePollThread(0); //background thread to call virtual callbacks - set by default, but just to be sure
+	sessParams1.SetMaximumPacketSize(MAX_PACKET_SIZE);
+	//setup transmission parameters
+	RTPUDPv4TransmissionParams transParams1;
+	transParams1.SetPortbase(nHostPort);
+	//CREATE THE SESSION
+	int status1 = m_fecrtpsession.Create(sessParams1, &transParams1);
+	if (status1){
+//		ReportError(status1);
+		return false; //unable to create the session
+	}	
+	
+	//must set for fec SendFECPacket. 
+	m_fecrtpsession.SetDefaultMark(true);
+	m_fecrtpsession.SetDefaultPayloadType(1);
+	m_fecrtpsession.SetDefaultTimestampIncrement(0);
+
+	if(m_pOutBuf==0){
+		m_pOutBuf = (uint8_t*)malloc(CVEncoder::V_En_OutBufSize);
+		if(m_pOutBuf==0){
+			return false;
+		}
+
+	}
+
+	//Init sencoder.
+	if(!m_vencoder.Init(CODEC_ID_MPEG1VIDEO)){
+		return false;
+	}
+
+	if (!m_modemutex.IsInitialized())
+	{
+		if (m_modemutex.Init() < 0)
+			return -2;
+	}
+	
+	
+	m_bInit = true;
+	return m_bInit;
+}
+
+bool CStuVideoSender::CreateXImage(Drawable parent, int x, int y, int width, int height)
+{
+	int screen_num;
+
+	if(!m_bInit)
+		return false;
+	
+
+	CloseXImage();
+
+	m_imagemutex.Lock();
+	
+	m_display = XOpenDisplay(NULL);
+	screen_num = DefaultScreen(m_display);
+	
+	
+	m_win = XCreateSimpleWindow(m_display, //display
+       	                   		    parent, //父窗口
+
+        	                  	    x, y, width, height, //Àœçœ®å’Œå€§å°„1€7
+
+				  	                0, //ÚŞ¹ç•Œå®œåºŠ
+				  	                BlackPixel(m_display, screen_num), //前ʙ¯Ú‰²
+
+				  	                65535/20);//ڃŒÊ™¯Ú‰²
+
+	XMapWindow(m_display, m_win);
+	m_gc = DefaultGC(m_display, screen_num);
+
+	// Init GlobalVar.image
+	//
+	int imagewidth, imageheight;
+	m_vencoder.GetCapSize(imagewidth, imageheight);
+	
+	m_image = XGetImage(m_display, 	//ڎ·å–圓前屏幕ʉ€Ê˜Şç€ºå›Şåƒ„1€7
+					     			  m_win,
+    	  			    			  0, 0,
+   	  			     				  imagewidth, imageheight,
+				    				  AllPlanes, ZPixmap);
+	if(!m_image){
+		printf("error\n");
+		m_imagemutex.Unlock();
+		return false;
+	}
+
+	m_imagemutex.Unlock();
+	return true;		
+}
+
+void CStuVideoSender::CloseXImage()
+{
+	if(!m_bInit)
+		return ;
+	
+	m_imagemutex.Lock();
+	
+	if(m_image){
+		XDestroyImage(m_image);
+//		m_image->f.destroy_image(m_image);
+		m_image = 0;
+	}
+
+	if(m_display){
+		if(m_win){
+			XUnmapWindow(m_display, m_win);
+			XClearWindow(m_display, m_win);
+			m_win = 0;
+		}
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+
+	m_imagemutex.Unlock();
+}
+
+void CStuVideoSender::Playback(uint8_t* videodata, int width, int height)
+{
+	AVPicture pic_rgb24, pic_rgb32;
+	
+	if(!m_bInit)
+		return;
+	
+	m_imagemutex.Lock();
+	
+	if(m_display && m_image && m_win){
+		
+		avpicture_fill(&pic_rgb32, (uint8_t*)m_image->data, PIX_FMT_RGBA32,
+					width, height);
+		avpicture_fill(&pic_rgb24, videodata, PIX_FMT_BGR24,
+					width, height);
+					
+		if(img_convert(&pic_rgb32, PIX_FMT_RGBA32, &pic_rgb24, PIX_FMT_BGR24, 
+			width, height) < 0){
+			perror("Error pixel format conversion");
+			m_imagemutex.Unlock();
+			return ;
+		}
+	
+	
+		XPutImage(m_display, m_win, m_gc, m_image, 
+					0, 0, 0, 0,
+					width, height);
+	}
+	
+	m_imagemutex.Unlock();
+	return;
+}
+
+
+int CStuVideoSender::Start(char* szFile /* =0 */, bool bIsRecord /* =false */)
+{
+	if(!m_bInit)
+		return -1;
+
+	if (JThread::IsRunning())
+		return 0;
+
+	if (!stopmutex.IsInitialized())
+	{
+		if (stopmutex.Init() < 0)
+			return -2;
+	}
+	
+	stop = false;
+
+
+	if (JThread::Start() < 0){
+		return -6;
+	}
+
+	return 0;
+}
+
+void CStuVideoSender::Stop()
+{	
+	if (!IsRunning())
+		return;
+	
+	stopmutex.Lock();
+	stop = true;
+	stopmutex.Unlock();
+	
+	//wait for two minute;
+	sleep(2);
+	if (JThread::IsRunning())
+	{
+#ifndef _WIN32_WCE
+		std::cerr << "RTPPollThread: Warning! Having to kill thread!" << std::endl;
+#endif // _WIN32_WCE
+		JThread::Kill();
+	}
+	stop = false;
+
+	
+}
+
+void CStuVideoSender::SetMode(STUVIDEOSENDERMODE mode)
+{
+	if(!m_bInit)
+		return;
+	
+	if(mode==ModeCapture || mode==ModeTransmit || mode==ModeNone){
+
+		m_modemutex.Lock();
+		m_mode = mode;
+		m_modemutex.Unlock();
+	}
+
+
+}
+
+
+void *CStuVideoSender::Thread()
+{
+	char * data;
+	int OutBufSzie;
+	int status;
+
+	JThread::ThreadStarted();
+	
+	bool stopthread;
+	STUVIDEOSENDERMODE mode;
+//	VideoPlayback fun;
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+	
+	int64_t pre_time, cur_time;
+	useconds_t delay, delay1;	
+
+	pre_time =  av_gettime();
+	if(m_vencoder.m_pCodecCtx->frame_rate!=0){
+		if(m_vencoder.m_pCodecCtx->frame_rate_base!=0)
+			delay1 = 1000000*m_vencoder.m_pCodecCtx->frame_rate_base/m_vencoder.m_pCodecCtx->frame_rate;
+		else
+			delay1 = 1000000/m_vencoder.m_pCodecCtx->frame_rate;
+	}
+	else{
+		delay1 = 40000;
+	}
+//	delay3 = 10000
+	while (!stopthread)
+	{
+
+		cur_time = av_gettime();
+		delay = cur_time-pre_time;
+		if(delay < delay1){
+			usleep(delay1-delay);
+			pre_time = av_gettime();
+		}
+
+		m_modemutex.Lock();
+		mode = m_mode;
+		m_modemutex.Unlock();
+
+		if(mode==ModeNone){
+			stopmutex.Lock();
+			stopthread = stop;
+			stopmutex.Unlock();
+			continue;
+		}
+
+		if ((status = m_vencoder.Capture(&data)) < 0)
+		{
+			printf("\nvideo: capture vital error.");
+			stopthread = true;
+		}
+		else{
+			if(mode==ModeCapture||mode==ModeTransmit){
+				int width, height;
+				m_vencoder.GetCapSize(width, height);
+				Playback((uint8_t*)data, width, height);		
+				
+				if(mode==ModeCapture){
+					stopmutex.Lock();
+					stopthread = stop;
+					stopmutex.Unlock();
+					continue;
+				}
+			}
+
+			OutBufSzie = CVEncoder::V_En_OutBufSize;
+			if ((status = m_vencoder.EncodeProcess(data, m_pOutBuf, OutBufSzie)) < 0)
+			{
+				printf("\nvideo: encode vital error.");
+				stopthread = true;
+			}
+			else{
+				if(status>0 && mode==ModeTransmit){
+					m_fecrtpsession.SendFECPacket(m_pOutBuf, status, 5000);
+				}
+
+				stopmutex.Lock();
+				stopthread = stop;
+				stopmutex.Unlock();
+			}
+		}
+
+	}
+	printf("\nvideo record close");
+	return 0;
+}
+
+bool CStuVideoSender::AddDestination(const RTPIPv4Address &des)
+{
+	if(!m_bInit)
+		return false;
+
+	if(m_fecrtpsession.AddDestination(des)<0)
+		return false;
+
+	return true;
+}
+void CStuVideoSender::ClearDestinations()
+{
+	if(!m_bInit)
+		return ;
+	m_fecrtpsession.ClearDestinations();
+}
+
+//CVideoReceiver class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CVideoReceiver::CVideoReceiver()
+{
+	m_bInit = false;
+}
+
+CVideoReceiver::~CVideoReceiver()
+{
+
+}
+
+bool CVideoReceiver::Init()
+{
+	if(m_bInit)
+		return m_bInit;
+
+	
+	if(!m_vdecoder.Init(320, 240, CODEC_ID_MPEG1VIDEO)){
+		return false;
+	}
+
+
+	m_bInit = true;
+	return m_bInit;
+
+}
+
+bool CVideoReceiver::CreateXImage(Drawable parent, int x, int y, int width, int height)
+{
+	bool ret;
+	//init video decoder.
+	
+	ret = m_vdecoder.CreateXImage(parent, x, y, width, height);
+	
+	return ret;
+}
+
+void CVideoReceiver::CloseXImage()
+{
+	m_vdecoder.CloseXImage();
+}
+
+
+int CVideoReceiver::Start(int nHostPort)
+{
+	if(!m_bInit)
+		return -1;
+
+	if(IsActive())
+		return 0;
+
+	//init rtpsession.
+	RTPSessionParams sessParams1;
+	sessParams1.SetOwnTimestampUnit(1.0 / 30.0); //30 video frames per second
+	sessParams1.SetUsePollThread(1); //background thread to call virtual callbacks - set by default, but just to be sure
+	sessParams1.SetMaximumPacketSize(MAX_PACKET_SIZE);
+	//setup transmission parameters
+	RTPUDPv4TransmissionParams transParams1;
+	transParams1.SetPortbase(nHostPort);
+	//CREATE THE SESSION
+	int status1 = Create(sessParams1, &transParams1);
+	if (status1){
+//		ReportError(status1);
+		return -2; //unable to create the session
+	}	
+
+	return 0;
+}
+
+void CVideoReceiver::Stop()
+{
+	Destroy();
+}
+
+void CVideoReceiver::ProcessFrame(unsigned char* framedata, int framelen)
+{
+	//printf("\nVideo decodeproocessing(%d): %d bytes\n", m_usLatestVideoSeq, framelen);
+	
+	pVideo= (VideoHeader*)framedata;	
+	//printf("%d,%d\n",pVideo->width,pVideo->height);
+	if(	pVideo->width!=m_vdecoder.m_width || pVideo->height != m_vdecoder.m_height){
+			m_vdecoder.ResetCodec(	pVideo->width, pVideo->height);
+	}
+	m_vdecoder.DecodeProcess(framedata+sizeof(VideoHeader), framelen-sizeof(VideoHeader));
+}
+
+
+#ifdef HAVE_1394_CONFIG_H
+//C1394VEncoder class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+C1394VEncoder::C1394VEncoder()
+{
+	m_pFrameBuf = 0;
+	m_pFrame = 0;
+    m_pCodec  = 0;
+	m_pCodecCtx  = 0;
+	m_bInit = false;
+}
+
+C1394VEncoder::~C1394VEncoder()
+{
+	if(m_pFrameBuf){
+		free(m_pFrameBuf);
+		m_pFrameBuf = 0;
+	}
+
+
+	if(m_pFrame){
+		free(m_pFrame);
+		m_pFrame = 0;
+	}
+	if(m_pCodecCtx){
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+	m_bInit = false;
+	
+}
+
+bool C1394VEncoder::Init(int width, int height, enum CodecID nCodecID /*=CODEC_ID_MPEG1VIDEO*/)
+{
+	m_bInit = false;
+	/*Init for encode*/
+	avcodec_init();
+    avcodec_register_all();
+	
+	//new a frame object.
+	if(m_pFrame){
+		free(m_pFrame);
+		m_pFrame = 0;
+	}
+	m_pFrame = avcodec_alloc_frame();
+	if(m_pFrame==0){
+		return false;
+	}
+	
+	/* find the video encoder */
+	m_pCodec = avcodec_find_encoder(nCodecID);
+	if (!m_pCodec) {
+		PErrorText("codec not found");
+		
+		printf("\ncodec not found\n");
+		return false;
+	}
+	
+	if(m_pCodecCtx){
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+
+	m_pCodecCtx = avcodec_alloc_context();
+	/* resolution must be a multiple of two */
+	m_pCodecCtx->width = width;  
+	m_pCodecCtx->height = height;
+	/* frames per second */
+	m_pCodecCtx->frame_rate = V_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= V_CODEC_frame_rate_base;
+
+	m_pCodecCtx->bit_rate = 512*1024;          // 1128kbps->512kbps
+	m_pCodecCtx->gop_size = V_CODEC_gop_size; /* emit one intra frame every ten frames */
+	m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
+	m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
+	
+	/* open it */
+	if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) {
+		PErrorText("could not open codec");
+		return false;
+	}
+	
+	//malloc outbuf.
+	if(m_pFrameBuf){
+		free(m_pFrameBuf);
+		m_pFrameBuf = 0;
+	}
+	
+	int image_size = avpicture_get_size (PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+
+	m_pFrameBuf = (uint8_t*)malloc(image_size);
+	if(m_pFrameBuf == 0){
+		PErrorText("FrameBuf malloc failed!");
+		return false;
+	}
+	/*Init for encode*/
+	
+
+	avpicture_fill ((AVPicture*)m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+	m_pFrame->type = FF_BUFFER_TYPE_SHARED;
+//	printf("\nWarning:m_pFrame->type is not seted!!!!!!!!!!!!!!!!!!!!!!!!\n");
+
+	m_bInit = true;
+	return true;
+}
+
+
+int C1394VEncoder::EncodeProcess(char *frameaddress, uint8_t *pOutBuf, int nOutsize)
+{
+	if(!m_bInit)
+		return -1;
+
+	if(nOutsize<V_En_OutBufSize){
+		return -2;
+	}
+
+	avpicture_fill(&m_pic_rgb, (uint8_t *)frameaddress, PIX_FMT_RGB24, m_pCodecCtx->width, m_pCodecCtx->height);
+	avpicture_fill((AVPicture*)m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+	
+	if (img_convert ((AVPicture*)m_pFrame, PIX_FMT_YUV420P,
+		&m_pic_rgb, PIX_FMT_RGB24, m_pCodecCtx->width, m_pCodecCtx->height) < 0) {
+		fprintf (stderr, "xtoffmpeg.XImageToFFMPEG(): pixel format conversion not handled ... aborting\n");
+		return -3;
+	}
+	
+	m_VideoHeader.width=m_pCodecCtx->width;
+	m_VideoHeader.height=m_pCodecCtx->height;
+	memcpy((char *)pOutBuf,&m_VideoHeader, sizeof(VideoHeader));
+
+	int iii = avcodec_encode_video(m_pCodecCtx, pOutBuf+sizeof(VideoHeader), nOutsize, m_pFrame);
+
+	if(iii<=0)
+		return -4;
+	
+	return iii+sizeof(VideoHeader);
+}
+
+bool C1394VEncoder::GetCapSize(int &width, int &height)
+{
+	if(!m_bInit)
+		return false;
+	
+	width = m_pCodecCtx->width;
+	height = m_pCodecCtx->height;
+	
+	return true;
+}
+
+
+
+void C1394VEncoder::GetColorInfo (XImage *image, ColorInfo *ci /* return struct */)
+{
+	unsigned long red_mask, green_mask, blue_mask, alpha_mask;
+	// the shifts are unsigned longs as well
+
+	if (!ci)
+		return;
+
+	// setting shifts and bit_depths to zero
+	ci->red_shift = ci->green_shift = ci->blue_shift = ci->alpha_shift = 0;
+	ci->red_bit_depth = ci->green_bit_depth = ci->blue_bit_depth =
+		ci->alpha_bit_depth = 0;
+
+	red_mask = image->red_mask;
+	if (red_mask > 0) {
+		// shift red_mask to the right till all empty bits have been
+		// shifted out and count how many they were
+		while ((red_mask & 0x01) == 0) {
+			red_mask >>= 1;
+			ci->red_shift++;
+		}
+		// count how many bits are set in the mask = depth
+		while ((red_mask & 0x01) == 1) {
+			red_mask >>= 1;
+			ci->red_bit_depth++;
+		}
+	}
+
+	ci->red_max_val = (1 << ci->red_bit_depth) - 1;
+
+	green_mask = image->green_mask;
+	if (green_mask > 0) {
+		while ((green_mask & 0x01) == 0) {
+			green_mask >>= 1;
+			ci->green_shift++;
+		}
+		while ((green_mask & 0x01) == 1) {
+			green_mask >>= 1;
+			ci->green_bit_depth++;
+		}
+	}
+	ci->green_max_val = (1 << ci->green_bit_depth) - 1;
+
+	blue_mask = image->blue_mask;
+	if (blue_mask > 0) {
+		while ((blue_mask & 0x01) == 0) {
+			blue_mask >>= 1;
+			ci->blue_shift++;
+		}
+		while ((blue_mask & 0x01) == 1) {
+			blue_mask >>= 1;
+			ci->blue_bit_depth++;
+		}
+	}
+	ci->blue_max_val = (1 << ci->blue_bit_depth) - 1;
+
+	/* over all max values */
+	// whatever they are good for
+	ci->max_val = max (ci->red_max_val, ci->green_max_val);
+	ci->max_val = max (ci->blue_max_val, ci->max_val);
+	ci->bit_depth = max (ci->red_bit_depth, ci->green_bit_depth);
+	ci->bit_depth = max (ci->blue_bit_depth, ci->bit_depth);
+	if (image->bits_per_pixel > image->depth) {
+		/* alpha? */
+		// this seems to not reflect X's ignorance of alpha in its
+		// masks
+		ci->alpha_mask = ~
+			(image->red_mask | image->blue_mask | image->green_mask); 
+		alpha_mask = ci->alpha_mask;
+		if (alpha_mask > 0) {
+			while ((alpha_mask & 0x01) == 0) {
+				alpha_mask >>= 1;
+				ci->alpha_shift++;
+			}
+			while ((alpha_mask & 0x01) == 1) {
+				alpha_mask >>= 1;
+				ci->alpha_bit_depth++;
+			}
+		}
+		ci->alpha_max_val = (1 << ci->alpha_bit_depth) - 1;
+	}
+}
+
+//C1394VideoSender class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+C1394VideoSender::C1394VideoSender() : m_sendthread(SendBufSize)
+{
+	stop = false;
+	m_bIsRecord = false;
+	m_bInit = 0;
+	
+	m_pOutBuf = 0;
+	m_hFile = 0;
+	m_mode = ModeNone;
+	m_p1394reader = 0;
+	m_pCapBuf = 0;
+
+	if(!m_initmutex.IsInitialized()){
+		m_initmutex.Init();
+	}
+	
+	m_display = 0;
+	m_image = 0;
+	m_win = 0;
+	m_d = 0;
+}
+
+C1394VideoSender::~C1394VideoSender()
+{
+	//first stop thread, because  m_pOutBuf is being used by Thread();
+	Stop();
+	
+	//close file.
+	if(m_hFile){
+		fclose(m_hFile);
+		m_hFile = 0;
+	} 
+
+	//free buffer.
+	if(m_pOutBuf!=0){
+		free(m_pOutBuf);
+		m_pOutBuf = 0;
+	}
+	
+	// for image
+	if(m_image){
+		XDestroyImage(m_image);
+		m_image = 0;
+	}
+
+	if(m_display){
+		if(m_win){
+			XUnmapWindow(m_display, m_win);
+			XClearWindow(m_display, m_win);
+			m_win = 0;
+		}
+		
+		if(m_d){
+			XClearWindow(m_display, m_d);
+			m_d = 0;
+		}
+		
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+}
+
+#define MAX_PACKET_SIZE 10*1024
+bool C1394VideoSender::Init(int nHostPort)
+{
+	m_initmutex.Lock();
+	m_bInit = false;
+	
+	if(!m_imagemutex.IsInitialized()){
+		if(m_imagemutex.Init() < 0){
+		    m_initmutex.Unlock();
+			return false;
+		}
+	}
+	
+	if(!m_sendthread.Init(nHostPort)){
+		
+		m_initmutex.Unlock();
+		return false;
+	}
+
+	if(m_pOutBuf==0){
+		m_pOutBuf = (uint8_t*)malloc(C1394VEncoder::V_En_OutBufSize);
+		if(m_pOutBuf==0){
+			m_initmutex.Unlock();
+			return false;
+		}
+
+	}
+
+	//Init sencoder.
+	if(!m_vencoder.Init(VideoWidth, VideoHeight, CODEC_ID_MPEG1VIDEO)){
+		m_initmutex.Unlock();
+		return false;
+	}
+
+	if (!m_modemutex.IsInitialized())
+	{
+		if (m_modemutex.Init() < 0){
+			m_initmutex.Unlock();
+			return false;
+		}
+		
+	}
+	
+	
+	m_bIsRecord = false;
+	
+	m_bInit = true;
+	m_initmutex.Unlock();
+	return true;
+}
+
+bool C1394VideoSender::IsInitialized()
+{
+	bool b;
+	
+	m_initmutex.Lock();
+	b = m_bInit;
+	m_initmutex.Unlock();
+	
+	return b;
+}
+
+
+bool C1394VideoSender::CreateXImage(Drawable parent, int x, int y, int width, int height)
+{
+	int screen_num;
+
+	
+	if(!IsInitialized())
+		return false;
+	
+	CloseXImage();
+
+	m_imagemutex.Lock();
+	
+	m_display = XOpenDisplay(NULL);
+	screen_num = DefaultScreen(m_display);
+	
+	
+	m_win = XCreateSimpleWindow(m_display, //display
+       	                   		    parent, //父窗口
+
+        	                  	    x, y, width, height, //Àœçœ®å’Œå€§å°„1€7
+
+				  	                0, //ÚŞ¹ç•Œå®œåºŠ
+				  	                BlackPixel(m_display, screen_num), //前ʙ¯Ú‰²
+
+				  	                65535/20);//ڃŒÊ™¯Ú‰²
+
+	XMapWindow(m_display, m_win);
+	m_gc = DefaultGC(m_display, screen_num);
+
+	int imagewidth, imageheight;
+	m_vencoder.GetCapSize(imagewidth, imageheight);
+	
+	m_d = RootWindow(m_display, screen_num);
+	
+	m_image = XGetImage(m_display, 	//ڎ·å–圓前屏幕ʉ€Ê˜Şç€ºå›Şåƒ„1€7
+					     			  m_d,
+    	  			    			  0, 0,
+   	  			     				  imagewidth, imageheight,
+				    				  AllPlanes, ZPixmap);
+	if(!m_image){
+		PErrorText("GetImage error");
+		m_imagemutex.Unlock();
+		return false;
+	}
+
+	m_imagemutex.Unlock();
+	return true;		
+}
+
+void C1394VideoSender::CloseXImage()
+{
+	
+	if(!IsInitialized())
+		return ;
+	
+	m_imagemutex.Lock();
+	
+	if(m_image){
+		XDestroyImage(m_image);
+		m_image = 0;
+	}
+
+	if(m_display){
+		if(m_win){
+			XUnmapWindow(m_display, m_win);
+			XClearWindow(m_display, m_win);
+			m_win = 0;
+		}
+		
+		if(m_d){
+			XClearWindow(m_display, m_d);
+			m_d = 0;
+		}
+		
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+
+	m_imagemutex.Unlock();
+}
+
+void C1394VideoSender::Playback(uint8_t* videodata)
+{
+	AVPicture pic_rgb24, pic_rgb32;
+	int width, height;
+	
+	if(!IsInitialized())
+		return;
+	
+	m_vencoder.GetCapSize(width, height);
+	
+	m_imagemutex.Lock();
+	
+// printf("****************%d\n",CVDecoder::input_pixfmt);
+	if(m_display && m_image && m_win){
+		
+		avpicture_fill(&pic_rgb32, (uint8_t*)m_image->data, CVDecoder::input_pixfmt,
+					width, height);
+		avpicture_fill(&pic_rgb24, videodata, PIX_FMT_RGB24,
+					width, height);
+					
+		if(img_convert(&pic_rgb32, CVDecoder::input_pixfmt, &pic_rgb24, PIX_FMT_RGB24, 
+			width, height) < 0){
+			PErrorText("Error pixel format conversion");
+			m_imagemutex.Unlock();
+			return ;
+		}
+	
+	
+		XPutImage(m_display, m_win, m_gc, m_image, 
+					0, 0, 0, 0,
+					width, height);
+	}
+	
+	m_imagemutex.Unlock();
+	return;
+}
+
+int C1394VideoSender::Start(char* szFile /* =0 */, bool bIsRecord /* =false */)
+{
+	
+	if(!IsInitialized())
+		return -1;
+
+	if (JThread::IsRunning())
+		return 0;
+
+	if (!stopmutex.IsInitialized())
+	{
+		if (stopmutex.Init() < 0)
+			return -2;
+	}
+	
+	stop = false;
+	
+	if (!m_recordmutex.IsInitialized())
+	{
+		if (m_recordmutex.Init() < 0)
+			return -2;
+	}
+
+	m_bIsRecord = bIsRecord;	
+
+	
+	if(!StartCapture()){
+		return -7;
+	}
+	
+	if( szFile != 0){
+		if(m_hFile){
+			fclose(m_hFile);
+			m_hFile = 0;
+		} 
+		
+		m_hFile = fopen(szFile, "wb");
+		if(m_hFile==0){
+			m_bIsRecord = false;
+			return -3;
+		}
+
+	}
+
+	if(m_sendthread.Start() < 0){
+		return -6;
+	}
+	
+	if (JThread::Start() < 0){
+		m_bIsRecord = false;
+		return -6;
+	}
+
+	return 0;
+}
+
+void C1394VideoSender::Stop()
+{	
+	if (!IsRunning())
+		return;
+	
+	stopmutex.Lock();
+	stop = true;
+	stopmutex.Unlock();
+	
+	//wait for two minute;
+	
+//	sleep(1);
+//	if (JThread::IsRunning())
+//	{
+//		JThread::Kill();
+//	}	
+	
+	int count=0;
+	while(1){
+		if(count>=100){
+			if (JThread::IsRunning())
+			{
+				JThread::Kill();
+			}
+			break;
+		}
+		
+		if(JThread::IsRunning()){
+			count++;
+			usleep(10000);
+			continue;
+		}
+		
+		break;
+	}
+
+	stop = false;
+	
+	//close file.
+	if(m_hFile){
+		fclose(m_hFile);
+		m_hFile = 0;
+	} 
+
+	m_sendthread.Stop();
+	
+	StopCapture();	
+	m_bIsRecord = false;
+}
+
+void C1394VideoSender::SetMode(_1394VIDEO_SEND_MODE mode)
+{
+	
+	if(!IsInitialized())
+		return;
+	
+	if(mode==ModeCapture || mode==ModeTransmit || mode==ModeNone){
+
+		m_modemutex.Lock();
+		m_mode = mode;
+		m_modemutex.Unlock();
+	}
+
+
+}
+
+void C1394VideoSender::Record(bool bInRecord /* =true */)
+{
+	
+	if(!IsInitialized())
+		return;
+	
+	m_recordmutex.Lock();
+	m_bIsRecord = bInRecord;
+	m_recordmutex.Unlock();
+	
+}
+
+void *C1394VideoSender::Thread()
+{
+	char * data;
+	int OutBufSzie;
+	int status;
+
+	JThread::ThreadStarted();
+	
+	bool stopthread;
+	_1394VIDEO_SEND_MODE mode;
+//	VideoPlayback fun;
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+	
+	bool isrecord;
+	m_recordmutex.Lock();
+	isrecord = m_bIsRecord;
+	m_recordmutex.Unlock();
+	
+	
+	int64_t pre_time, cur_time;
+	useconds_t delay, delay1;	
+	pre_time =  av_gettime();
+	if(m_vencoder.m_pCodecCtx->frame_rate!=0){
+		if(m_vencoder.m_pCodecCtx->frame_rate_base!=0)
+			delay1 = 1000000*m_vencoder.m_pCodecCtx->frame_rate_base/m_vencoder.m_pCodecCtx->frame_rate;
+		else
+			delay1 = 1000000/m_vencoder.m_pCodecCtx->frame_rate;
+	}
+	else{
+		delay1 = 62500; // 1000000/16 = 62500
+	}
+	
+	// sleep for sync
+	if(delay_time > 0){
+		sleep(delay_time);
+	}
+	
+	// for utility rate of CPU
+	cur_time = pre_time = av_gettime();
+	pre_time -= delay1;
+	
+	// for compensate.
+	int64_t nFrame=0;
+	int64_t rec_time=0;
+	int64_t rec_start;
+	rec_start = av_gettime();
+	while (!stopthread)
+	{
+		delay = cur_time - pre_time;
+	    if(delay < delay1){
+			usleep(delay1 - delay);
+		}
+		pre_time = av_gettime();
+		
+		
+		m_modemutex.Lock();
+		mode = m_mode;
+		m_modemutex.Unlock();
+
+		if(mode==ModeNone){
+			stopmutex.Lock();
+			stopthread = stop;
+			stopmutex.Unlock();
+			
+			rec_start = cur_time = av_gettime();
+			nFrame = 0;
+			cur_time = av_gettime();
+			continue;
+		}
+
+		if ((status = Capture((uint8_t**)&data)) < 0)
+		{
+			printf("\nvideo: capture vital error.");
+			stopthread = true;
+			continue;
+		}
+		else{
+			if(mode==ModeCapture||mode==ModeTransmit){
+//				int width, height;
+//				m_vencoder.GetCapSize(width, height);
+				Playback((uint8_t*)data);		
+				
+				if(mode==ModeCapture){
+					stopmutex.Lock();
+					stopthread = stop;
+					stopmutex.Unlock();
+					
+					rec_start = cur_time = av_gettime();
+					nFrame = 0;
+					cur_time = av_gettime();
+					continue;
+				}
+			}
+
+			OutBufSzie = C1394VEncoder::V_En_OutBufSize;
+			if ((status = m_vencoder.EncodeProcess(data, m_pOutBuf, OutBufSzie)) < 0)
+			{
+				printf("\nvideo: encode vital error.");
+				stopthread = true;
+				continue;
+			}
+			else{
+				if(status>0 && mode==ModeTransmit){
+					m_sendthread.SendData(m_pOutBuf, status);
+//					printf("\n-----------------video send------------------:  %d bytes encoded.", status);
+					if(m_hFile!=0 && isrecord){
+						nFrame++;
+						fwrite(m_pOutBuf+sizeof(VideoHeader), status-sizeof(VideoHeader), 1, m_hFile);
+						
+						//add up rec_time;
+						rec_time = av_gettime()-rec_start;
+						int i;
+						for(i=0;rec_time>nFrame*delay1;nFrame++, i++){
+					//		printf("(%d): rec_time=%ld, ", i, rec_time, nFrame);
+					//		printf("nFrame=%d\n", nFrame);
+							if( (status = m_vencoder.EncodeProcess(data, m_pOutBuf, OutBufSzie) )<0){
+								printf("\nvideo: encode vital error.");
+								stopthread = true;
+								printf("\nvideo capture thread stoped by EncodeProcess error!\n");
+								return 0;
+							}
+							if(status>0){
+							    fwrite(m_pOutBuf+sizeof(VideoHeader), status-sizeof(VideoHeader), 1, m_hFile);
+								//printf("1394 frame conpensation .... \n");
+							}
+						}
+						
+						//printf("\n1394 video rec_time=%ld,", rec_time);
+						//printf("Frame=%ld\n", nFrame);
+
+					}
+					else{
+						rec_start = av_gettime();
+						nFrame = 0;
+					}
+					
+				}
+	
+//				m_recordmutex.Lock();
+//				isrecord = m_bIsRecord;
+//				m_recordmutex.Unlock();
+
+//				stopmutex.Lock();
+//				stopthread = stop;
+//				stopmutex.Unlock();
+			}
+		}
+		
+		cur_time = av_gettime();
+	}
+
+	m_recordmutex.Lock();
+	isrecord = m_bIsRecord;
+	m_recordmutex.Unlock();
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+
+	// printf("\n--------------nFrame=%d:%d \n", nFrame, (int)rec_time);
+
+	printf("\nvideo capture thread stoped.\n");
+	return 0;
+}
+
+bool C1394VideoSender::AddDestination(const RTPIPv4Address &des)
+{
+	
+	if(!IsInitialized())
+		return false;
+
+	if(m_sendthread.AddDestination(des)<0)
+		return false;
+
+	return true;
+}
+void C1394VideoSender::ClearDestinations()
+{
+
+	if(!IsInitialized())
+		return;
+	
+	m_sendthread.ClearDestinations();
+}
+
+
+bool C1394VideoSender::StartCapture()
+{
+	StopCapture();
+	
+	m_pCapBuf = (void*) malloc(FRAME_MAX_WIDTH*FRAME_MAX_HEIGHT*4);
+	if(m_pCapBuf==0)
+		return false;
+	
+	m_p1394reader = new raw1394Reader(0, 63, 5);
+	
+	if(m_p1394reader == 0)
+	    return false;
+	
+	
+	if(!m_p1394reader->StartThread()){
+		delete m_p1394reader;
+		m_p1394reader = 0;
+	    return false;
+	}
+	
+	return true;
+	
+}
+
+void C1394VideoSender::StopCapture()
+{
+
+	if(m_p1394reader){
+		m_p1394reader->StopThread();
+		m_p1394reader->StopReceive();
+		m_p1394reader->Close();
+		delete m_p1394reader;
+		m_p1394reader = 0;
+	}
+ 
+	if(m_pCapBuf){
+		free(m_pCapBuf);
+		m_pCapBuf = 0;
+	}
+}
+
+bool C1394VideoSender::IsHaved1394Video()
+{
+
+	bool res = false;
+/*
+	if(IsInitialized()){
+		if(IsRunning())
+	}
+	else{
+		
+	}
+*/
+	
+	return res;
+}
+
+int C1394VideoSender::Capture(uint8_t** data)
+{
+	Frame *pFrame;
+	m_p1394reader->WaitForAction();
+	pFrame = m_p1394reader->GetFrame();
+	
+	pFrame->ExtractRGB(m_pCapBuf);
+	Scale();
+	m_p1394reader->DoneWithFrame(pFrame);
+	
+	*data = (uint8_t*)m_pCapBuf;
+	return 0;
+
+}
+
+void C1394VideoSender::Scale()
+{
+	int width, height;
+	GdkPixbuf *original_pixbuf = 0;
+	GdkPixbuf *scaled_pixbuf = 0;
+
+	width=0,height=0;
+	m_vencoder.GetCapSize(width, height);
+	if(width==720 && height == 576)
+	    return;
+	original_pixbuf = gdk_pixbuf_new_from_data((const guchar*)m_pCapBuf, // const guchar *data
+									   GDK_COLORSPACE_RGB, // GdkColorspace colorspace
+									   FALSE, // gboolean has_alpha
+									   8, // int bits_per_sample
+									   720, // int width
+									   576, // int height
+									   720*3, // int rowstride
+									   NULL,// GdkPixbufDestroyNotify destroy_fn
+									   NULL); // gpointer destroy_fn_data
+	if(original_pixbuf == 0){
+		g_object_unref(original_pixbuf);
+		printf("\n gdk_pixbuf_new_from_data failed!! \n");
+		return ;
+	}
+
+	scaled_pixbuf = gdk_pixbuf_scale_simple(original_pixbuf, width, height, GDK_INTERP_BILINEAR);
+
+	if(scaled_pixbuf == 0){
+		g_object_unref(scaled_pixbuf);
+		printf("\n gdk_pixbuf_scale_simple failed!!! \n");
+		return ;
+	}
+	
+	memcpy(m_pCapBuf, (uint8_t*)gdk_pixbuf_get_pixels(scaled_pixbuf), width*height*3);
+	g_object_unref(original_pixbuf);
+	g_object_unref(scaled_pixbuf);
+	
+}
+#endif // HAVE_1394_CONFIG_H
+
+//CV4LVEncoder class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CV4LVEncoder::CV4LVEncoder()
+{
+	m_pFrameBuf = 0;
+	m_pFrame = 0;
+    m_pCodec  = 0;
+	m_pCodecCtx  = 0;
+	m_bInit = false;
+//	for test encode.
+//	pFile = fopen("video.mpg", "wb+");	
+}
+
+CV4LVEncoder::~CV4LVEncoder()
+{
+//	for test encode.
+//	if(pFile!=0)
+//		fclose(pFile);
+	
+	
+	if(m_pFrameBuf){
+		free(m_pFrameBuf);
+		m_pFrameBuf = 0;
+	}
+
+
+	if(m_pFrame){
+		free(m_pFrame);
+		m_pFrame = 0;
+	}
+	if(m_pCodecCtx){
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+	m_bInit = false;
+	
+}
+
+bool CV4LVEncoder::Init(int width, int height, enum CodecID nCodecID /*=CODEC_ID_MPEG1VIDEO*/)
+{
+	m_bInit = false;
+	/*Init for encode*/
+	avcodec_init();
+    avcodec_register_all();
+	
+	//new a frame object.
+	if(m_pFrame){
+		free(m_pFrame);
+		m_pFrame = 0;
+	}
+	m_pFrame = avcodec_alloc_frame();
+	if(m_pFrame==0){
+		return false;
+	}
+	
+	/* find the video encoder */
+	m_pCodec = avcodec_find_encoder(nCodecID);
+	if (!m_pCodec) {
+		PErrorText("codec not found");
+		
+		printf("\ncodec not found\n");
+		return false;
+	}
+	
+	if(m_pCodecCtx){
+		avcodec_close(m_pCodecCtx);
+		m_pCodecCtx = 0;
+	}
+
+	m_pCodecCtx = avcodec_alloc_context();
+	/* resolution must be a multiple of two */
+	m_pCodecCtx->width = width;  
+	m_pCodecCtx->height = height;
+	/* frames per second */
+	m_pCodecCtx->frame_rate = V_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= V_CODEC_frame_rate_base;
+	
+	m_pCodecCtx->bit_rate = 512*1024;          //1128kbps->512kbps
+	m_pCodecCtx->gop_size = V_CODEC_gop_size; /* emit one intra frame every ten frames */
+	m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
+	m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
+	
+	/* open it */
+	if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) {
+		PErrorText("could not open codec");
+		return false;
+	}
+	
+	//malloc outbuf.
+	if(m_pFrameBuf){
+		free(m_pFrameBuf);
+		m_pFrameBuf = 0;
+	}
+	
+	int image_size = avpicture_get_size (PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+
+	m_pFrameBuf = (uint8_t*)malloc(image_size);
+	if(m_pFrameBuf == 0){
+		PErrorText("FrameBuf malloc failed!");
+		return false;
+	}
+	/*Init for encode*/
+	
+
+	avpicture_fill ((AVPicture*)m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+	m_pFrame->type = FF_BUFFER_TYPE_SHARED;
+//	printf("\nWarning:m_pFrame->type is not seted!!!!!!!!!!!!!!!!!!!!!!!!\n");
+
+	m_bInit = true;
+	return true;
+}
+
+//	for test encode.
+//void SaveVideoFile(char* buf, int bufsize)
+//{
+//	fwrite(buf, bufsize, 1, pFile);
+//	return;
+//}
+int CV4LVEncoder::EncodeProcess(char *frameaddress, uint8_t *pOutBuf, int nOutsize)
+{
+
+	if(!m_bInit)
+		return -1;
+
+	if(nOutsize<V_En_OutBufSize){
+		return -2;
+	}
+
+	avpicture_fill(&m_pic_rgb, (uint8_t *)frameaddress, PIX_FMT_BGR24, m_pCodecCtx->width, m_pCodecCtx->height);
+	avpicture_fill((AVPicture*)m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, m_pCodecCtx->width, m_pCodecCtx->height);
+	
+	if (img_convert ((AVPicture*)m_pFrame, PIX_FMT_YUV420P,
+		&m_pic_rgb, PIX_FMT_BGR24, m_pCodecCtx->width, m_pCodecCtx->height) < 0) {
+		fprintf (stderr, "xtoffmpeg.XImageToFFMPEG(): pixel format conversion not handled ... aborting\n");
+		return -3;
+	}
+	
+	m_VideoHeader.width=m_pCodecCtx->width;
+	m_VideoHeader.height=m_pCodecCtx->height;
+	memcpy((char *)pOutBuf,&m_VideoHeader, sizeof(VideoHeader));
+
+	int iii = avcodec_encode_video(m_pCodecCtx, pOutBuf+sizeof(VideoHeader), nOutsize, m_pFrame);
+
+	if(iii<=0)
+		return -4;
+	
+	return iii+sizeof(VideoHeader);
+}
+
+bool CV4LVEncoder::GetCapSize(int &width, int &height)
+{
+	if(!m_bInit)
+		return false;
+	
+	width = m_pCodecCtx->width;
+	height = m_pCodecCtx->height;
+	
+	return true;
+}
+
+
+
+void CV4LVEncoder::GetColorInfo (XImage *image, ColorInfo *ci /* return struct */)
+{
+	unsigned long red_mask, green_mask, blue_mask, alpha_mask;
+	// the shifts are unsigned longs as well
+
+	if (!ci)
+		return;
+
+	// setting shifts and bit_depths to zero
+	ci->red_shift = ci->green_shift = ci->blue_shift = ci->alpha_shift = 0;
+	ci->red_bit_depth = ci->green_bit_depth = ci->blue_bit_depth =
+		ci->alpha_bit_depth = 0;
+
+	red_mask = image->red_mask;
+	if (red_mask > 0) {
+		// shift red_mask to the right till all empty bits have been
+		// shifted out and count how many they were
+		while ((red_mask & 0x01) == 0) {
+			red_mask >>= 1;
+			ci->red_shift++;
+		}
+		// count how many bits are set in the mask = depth
+		while ((red_mask & 0x01) == 1) {
+			red_mask >>= 1;
+			ci->red_bit_depth++;
+		}
+	}
+
+	ci->red_max_val = (1 << ci->red_bit_depth) - 1;
+
+	green_mask = image->green_mask;
+	if (green_mask > 0) {
+		while ((green_mask & 0x01) == 0) {
+			green_mask >>= 1;
+			ci->green_shift++;
+		}
+		while ((green_mask & 0x01) == 1) {
+			green_mask >>= 1;
+			ci->green_bit_depth++;
+		}
+	}
+	ci->green_max_val = (1 << ci->green_bit_depth) - 1;
+
+	blue_mask = image->blue_mask;
+	if (blue_mask > 0) {
+		while ((blue_mask & 0x01) == 0) {
+			blue_mask >>= 1;
+			ci->blue_shift++;
+		}
+		while ((blue_mask & 0x01) == 1) {
+			blue_mask >>= 1;
+			ci->blue_bit_depth++;
+		}
+	}
+	ci->blue_max_val = (1 << ci->blue_bit_depth) - 1;
+
+	/* over all max values */
+	// whatever they are good for
+	ci->max_val = max (ci->red_max_val, ci->green_max_val);
+	ci->max_val = max (ci->blue_max_val, ci->max_val);
+	ci->bit_depth = max (ci->red_bit_depth, ci->green_bit_depth);
+	ci->bit_depth = max (ci->blue_bit_depth, ci->bit_depth);
+	if (image->bits_per_pixel > image->depth) {
+		/* alpha? */
+		// this seems to not reflect X's ignorance of alpha in its
+		// masks
+		ci->alpha_mask = ~
+			(image->red_mask | image->blue_mask | image->green_mask); 
+		alpha_mask = ci->alpha_mask;
+		if (alpha_mask > 0) {
+			while ((alpha_mask & 0x01) == 0) {
+				alpha_mask >>= 1;
+				ci->alpha_shift++;
+			}
+			while ((alpha_mask & 0x01) == 1) {
+				alpha_mask >>= 1;
+				ci->alpha_bit_depth++;
+			}
+		}
+		ci->alpha_max_val = (1 << ci->alpha_bit_depth) - 1;
+	}
+}
+
+
+//CV4LVideoSender class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CV4LVideoSender::CV4LVideoSender() : m_sendthread(SendBufSize)
+{
+	stop = false;
+	m_bIsRecord = false;
+	m_bInit = 0;
+	
+	m_pOutBuf = 0;
+	m_hFile = 0;
+	m_mode = ModeNone;
+	m_pV4Ldev = 0;
+
+	if(!m_initmutex.IsInitialized()){
+		m_initmutex.Init();
+	}
+	
+	m_display = 0;
+	m_win = 0;
+	m_d = 0;
+	m_image = 0;
+	
+
+}
+
+CV4LVideoSender::~CV4LVideoSender()
+{
+	//first stop thread, because  m_pOutBuf is being used by Thread();
+	Stop();
+	
+	//close file.
+	if(m_hFile){
+		fclose(m_hFile);
+		m_hFile = 0;
+	} 
+
+	//free buffer.
+	if(m_pOutBuf!=0){
+		free(m_pOutBuf);
+		m_pOutBuf = 0;
+	}
+	
+	// for image
+	if(m_image){
+		XDestroyImage(m_image);
+		m_image = 0;
+	}
+
+	if(m_display){
+		if(m_win){
+			XUnmapWindow(m_display, m_win);
+			XClearWindow(m_display, m_win);
+			m_win = 0;
+		}
+		
+		if(m_d){
+			XClearWindow(m_display, m_d);
+			m_d = 0;
+		}
+		
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+	
+	CloseVideo();	
+}
+
+
+bool CV4LVideoSender::Init(int nHostPort)
+{
+	m_initmutex.Lock();
+	m_bInit = false;
+	
+	if(!m_imagemutex.IsInitialized()){
+		if(m_imagemutex.Init() < 0){
+		    m_initmutex.Unlock();
+			return false;
+		}
+	}
+	
+	
+	if(!OpenVideo()){
+		m_initmutex.Unlock();
+		return false;
+	}
+
+	if(!m_sendthread.Init(nHostPort)){
+		
+		m_initmutex.Unlock();
+		return false;
+	}
+
+	if(m_pOutBuf==0){
+		m_pOutBuf = (uint8_t*)malloc(CV4LVEncoder::V_En_OutBufSize);
+		if(m_pOutBuf==0){
+			m_initmutex.Unlock();
+			return false;
+		}
+
+	}
+
+	//Init sencoder.
+	if(!m_vencoder.Init(VideoWidth, VideoHeight, CODEC_ID_MPEG1VIDEO)){
+		m_initmutex.Unlock();

[... 1096 lines stripped ...]