incubator-bluesky-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tp...@apache.org
Subject svn commit: r662948 [24/31] - in /incubator/bluesky/NCstu-2.0: ./ autom4te.cache/ include/ intl/ po/ src/ src/.deps/ src/ffmpeg/ src/pic/
Date Wed, 04 Jun 2008 02:48:20 GMT
Added: incubator/bluesky/NCstu-2.0/src/en_de_screen.cpp
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/en_de_screen.cpp?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/en_de_screen.cpp (added)
+++ incubator/bluesky/NCstu-2.0/src/en_de_screen.cpp Tue Jun  3 19:48:16 2008
@@ -0,0 +1,1583 @@
+
+#include "en_de_screen.h"
+
+extern int delay_time;
+
+extern void PErrorText(const char* error);
+//CSEncoder class.
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CSEncoder::CSEncoder()
+{
+	m_pFrameBuf = 0;
+	m_pFrame = 0;
+    m_pCodec  = 0;
+	m_pCodecCtx  = 0;
+	m_bInit = false;
+	m_bInitScreen = false;
+	
+
+	m_image = 0;
+	m_display = 0;
+	m_d = 0;
+	m_width = 0;
+	m_height = 0;
+	m_screen_num = 0;
+
+}
+
+CSEncoder::~CSEncoder()
+{
+	m_bInitScreen = false;
+	m_bInit = false;
+		
+	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;
+	}
+	
+	// free for image
+	if(m_image){
+		XDestroyImage(m_image);
+//		m_image->f.destroy_image(m_image);
+		m_image = 0;
+	}
+	
+	if(m_display){
+		if(m_d){
+			XClearWindow(m_display, m_d);
+			m_d = 0;
+		}
+		
+		XCloseDisplay(m_display);
+		m_display = 0;
+	}
+
+}
+
+bool CSEncoder::Init(enum CodecID nCodecID /*=CODEC_ID_MPEG4*/)
+{
+	m_bInit = false;
+	/*Init for encode*/
+	avcodec_init();
+    avcodec_register_all();
+	
+	if(!InitScreen(S_CODEC_width, S_CODEC_height))
+		return false;
+
+
+	//new a frame object.
+	if(m_pFrame){
+		free(m_pFrame);
+		m_pFrame = 0;
+	}
+	m_pFrame = avcodec_alloc_frame();
+
+	/* find the mpeg4 video encoder */
+	m_pCodec = avcodec_find_encoder(nCodecID);
+	if (!m_pCodec) {
+		PErrorText("codec not found\n");
+//		fprintf(stderr, );
+		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 = S_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= S_CODEC_frame_rate_base;
+	m_pCodecCtx->gop_size = S_CODEC_gop_size; /* emit one intra frame every ten frames */
+	
+	m_pCodecCtx->bit_rate = 512*1024;
+	m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
+	m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
+	
+	/* open it */
+	if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) {
+		fprintf(stderr, "could not open codec\n");
+		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;
+}
+
+
+
+
+
+
+
+int CSEncoder::EncodeProcess(XImage *image, uint8_t *pOutBuf, int nOutsize)
+{
+
+	if(!m_bInit)
+		return -1;
+
+	if(nOutsize<S_En_OutBufSize){
+		return -2;
+	}
+
+//colorconvert
+	int k, j;
+	unsigned long  r32,g32,b32,color32;
+
+			for (k=0;k<m_pCodecCtx->height;k++){         
+				for (j=0;j<m_pCodecCtx->width;j++){
+					color32 = *((unsigned long*)(image->data+k*m_pCodecCtx->width*4+j*4));
+					r32 = color32 & (image->red_mask);
+					g32 = color32 & (image->green_mask);
+					b32 = color32 & (image->blue_mask);
+					r32  = ((r32 >> 16) &255) << 16;
+					g32  = ((g32 >> 8 ) &255 ) <<8;
+					b32  = ((b32      ) &255 )     ;
+					color32 = r32 | g32 | b32;
+					color32=color32&16777215;
+					*((unsigned long*)(image->data+k*m_pCodecCtx->width*4+j*4))=color32;
+				}		
+			}	
+	 GetColorInfo (image, &c_info);
+	 switch (image->bits_per_pixel) {
+            case 8:
+                input_pixfmt = PIX_FMT_PAL8;
+                break;
+            case 16:
+                if ( image->red_mask == 0xF800 && image->green_mask == 0x07E0
+                && image->blue_mask == 0x1F ) {
+                    input_pixfmt = PIX_FMT_RGB565;
+                } else if ( image->red_mask == 0x7C00 && image->green_mask == 0x03E0
+                && image->blue_mask == 0x1F ) {
+                    input_pixfmt = PIX_FMT_RGB555;                    
+                } else {
+                    fprintf (stderr, "xtoffmpeg.XImageToFFMPEG(): rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
+                    fprintf (stderr, "xtoffmpeg.XImageToFFMPEG(): color masks: r 0x%.6lX g 0x%.6lX b 0x%.6lX\n", image->red_mask, image->green_mask, image->blue_mask);
+                }
+                break;
+            case 24:
+                if ( image->red_mask == 0xFF0000 && image->green_mask == 0xFF00
+                && image->blue_mask == 0xFF ) {
+                    input_pixfmt = PIX_FMT_BGR24;
+                } else if ( image->red_mask == 0xFF && image->green_mask == 0xFF00
+                && 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()");
+                    return false;
+                }
+                break;
+            case 32:
+                if ( c_info.alpha_mask == 0xFF000000 && 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;
+        }
+    
+	avpicture_fill(&m_pic_rgb, (uint8_t *)image->data, input_pixfmt, 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, input_pixfmt, m_pCodecCtx->width, m_pCodecCtx->height) < 0) {
+		PErrorText("xtoffmpeg.XImageToFFMPEG(): pixel format conversion not handled ... aborting");
+		return -2;
+	}
+	
+	m_ScreenHeader.width=m_width;
+	m_ScreenHeader.height=m_height;
+	memcpy((char *)pOutBuf,&m_ScreenHeader, sizeof(ScreenHeader));
+
+	int ret;
+	ret = avcodec_encode_video(m_pCodecCtx, pOutBuf+sizeof(ScreenHeader), nOutsize, m_pFrame);
+	
+	if(ret<=0)
+		return ret;
+	
+	return ret+sizeof(ScreenHeader);
+	
+}
+
+bool CSEncoder::InitScreen(int width, int height)
+{
+	if(m_bInitScreen)
+		return true;
+	m_display=XOpenDisplay(NULL);
+
+	m_width = width;
+	m_height = height;
+	m_screen_num = DefaultScreen(m_display);
+	
+	m_d = RootWindow(m_display,m_screen_num);
+	
+	XWindowAttributes win_attr;
+
+	if (!XGetWindowAttributes(m_display, m_d, &win_attr))//获取屏幕窗口属性
+
+	    perror("Can't get window attributes!\n");
+
+	m_image = 0;
+	m_bInitScreen = true;
+	return true;
+}
+
+bool CSEncoder::GetScreenSize(int &width, int &height)
+{
+	if(!m_bInit)
+		return false;
+	
+	width = m_pCodecCtx->width;
+	height = m_pCodecCtx->height;
+	
+	return true;
+}
+
+//Mouse capture.
+uint16_t mousePointerBlack[] = { 0, 49152, 40960, 36864, 34816, 33792, 33280, 33024, 32896, 32832,
+33728, 37376, 43264, 51456, 1152, 1152, 576, 576, 448, 0 };
+uint16_t mousePointerWhite[] = { 0, 0, 16384, 24576, 28672, 30720, 31744, 32256, 32512, 32640, 31744,
+27648, 17920, 1536, 768, 768, 384, 384, 0, 0 };
+/*
+ * the following function finds out where the mouse pointer is
+ */
+void CSEncoder::getCurrentPointer(int *x, int *y) {
+    Window mrootwindow, childwindow;
+    int dummy;
+
+	if(!m_bInit)
+		return ;
+	
+    mrootwindow = DefaultRootWindow(m_display);
+    
+    if (XQueryPointer(m_display, mrootwindow, &mrootwindow, &childwindow,
+    			x, y, &dummy, &dummy, (unsigned int *)&dummy)) {
+		// empty
+		// if the XQueryPointer was successfull, we have everything we need in the variables
+		// passed as result pointers
+    } else {
+        *x = -1;
+        *y = -1;
+    }
+	
+	XClearWindow(m_display, mrootwindow);
+}
+
+
+/* 
+ * paint the dummy mouse pointer into a given frame
+ */
+void CSEncoder::paintMousePointer(int *x, int *y, XImage *image) {
+	// only paint a mouse pointer into the dummy frame if the position of the mouse
+	// is within the rectangle defined by the capture frame
+	
+    if ( *x >= 0 && *x < S_CODEC_width-25 &&				//25 is width and height of cursor .
+    *y  >= 0 && *y < S_CODEC_height-25 ) {
+        int line;
+        uint8_t *im_data = (uint8_t *)image->data;
+        
+	// move the cursor to the right starting position
+        im_data += (image->bytes_per_line * (*y)); // shift to right line
+        im_data += (image->bits_per_pixel / 8 * (*x)); // shift to right pixel
+        
+        uint32_t *cursor;
+        int width;
+        uint16_t bm_b, bm_w, mask;
+                
+		// the dummy mouse pointer is 20 pixels high ...
+        for (line = 0; line < 20; line++ ) {
+                    bm_b = mousePointerBlack[line];
+                    bm_w = mousePointerWhite[line];
+               
+                 mask = ( 0x0001 << 15 );
+                    
+		    // ... and 16 pixels wide
+         for (cursor = (uint32_t*) im_data, width = 0;
+                    ((width + *x) < S_CODEC_width&&width < 16);
+                    cursor++, width++) {
+                        if ( ( bm_b & mask ) > 0 ) {
+                            *cursor &= ((~ image->red_mask) & (~ image->green_mask) & (~
+                            image->blue_mask ));
+                        } else if ( ( bm_w & mask ) > 0 ) {
+                            *cursor |= (image->red_mask | image->green_mask | image->blue_mask );
+                        }
+                        mask >>= 1;
+                    }
+                    im_data += image->bytes_per_line;
+                }
+
+    }
+}
+
+//Mouse capture.
+
+bool CSEncoder::Capture(XImage **image)
+{
+	int x, y;
+	if(!m_bInitScreen)
+		return false;
+	
+	if(m_image){
+		m_image->f.destroy_image(m_image);
+		m_image = 0;
+	}
+	getCurrentPointer(&x, &y);
+	m_image = XGetImage(m_display, 	//获取圓前屏幕所星瀺囟像
+					     m_d,
+    		      	      0, 0,
+   			     	     m_width, m_height,
+			    	     AllPlanes, ZPixmap);
+	
+	if(m_image==0){
+		PErrorText("GetImage error");
+		return false;
+	}
+	paintMousePointer(&x, &y, m_image);
+	
+	*image = m_image;
+	return true;
+}
+
+void CSEncoder::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;
+	}
+}
+//CSDecoder class.
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CSDecoder::CSDecoder()
+{
+    m_pCodec  = 0;
+	m_pCodecCtx = 0;
+	m_pOutFrame = 0;
+//	m_pSDLBuf = 0;
+//	m_pFrameBuf = 0;
+	m_bInit = false;
+//	AVPicture pic_rgb, pic_yuv;
+	m_display = 0;
+//	GC m_gc;
+	m_win = 0;
+	m_d = 0;
+	m_image = 0;
+	m_parent = 0;
+
+	m_width = 0;
+	m_height = 0;
+	
+}
+
+CSDecoder::~CSDecoder()
+{
+	m_bInit = false;
+
+	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;
+	}
+
+
+	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 CSDecoder::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/screen.bmp", NULL)==NULL)
+	{
+      XSetWindowBackgroundPixmap(m_display,m_win,ParentRelative);
+	  XMapWindow(m_display, m_win);	
+	}
+	else
+    {
+	  original_pixbuf = gdk_pixbuf_new_from_file ("pic/screen.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, 	//获取圓前屏幕所星瀺囟像
+					     			  m_d,
+    	  			    			  0, 0,
+   	  			     				  m_width, m_height,
+				    				  AllPlanes, ZPixmap);
+	if(!m_image){
+		printf("error\n");
+		m_imagemutex.Unlock();
+		return false;
+	}
+
+	m_imagemutex.Unlock();
+	m_parent = parent;
+	return true;		
+}
+
+void CSDecoder::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();	
+	
+}
+
+void CSDecoder::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 CSDecoder::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
+	/* resolution must be a multiple of two */
+	m_pCodecCtx->width = m_width;  
+	m_pCodecCtx->height = m_height;
+	/* frames per second */
+	m_pCodecCtx->frame_rate = CSEncoder::S_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= CSEncoder::S_CODEC_frame_rate_base;
+	m_pCodecCtx->gop_size = CSEncoder::S_CODEC_gop_size; /* emit one intra frame every ten frames */
+
+	m_pCodecCtx->bit_rate = 512*1024;
+	m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
+	m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
+	
+	m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+	m_pCodecCtx->extradata = malloc(S_De_ExtraHeaderSize);
+	if(m_pCodecCtx->extradata == 0){
+		return false;
+	}
+	m_pCodecCtx->extradata_size = S_De_ExtraHeaderSize/8;
+	
+	// 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_bIsFirstKeyFrame = false;
+	
+	
+	if(m_image){
+		XDestroyImage(m_image);
+		m_image = 0;
+	}
+	
+	m_image = XGetImage(m_display, 	//获取圓前屏幕所星瀺囟像
+		     			  m_parent,
+    	    			  0, 0,
+   		   				  m_width, m_height,
+		   				  AllPlanes, ZPixmap);
+	if(!m_image){
+		PErrorText("GetImage error");
+		m_imagemutex.Unlock();
+		return false;
+	}
+	
+	m_bInit = true;	
+	return true;
+	
+}
+
+bool CSDecoder::Init(int width, int height, enum CodecID nCodecID)
+{
+
+	if(m_bInit)
+		return true;
+	
+
+	avcodec_init();
+    avcodec_register_all();
+	
+/*	if(width!=CSEncoder::S_CODEC_width && height!=CSEncoder::S_CODEC_height){
+		printf("\nScreen Init Error: screen size is not %d, %d\n", CSEncoder::S_CODEC_width, CSEncoder::S_CODEC_height);
+		return false;
+	}
+*/	
+	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");
+		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
+	/* resolution must be a multiple of two */
+	m_pCodecCtx->width = m_width;  
+	m_pCodecCtx->height = m_height;
+	/* frames per second */
+	m_pCodecCtx->frame_rate = CSEncoder::S_CODEC_framerate;  
+	m_pCodecCtx->frame_rate_base= CSEncoder::S_CODEC_frame_rate_base;
+	m_pCodecCtx->gop_size = CSEncoder::S_CODEC_gop_size; /* emit one intra frame every ten frames */
+
+	m_pCodecCtx->bit_rate = 512*1024;
+	m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
+	m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO;
+	
+	m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+	m_pCodecCtx->extradata = malloc(S_De_ExtraHeaderSize);
+	if(m_pCodecCtx->extradata == 0){
+		return false;
+	}
+	m_pCodecCtx->extradata_size = S_De_ExtraHeaderSize/8;
+	
+	// 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_bIsFirstKeyFrame = false;
+	m_bInit = true;
+	return true;
+}
+
+
+
+
+int CSDecoder::DecodeProcess(uint8_t *encodeddata_v, const int encodeddatasize_v)
+{
+	bool isPaintPic;
+	int realsize, i;
+	int got_picture ;
+	if(!m_bInit){
+		return -1;
+	}
+	
+//	int ngot = 0;
+	int left = 0;
+	int len;
+	m_imagemutex.Lock();
+	for(i = 0 ; ; i++){
+		if(encodeddatasize_v - i * S_De_INBUF_SIZE >= S_De_INBUF_SIZE)
+			realsize = S_De_INBUF_SIZE;
+		else
+			realsize = encodeddatasize_v - i * S_De_INBUF_SIZE;
+		
+		if(realsize <= 0)
+			break;
+		
+		left = 0;
+		isPaintPic = false;
+		while(realsize > 0){
+			//ÒòΪdecodeÓпÉÄÜ»ážüžÄŽóС£¬ËùÒÔÒªÖØÐÂÉèÖÃ.
+			m_pCodecCtx->width = m_width;
+			m_pCodecCtx->height = m_height;
+			len = avcodec_decode_video(m_pCodecCtx, m_pOutFrame, &got_picture, 
+				(encodeddata_v + i * S_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");
+                        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\n");
+					    return false;
+                    }
+                    break;
+                default:
+                    PErrorText("xtoffmpeg.XImageToFFMPEG(): image depth not supported ... aborting\n");
+                    return false;
+                }
+			}
+    
+			
+			if(got_picture){
+//			ngot++;				
+//			printf("\nngot = %d\n", ngot);
+				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;
+}
+
+
+//CScreenSender class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CScreenSender::CScreenSender() : m_sendthread(SendBufSize)
+{
+	stop = false;
+	m_bIsRecord = false;
+	m_bInit = 0;
+	
+	m_hFile = 0;
+	
+#if (defined(WIN32) || defined(_WIN32_WCE))
+	timeinit.Dummy();
+#endif // WIN32 || _WIN32_WCE
+}
+
+CScreenSender::~CScreenSender()
+{
+	//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);
+}
+
+
+bool CScreenSender::Init(int nPort)
+{
+	if(m_bInit)
+		return true;
+
+	//init sendthread.
+	if(!m_sendthread.Init(nPort))
+		return false;
+
+	if(m_pOutBuf==0){
+		m_pOutBuf = (uint8_t*)malloc(CSEncoder::S_En_OutBufSize);
+		if(m_pOutBuf==0){
+			return false;
+		}
+
+	}
+
+	//Init sencoder.
+	if(!m_sencoder.Init(CODEC_ID_MPEG1VIDEO)){
+		return false;
+	}
+
+	m_bInit = true;
+	return m_bInit;
+}
+
+
+
+int CScreenSender::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 (!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;
+		}
+
+	}
+
+	if(m_sendthread.Start() < 0){
+		return -6;
+	}
+
+	if (JThread::Start() < 0){
+		return -6;
+	}
+
+	return 0;
+}
+
+void CScreenSender::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;
+	
+	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_bIsRecord = false;
+
+	m_sendthread.Stop();
+	
+}
+
+void CScreenSender::Record(bool bInRecord /* =true */)
+{
+	if(!m_bInit)
+		return ;
+	
+	m_recordmutex.Lock();
+	m_bIsRecord = bInRecord;
+	m_recordmutex.Unlock();
+	
+}
+
+void *CScreenSender::Thread()
+{
+	XImage * pImage;
+	int OutBufSzie;
+
+	JThread::ThreadStarted();
+	
+	bool stopthread;
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+	
+	bool isrecord;
+	m_recordmutex.Lock();
+	isrecord = m_bIsRecord;
+	m_recordmutex.Unlock();
+	
+	int status;
+	
+	int64_t pre_time, cur_time;
+	useconds_t delay, delay1;	
+
+	
+	if(m_sencoder.m_pCodecCtx->frame_rate!=0){
+		if(m_sencoder.m_pCodecCtx->frame_rate_base!=0)
+			delay1 = 1000000*m_sencoder.m_pCodecCtx->frame_rate_base/m_sencoder.m_pCodecCtx->frame_rate;
+		else
+			delay1 = 1000000/m_sencoder.m_pCodecCtx->frame_rate;
+	}
+	else{
+		delay1 = 1000000;
+	}
+	
+	// sleep for sync
+	if(delay_time > 0){
+		sleep(delay_time);
+	}
+	
+	// for Utiltiy rate of CPU
+	cur_time = av_gettime();
+	pre_time = cur_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();
+		
+
+		if ((status = m_sencoder.Capture(&pImage)) < 0)
+		{
+			stopthread = true;
+			continue;
+		}
+		else{
+			OutBufSzie = CSEncoder::S_En_OutBufSize;
+			if ((status = m_sencoder.EncodeProcess(pImage, m_pOutBuf, OutBufSzie)) < 0)
+			{
+				stopthread = true;
+				continue;
+			}
+			else{
+				if(status>0){
+					//static int iiii=0;					
+					m_sendthread.SendData(m_pOutBuf, status);
+					//iiii ++;
+					//printf("\nscreen send(%d): %d bytes\n", iiii, status);
+					
+					if(m_hFile!=0 && isrecord){
+						fwrite(m_pOutBuf+sizeof(ScreenHeader), status-sizeof(ScreenHeader), 1, m_hFile);
+						nFrame++;
+
+						//add up rec_time;
+						rec_time = av_gettime()-rec_start;
+						int i;
+						for(i=0;rec_time>nFrame*delay1;nFrame++, i++){
+					    	printf("\nScreen Frame=%d\n", nFrame);
+							if((status = m_sencoder.EncodeProcess(pImage, m_pOutBuf, OutBufSzie))<0){
+								printf("\nscreen: encode vital error.");
+								stopthread = true;
+								printf("\nscreen capture thread stoped by EncodeProcess error!\n");
+								return 0;
+							}
+							if(status>0)
+								fwrite(m_pOutBuf+sizeof(ScreenHeader), status-sizeof(ScreenHeader), 1, m_hFile);
+						}
+						
+
+					}
+					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();
+		// printf("\ncur-pre=%d\n", cur-pre);
+	}
+	
+	printf("\nscreen capture thread stoped!\n");
+	return 0;
+}
+
+bool CScreenSender::AddDestination(const RTPIPv4Address &des)
+{
+	if(!m_bInit)
+		return false;
+	if(m_sendthread.AddDestination(des)<0)
+		return false;
+
+	return true;
+}
+void CScreenSender::ClearDestinations()
+{
+	if(!m_bInit)
+		return ;
+	m_sendthread.ClearDestinations();
+}
+
+
+//CScreenReceiver class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CScreenReceiver::CScreenReceiver()
+{
+	m_bInit = false;
+	m_ScreenInit=false;
+//	m_playback = 0;
+}
+
+CScreenReceiver::~CScreenReceiver()
+{
+
+}
+bool CScreenReceiver::Init()
+{
+	if(m_bInit)
+		return m_bInit;
+
+	//init video decoder.
+	if(!m_sdecoder.Init(800, 600, CODEC_ID_MPEG1VIDEO)){
+		return false;
+	}
+
+
+//	m_playback = fun;
+	m_bInit = true;
+	return m_bInit;
+
+}
+bool CScreenReceiver::CreateXImage(Drawable parent, int x, int y, int width, int height)
+{
+	bool ret;
+	//init screen decoder.
+
+	ret = m_sdecoder.CreateXImage(parent, x, y, width, height);
+	
+	return ret;	
+}
+
+void CScreenReceiver::CloseXImage()
+{
+	m_sdecoder.CloseXImage();
+}
+
+#define MAX_PACKET_SIZE 10240
+
+int CScreenReceiver::Start(int nPort)
+{
+//guoyachong
+//	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(nPort);
+	//CREATE THE SESSION
+	int status1 = Create(sessParams1, &transParams1);
+	if (status1){
+//		ReportError(status1);
+		return -2; //unable to create the session
+	}	
+
+	return 0;
+}
+
+void CScreenReceiver::Stop()
+{
+	Destroy();
+}
+
+void CScreenReceiver::ProcessFrame(unsigned char* framedata, int framelen)
+{
+	//printf("\nScreen decodeproocessing(%d): %d bytes\n", m_usLatestVideoSeq, framelen);	
+
+
+	pScreen= (ScreenHeader*)framedata;	
+
+	if(	pScreen->width!=m_sdecoder.m_width || pScreen->height != m_sdecoder.m_height){
+			m_sdecoder.ResetCodec(	pScreen->width, pScreen->height);
+	}
+	m_sdecoder.DecodeProcess(framedata+sizeof(ScreenHeader), framelen-sizeof(ScreenHeader));
+
+}
+
+/*
+//CWScreenRecorder class.
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CWScreenRecorder::CWScreenRecorder()
+{
+	stop = false;
+	m_bPause = false;
+	
+	m_hFile = 0;
+		
+#if (defined(WIN32) || defined(_WIN32_WCE))
+	timeinit.Dummy();
+#endif // WIN32 || _WIN32_WCE
+}
+
+CWScreenRecorder::~CWScreenRecorder()
+{
+	//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);
+}
+
+int CWScreenRecorder::Record(char* szFile)
+{
+	if (JThread::IsRunning())
+		return -1;
+
+	if (!stopmutex.IsInitialized())
+	{
+		if (stopmutex.Init() < 0)
+			return -2;
+	}
+	stop = false;
+
+	if(m_hFile){
+		fclose(m_hFile);
+		m_hFile = 0;
+	} 
+	m_hFile = fopen(szFile, "wb");
+	if(m_hFile==0){
+		return -3;
+	}
+
+
+	if(m_pOutBuf==0){
+		m_pOutBuf = (uint8_t*)malloc(CSEncoder::S_En_OutBufSize);
+		if(m_pOutBuf==0){
+			return -4;
+		}
+
+	}
+	//Init vencoder.
+	if(!m_sencoder.Init(CODEC_ID_MPEG1VIDEO)){
+		return -5;
+	}
+
+	if (JThread::Start() < 0)
+		return -6;
+
+	return 0;
+}
+
+void CWScreenRecorder::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;
+
+	//close file.
+	if(m_hFile){
+		fclose(m_hFile);
+		m_hFile = 0;
+	} 
+
+}
+
+void *CWScreenRecorder::Thread()
+{
+	XImage * pImage;
+	int OutBufSzie;
+
+	JThread::ThreadStarted();
+	
+	bool stopthread;
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+
+	int status;
+	
+	int64_t pre_time, cur_time;
+	useconds_t delay, delay1;	
+
+	if(m_sencoder.m_pCodecCtx->frame_rate!=0){
+		if(m_sencoder.m_pCodecCtx->frame_rate_base!=0)
+			delay1 = 1000000*m_sencoder.m_pCodecCtx->frame_rate_base/m_sencoder.m_pCodecCtx->frame_rate;
+		else
+			delay1 = 1000000/m_sencoder.m_pCodecCtx->frame_rate;
+	}
+	else{
+		delay1 = 1000000;
+	}
+
+	
+	pre_time = av_gettime();
+	while (!stopthread)
+	{
+		cur_time = av_gettime();
+		delay = cur_time-pre_time;
+		if(delay < delay1){
+			usleep(delay1-delay);
+			pre_time = av_gettime();
+		}
+		if ((status = m_sencoder.Capture(&pImage)) < 0)
+		{
+			stopthread = true;
+		}
+		else{
+			OutBufSzie = CSEncoder::S_En_OutBufSize;
+			if ((status = m_sencoder.EncodeProcess(pImage, m_pOutBuf, OutBufSzie)) < 0)
+			{
+				stopthread = true;
+			}
+			else{
+				if(status>0){
+					if(m_hFile!=0 && !m_bPause)
+						fwrite(m_pOutBuf, status, 1, m_hFile);
+				}
+				stopmutex.Lock();
+				stopthread = stop;
+				stopmutex.Unlock();
+			}
+		}
+
+	}
+	printf("\nscreen record close");
+	return 0;
+}
+*/

Propchange: incubator/bluesky/NCstu-2.0/src/en_de_screen.cpp
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/en_de_screen.h
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/en_de_screen.h?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/en_de_screen.h (added)
+++ incubator/bluesky/NCstu-2.0/src/en_de_screen.h Tue Jun  3 19:48:16 2008
@@ -0,0 +1,245 @@
+//en_de_srceen.h
+
+
+// rtp
+#include "fecrtpsession.h"
+
+// Linux sys.
+#include <iostream>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <linux/types.h>
+#include <linux/videodev.h>
+// FFmpeg
+#include <ffmpeg/avcodec.h>
+#include <ffmpeg/avformat.h>
+//Time
+#include <time.h>
+// X11
+#include <X11/Intrinsic.h>
+#include <X11/XWDFile.h>
+// Jthread and JMutex
+#include <jthread.h>
+#include <jmutex.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "en_de_sendthread.h"
+
+#define max(x,y) (x > y ? x : y)
+
+#if !defined(_EN_DE_SCREEN_H__INCLUDED_)
+#define _EN_DE_SCREEN_H__INCLUDED_
+
+
+typedef void (*ScreenPlayback)(uint8_t* screendata, int width, int height);
+typedef struct ScreenHeader{
+		int width;
+		int height;
+	}ScreenHeader;
+	
+typedef struct {
+	unsigned long red_shift;
+	unsigned long green_shift;
+	unsigned long blue_shift;
+	unsigned long alpha_shift;
+	unsigned long max_val;
+	unsigned long bit_depth;
+	unsigned long red_max_val;
+	unsigned long green_max_val;
+	unsigned long blue_max_val;
+	unsigned long alpha_max_val;
+	unsigned long red_bit_depth;
+	unsigned long green_bit_depth;
+	unsigned long blue_bit_depth;
+	unsigned long alpha_bit_depth;
+	u_int32_t alpha_mask;
+} ColorInfo;
+
+//Screen encoder.
+class CSEncoder  
+{
+	friend class CSDecoder;
+	friend class CScreenSender;
+	friend class CWScreenRecorder;
+private:
+	enum SENCODERBUFSIZE {S_En_OutBufSize = 400*1024};
+	enum SCREEN_CODEC_PARA {S_CODEC_width=800, S_CODEC_height=600,			\
+							S_CODEC_framerate=1, S_CODEC_frame_rate_base=1,	\
+							S_CODEC_gop_size=4,										\
+							S_CODEC_max_b_frames};							
+public:
+	bool GetScreenSize(int &width, int &height);
+	bool Capture(XImage **image);
+	int EncodeProcess(XImage *image, uint8_t *pOutBuf, int nOutsize);
+	bool Init(enum CodecID nCodecID =CODEC_ID_MPEG4);
+	CSEncoder();
+	virtual ~CSEncoder();
+	void GetColorInfo (XImage *image, ColorInfo *ci /* return struct */);
+
+private:
+	void paintMousePointer(int *x, int *y, XImage *image);
+	void getCurrentPointer(int *x, int *y);	
+	bool InitScreen(int width, int height);
+
+
+// for screen .
+private:
+	XImage *m_image;
+	Display *m_display;
+	int m_screen_num;
+	Drawable m_d;
+	unsigned int m_width, m_height;//屏幕尺寸
+	bool m_bInitScreen;
+	ColorInfo c_info;
+	int input_pixfmt;	
+	ScreenHeader m_ScreenHeader;
+// for encode.
+private:
+	bool m_bInit;
+	AVPicture m_pic_rgb;
+//	AVPicture m_pic_yuv;
+	uint8_t *m_pFrameBuf;
+	AVFrame *m_pFrame;
+    AVCodec *m_pCodec ;
+	AVCodecContext *m_pCodecCtx ;
+};
+
+//Screen decoder.
+class CSDecoder  
+{
+	friend class CScreenReceiver;
+private:
+	enum VDECODERBUFSIZE {S_De_ExtraHeaderSize = 10000, S_De_INBUF_SIZE = 1024};
+public:
+	CSDecoder();
+	virtual ~CSDecoder();
+public:
+//	enum AVFRAMEDATASIZE_V{ size_v = 100*1024};
+	int DecodeProcess(uint8_t *encodeddata_v, const int encodeddatasize_v);
+	bool Init(int width, int height, enum CodecID nCodecID);
+
+public:
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+
+private:
+	void CloseCodec();
+	bool	ResetCodec(const int width, const int height);
+	//for ximage.
+	Drawable m_parent;
+	Display *m_display;
+	GC m_gc;
+	Window m_d;
+
+	Window m_win;
+	XImage *m_image;
+	JMutex m_imagemutex;
+	CSEncoder m_encoder;
+	ColorInfo c_info;
+	int input_pixfmt;	
+
+
+private:
+//	bool m_bIsFirstKeyFrame;
+	bool m_bInit;
+    AVCodec *m_pCodec ;
+	AVCodecContext *m_pCodecCtx ;
+	AVFrame *m_pOutFrame;
+	AVPicture pic_rgb;
+	int m_width;
+	int m_height;
+//	AVPicture pic_yuv;
+//	uint8_t *m_pSDLBuf;
+//	uint8_t *m_pFrameBuf;
+
+};
+
+
+
+//screen sender.
+class CScreenSender : private JThread
+{
+private:
+	enum SCREENSENDBUFSIZE {SendBufSize=2};
+public:
+	CScreenSender();
+	~CScreenSender();
+	bool Init(int nPort);
+	bool AddDestination(const RTPIPv4Address &des);
+	void ClearDestinations();
+	int Start(char* szFile=0, bool bIsRecord=false);
+	void Stop();
+	void Record(bool bInRecord=true);
+private:
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	bool m_bIsRecord;				
+	JMutex m_recordmutex;
+
+	CSEncoder m_sencoder;
+	uint8_t *m_pOutBuf;
+	FILE* m_hFile;
+	CSendThread m_sendthread;
+	int m_bInit;
+};
+
+
+
+
+//screen receiver
+
+class CScreenReceiver : public CFECRtpSession  
+{
+public:
+	CScreenReceiver();
+	virtual ~CScreenReceiver();
+
+	bool Init();
+	int Start(int nPort);
+	void Stop();
+
+public:
+	bool CreateXImage(Drawable parent, int x, int y, int width, int height);
+	void CloseXImage();
+
+private:
+	virtual void ProcessFrame(unsigned char* framedata, int framelen);
+
+private:
+	bool m_ScreenInit;
+	bool m_bInit;
+	CSDecoder m_sdecoder;
+public:
+//guoyachong
+	ScreenHeader* pScreen;
+//	ScreenPlayback m_playback;
+};
+
+/*
+//screen recoder.
+class CWScreenRecorder : private JThread
+{
+public:
+	CWScreenRecorder();
+	~CWScreenRecorder();
+	int Record(char* szFile);
+	void Stop();
+private:
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	bool m_bPause;				//for pauseing record.
+	JMutex m_pausemutex;		//for pauseing record.
+	CSEncoder m_sencoder;
+	uint8_t *m_pOutBuf;
+	FILE* m_hFile;
+};
+*/
+#endif // !defined(_EN_DE_SCREEN_H__INCLUDED_)

Propchange: incubator/bluesky/NCstu-2.0/src/en_de_screen.h
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/bluesky/NCstu-2.0/src/en_de_sendthread.cpp
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/en_de_sendthread.cpp?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/en_de_sendthread.cpp (added)
+++ incubator/bluesky/NCstu-2.0/src/en_de_sendthread.cpp Tue Jun  3 19:48:16 2008
@@ -0,0 +1,535 @@
+#include "en_de_sendthread.h"
+
+
+extern void PErrorText(const char* error);
+//CSendThread class.
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CSendThread::CSendThread(int nSendBufSize)
+{
+	stop = false;
+	m_bInit = 0;
+	
+	if(nSendBufSize <=2){
+		m_nSendBufSize = 2;
+	}
+	else
+		if(nSendBufSize>=25){
+			m_nSendBufSize = 25;
+		}
+		else
+			m_nSendBufSize = nSendBufSize;
+	
+#if (defined(WIN32) || defined(_WIN32_WCE))
+	timeinit.Dummy();
+#endif // WIN32 || _WIN32_WCE
+}
+
+CSendThread::~CSendThread()
+{
+	//first stop thread, because  m_pOutBuf is being used by Thread();
+	Stop();
+	
+}
+
+#define MAX_PACKET_SIZE 10*1024
+bool CSendThread::Init(int nPort)
+{
+	if(m_bInit)
+		return true;
+
+	//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(nPort);
+	//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);
+
+
+	m_bInit = true;
+	return m_bInit;
+}
+
+
+
+int CSendThread::Start()
+{
+	if(!m_bInit)
+		return -1;
+
+	if (JThread::IsRunning())
+		return 0;
+
+	if (!stopmutex.IsInitialized())
+	{
+		if (stopmutex.Init() < 0)
+			return -2;
+	}
+
+	stop = false;
+
+	if (!m_senddatamutex.IsInitialized())
+	{
+		if (m_senddatamutex.Init() < 0)
+			return -2;
+	}
+
+	if (JThread::Start() < 0){
+		return -6;
+	}
+
+	return 0;
+}
+
+void CSendThread::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;
+
+	
+}
+
+int CSendThread::SendData(uint8_t *data, int datalen)
+{
+	SENDBUFDATA *pData;
+//	uint8_t* pbufdata;
+	if(!m_bInit)
+		return -1;
+
+	pData = new SENDBUFDATA;
+	if(pData==0){
+		PErrorText("Error: CSendThread::SendData new SENDBUFDATA");	
+		return -2;
+	}
+
+	pData->data = new uint8_t[datalen];
+	if(pData->data==0){
+		delete pData;
+		PErrorText("Error: CSendThread::SendData new uint8_t");	
+		return -3;
+	}
+
+	memcpy(pData->data, data, datalen);
+	pData->datalen = datalen;
+
+
+	m_senddatamutex.Lock();
+	m_senddata.insert(m_senddata.end(), pData);
+	m_senddatamutex.Unlock();
+	
+	return 0;
+}
+
+
+void *CSendThread::Thread()
+{
+	JThread::ThreadStarted();
+	
+//	m_nSendBufSize
+	SENDBUFDATA *senddata = new SENDBUFDATA[m_nSendBufSize];
+	bool stopthread;
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+	
+	int size;
+	SENDBUFDATA* p;
+	SendDatalist::iterator itera;
+	int index;
+	while (!stopthread)
+	{
+		
+		m_senddatamutex.Lock();
+		size = m_senddata.size();
+		if(size==0){
+			m_senddatamutex.Unlock();
+
+			usleep(50000);
+
+			stopmutex.Lock();
+			stopthread = stop;
+			stopmutex.Unlock();
+			continue;
+		}
+		if(size>m_nSendBufSize){
+			for(itera=m_senddata.begin(); itera!=m_senddata.end(); itera++){
+				p = *itera;
+				delete p->data;
+				delete p;
+				p = 0;
+			}
+			m_senddata.clear();
+			size = 0;
+		}
+		else{
+			for(itera=m_senddata.begin(),index=0; itera!=m_senddata.end(); itera++,index++){
+				p = *itera;
+				senddata[index].data = p->data;
+				senddata[index].datalen = p->datalen;
+				delete p;
+				p = 0;
+			}
+			m_senddata.clear();
+			size = index;
+		}
+			
+		m_senddatamutex.Unlock();
+
+		for(index=0; index<size; index++){
+			m_fecrtpsession.SendFECPacket(senddata[index].data, senddata[index].datalen, 5000);
+			delete senddata[index].data;
+		}
+
+
+		stopmutex.Lock();
+		stopthread = stop;
+		stopmutex.Unlock();
+
+	}
+	printf("\nSendthread stoped.\n");
+	return 0;
+}
+
+bool CSendThread::AddDestination(const RTPIPv4Address &des)
+{
+	if(!m_bInit)
+		return false;
+	if(m_fecrtpsession.AddDestination(des)<0)
+		return false;
+
+	return true;
+}
+
+void CSendThread::ClearDestinations()
+{
+	if(!m_bInit)
+		return ;
+	m_fecrtpsession.ClearDestinations();
+}
+
+
+///********************************************************AUDIO CLASS
+int CAudioWriteThread::g_arts_count=0;
+CAudioWriteThread::CAudioWriteThread(int nSendBufSize)
+{
+	stop = false;
+	m_bInit = false;
+	m_bOpenArts = false;
+	static int siSeq = 0;	
+	
+	if(nSendBufSize <=2){
+		m_nSendBufSize = 2;
+	}
+	else
+		if(nSendBufSize>MAX_ARTS_WRITE_FRAMES){
+			m_nSendBufSize = MAX_ARTS_WRITE_FRAMES;
+		}
+		else
+			m_nSendBufSize = nSendBufSize;
+		
+	m_stream = 0;
+	
+	if(g_arts_count<=0){
+		if(g_arts_count<0)
+		    g_arts_count = 0;
+		if(arts_init()==0){
+			g_arts_count++;
+		}
+	}
+	siSeq++;
+	sprintf(m_pName,"RC_%d",siSeq);
+	
+	printf("arts name is %s",m_pName);
+	
+#if (defined(WIN32) || defined(_WIN32_WCE))
+	timeinit.Dummy();
+#endif // WIN32 || _WIN32_WCE
+}
+
+
+CAudioWriteThread::~CAudioWriteThread()
+{
+	//first stop thread, because  m_pOutBuf is being used by Thread();
+	g_arts_count--;
+	if(g_arts_count<=0){
+		arts_free();
+	}
+	
+	Stop();
+	
+}
+
+void CAudioWriteThread::CloseAudio()
+{
+	if(m_stream>0){
+		arts_close_stream(m_stream);
+	}
+
+	m_stream = 0;	
+	
+}
+
+#define ARTS_PACKETS 10 /* Number of audio packets */
+#define ARTS_PACKET_SIZE_LOG2 11 /* Log2 of audio packet size */
+bool CAudioWriteThread::OpenAudio()
+{
+/*	int errorcode;
+	
+	errorcode = arts_init();
+	if(errorcode != 0){
+		PErrorText("\nOpenAudio: arts_init Error.\n");	
+		return false;
+	}
+*/	
+	if(!m_bOpenArts){
+	
+		m_stream = arts_play_stream(AUDIO_SAMPLE_RATE, 16, STATIC_AUDIO_CHANNEL, m_pName);
+		//arts_stream_set(m_stream,ARTS_P_BLOCKING,0);
+		
+	
+		
+		if(m_stream <= 0  ){
+			PErrorText("\nOpenAudio: arts_play_stream Error.\n");	
+			return false;
+		}
+		arts_stream_set(m_stream, ARTS_P_BLOCKING, 0);
+		arts_stream_set(m_stream, ARTS_P_BUFFER_TIME, 500);
+		int frag_spec = ARTS_PACKET_SIZE_LOG2 | ARTS_PACKETS << 16;
+		arts_stream_set(m_stream, ARTS_P_PACKET_SETTINGS, frag_spec);	
+	
+		printf("\narts_play_stream ok\n");
+		m_bOpenArts=true;
+	}
+	
+	return true;
+	
+}
+
+bool CAudioWriteThread::Init()
+{
+	if(m_bInit)
+		return true;
+
+	m_bInit = true;
+	return m_bInit;
+}
+
+
+
+int CAudioWriteThread::Start()
+{
+	if(!m_bInit)
+		return -1;
+
+	if (JThread::IsRunning())
+		return 0;
+
+	if (!stopmutex.IsInitialized())
+	{
+		if (stopmutex.Init() < 0)
+			return -2;
+	}
+
+	//stop = false;
+
+	if (!m_senddatamutex.IsInitialized())
+	{
+		if (m_senddatamutex.Init() < 0)
+			return -2;
+	}
+
+	if (JThread::Start() < 0){
+		return -6;
+	}
+	stop = false;
+	return 0;
+}
+
+void CAudioWriteThread::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;
+
+	
+}
+
+int CAudioWriteThread::SetData(uint8_t *data, int datalen)
+{
+	AUDIOBUFDATA *pData;
+//	uint8_t* pbufdata;
+	if(!m_bInit)
+		return -1;
+
+	pData = new AUDIOBUFDATA;
+	if(pData==0){
+		PErrorText("Error: CSendThread::SendData new SENDBUFDATA");	
+		return -2;
+	}
+
+	pData->data = new uint8_t[datalen];
+	//printf("SET data length is %d\n",datalen);
+	if(pData->data==0){
+		delete pData;
+		PErrorText("Error: CSendThread::SendData new uint8_t");	
+		return -3;
+	}
+
+	memcpy(pData->data, data, datalen);
+	pData->datalen = datalen;
+
+
+	m_senddatamutex.Lock();
+	m_senddata.insert(m_senddata.end(), pData);
+	m_senddatamutex.Unlock();
+	
+	return 0;
+}
+
+
+void *CAudioWriteThread::Thread()
+{
+	JThread::ThreadStarted();
+	
+//	m_nSendBufSize
+	AUDIOBUFDATA *senddata = new AUDIOBUFDATA[m_nSendBufSize];
+	bool stopthread;
+
+	stopmutex.Lock();
+	stopthread = stop;
+	stopmutex.Unlock();
+	
+	int size=0;
+	AUDIOBUFDATA* p;
+	SendAudioDatalist::iterator itera;
+	int index;
+	
+	//*
+	static JMutex arts_writemutex;
+	
+	if(!arts_writemutex.IsInitialized()){
+		if(!arts_writemutex.Init()){
+			PErrorText("\nDecodeProcess: arts_writemutex Init error\n");
+		}
+	}
+	//*/
+	
+	while (!stopthread)
+	{
+
+		m_senddatamutex.Lock();
+		size = m_senddata.size();
+		if(size<MIN_ARTS_WRITE_FRAMES){
+			m_senddatamutex.Unlock();
+
+			usleep(20000);
+			//printf("sleep!!!!!!!!!!!!!!!!!%d  %d\n",size,m_nSendBufSize);
+			stopmutex.Lock();
+			stopthread = stop;
+			stopmutex.Unlock();
+			continue;
+		}
+		if(size>m_nSendBufSize){
+			for(itera=m_senddata.begin(); itera!=m_senddata.end(); itera++){
+				p = *itera;
+				delete p->data;
+				delete p;
+				p = 0;
+			}
+			m_senddata.clear();
+			printf("delete audio stream!!!\n");
+			size = 0;
+		}
+		else{
+			
+			for(itera=m_senddata.begin(),index=0; itera!=m_senddata.end(); itera++,index++){
+				p = *itera;
+				senddata[index].data = p->data;
+				senddata[index].datalen = p->datalen;
+				delete p;
+				p = 0;
+
+			}
+			m_senddata.clear();
+			size = index;
+
+		}
+			
+		m_senddatamutex.Unlock();
+
+		for(index=0; index<size; index++){
+			arts_writemutex.Lock();
+			
+			if(m_stream >0 ){			
+			//static int64_t pre, cur,inteval;
+			//pre = av_gettime();
+			arts_write(m_stream, senddata[index].data, senddata[index].datalen);
+
+			//cur = av_gettime();
+			//inteval = (cur-pre);
+			
+			//std::cout<<m_pName<<" artsd cost time is "<<inteval<<std::endl;
+			}
+			
+			
+			delete senddata[index].data;
+			arts_writemutex.Unlock();
+		}
+
+
+		stopmutex.Lock();
+		stopthread = stop;
+		stopmutex.Unlock();
+
+	}
+	printf("\nSendthread stoped.\n");
+	printf("\nSendthread stoped.\n");
+	printf("\nSendthread stoped.\n");
+	printf("\nSendthread stoped.\n");
+	
+	return 0;
+}

Added: incubator/bluesky/NCstu-2.0/src/en_de_sendthread.h
URL: http://svn.apache.org/viewvc/incubator/bluesky/NCstu-2.0/src/en_de_sendthread.h?rev=662948&view=auto
==============================================================================
--- incubator/bluesky/NCstu-2.0/src/en_de_sendthread.h (added)
+++ incubator/bluesky/NCstu-2.0/src/en_de_sendthread.h Tue Jun  3 19:48:16 2008
@@ -0,0 +1,121 @@
+
+
+// rtp
+#include "fecrtpsession.h"
+// Linux sys.
+#include <iostream>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <linux/types.h>
+#include <linux/videodev.h>
+// FFmpeg
+#include <ffmpeg/avcodec.h>
+#include <ffmpeg/avformat.h>
+
+// SDL
+#include <time.h>
+
+// X11
+#include <X11/Intrinsic.h>
+#include <X11/XWDFile.h>
+// Jthread and JMutex
+#include <jthread.h>
+#include <jmutex.h>
+
+// arts
+#include <kde/artsc/artsc.h>
+
+#if !defined(_EN_DE_SENDTHREAD_H__INCLUDED_)
+#define _EN_DE_SENDTHREAD_H__INCLUDED_
+
+#define MIN_ARTS_WRITE_FRAMES 3
+#define MAX_ARTS_WRITE_FRAMES 250
+#define AUDIO_SAMPLE_RATE 44100 
+#define STATIC_AUDIO_CHANNEL 1
+
+
+
+
+struct SENDBUFDATA{
+	uint8_t* data;
+	int datalen;
+	//		SENDBUFDATA* next;
+};
+typedef std::list<SENDBUFDATA*> SendDatalist;
+
+//CSendThread class.
+class CSendThread : private JThread
+{
+public:
+	CSendThread(int nSendBufSize);
+	~CSendThread();
+	bool Init(int nPort);
+	bool AddDestination(const RTPIPv4Address &des);
+	void ClearDestinations();
+	int SendData(uint8_t *data, int datalen);
+	int Start();
+	void Stop();
+//	inline uint16_t GetFrameNo(){return m_fecrtpsession.GetFrameNo();};
+private:
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	CFECRtpSession m_fecrtpsession;
+	int m_bInit;
+
+	int m_nSendBufSize;
+	SendDatalist m_senddata;
+	JMutex m_senddatamutex;
+};
+
+//***************************************************audio arts write*****************
+
+
+
+struct AUDIOBUFDATA{
+	uint8_t* data;
+	int datalen;
+	//		SENDBUFDATA* next;
+};
+typedef std::list<AUDIOBUFDATA*> SendAudioDatalist;
+
+//CSendThread class.
+class CAudioWriteThread : private JThread
+{
+public:
+	CAudioWriteThread(int nSendBufSize);
+	~CAudioWriteThread();
+	bool Init( );
+
+	int SetData(uint8_t *data, int datalen);
+	int Start();
+	void CloseAudio();
+	bool OpenAudio();
+	void Stop();
+
+private:
+	void *Thread();
+	bool stop;
+	JMutex stopmutex;
+private:
+	bool m_bInit;
+	bool m_bOpenArts;
+
+	int m_nSendBufSize;
+	SendAudioDatalist m_senddata;
+	JMutex m_senddatamutex;
+
+	// arts
+	static int g_arts_count;
+	arts_stream_t m_stream;
+	char m_pName[20];
+};
+
+
+#endif // !defined(_EN_DE_SENDTHREAD_H__INCLUDED_)



Mime
View raw message