diff options
author | iovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a> | 2007-05-08 04:20:33 +0000 |
---|---|---|
committer | iovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a> | 2007-05-08 04:20:33 +0000 |
commit | 6690076b0c1d40ec0b0990b31092b4a459a71669 (patch) | |
tree | 80c4a7c132449ce7113a6d226959b798d0be3a03 /recordmydesktop | |
parent | 92d58558179beff08d52ac152c3a3da8a1a367cb (diff) |
added double buffering when capturing in full-shots.
This way, only pixels that have changed are converted to yuv
git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@333 f606c939-3180-4ac9-a4b8-4b8779d57d0a
Diffstat (limited to 'recordmydesktop')
-rw-r--r-- | recordmydesktop/include/recordmydesktop.h | 2 | ||||
-rw-r--r-- | recordmydesktop/include/rmdmacro.h | 197 | ||||
-rw-r--r-- | recordmydesktop/include/rmdtypes.h | 5 | ||||
-rw-r--r-- | recordmydesktop/src/get_frame.c | 132 | ||||
-rw-r--r-- | recordmydesktop/src/initialize_data.c | 60 | ||||
-rw-r--r-- | recordmydesktop/src/recordmydesktop.c | 8 | ||||
-rw-r--r-- | recordmydesktop/src/update_image.c | 2 |
7 files changed, 310 insertions, 96 deletions
diff --git a/recordmydesktop/include/recordmydesktop.h b/recordmydesktop/include/recordmydesktop.h index 358965d..ae17db4 100644 --- a/recordmydesktop/include/recordmydesktop.h +++ b/recordmydesktop/include/recordmydesktop.h @@ -56,7 +56,7 @@ unsigned int frames_total, //frames calculated by total time expirations int capture_busy, encoder_busy; - +int exit_status; #endif diff --git a/recordmydesktop/include/rmdmacro.h b/recordmydesktop/include/rmdmacro.h index 92e0903..9c49292 100644 --- a/recordmydesktop/include/rmdmacro.h +++ b/recordmydesktop/include/rmdmacro.h @@ -309,6 +309,59 @@ }\ } +#define UPDATE_Y_PLANE_DBUF(data,\ + data_back,\ + x_tm,\ + y_tm,\ + height_tm,\ + width_tm,\ + yuv,\ + __bit_depth__){ \ + int k,i;\ + register u_int##__bit_depth__##_t t_val;\ + register unsigned char *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\ + *_yr=Yr,*_yg=Yg,*_yb=Yb;\ + register u_int##__bit_depth__##_t *datapi=(u_int##__bit_depth__##_t *)data,\ + *datapi_back=(u_int##__bit_depth__##_t *)data_back;\ + for(k=0;k<height_tm;k++){\ + for(i=0;i<width_tm;i++){\ + if(*datapi!=*datapi_back){\ + t_val=*datapi;\ + *yuv_y=_yr[__RVALUE_##__bit_depth__(t_val)] +\ + _yg[__GVALUE_##__bit_depth__(t_val)] +\ + _yb[__BVALUE_##__bit_depth__(t_val)] ;\ + }\ + datapi++;\ + datapi_back++;\ + yuv_y++;\ + }\ + yuv_y+=yuv->y_width-width_tm;\ + }\ +} + +#define UPDATE_A_UV_PIXEL(yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ + if(__sampling_type==__PXL_AVERAGE){\ + CALC_TVAL_AVG_##__bit_depth__(t_val,datapi,datapi_next)\ + }\ + else\ + t_val=*datapi;\ + *yuv_u=\ + _ur[__RVALUE_##__bit_depth__(t_val)] +\ + _ug[__GVALUE_##__bit_depth__(t_val)] +\ + _ubvr[__BVALUE_##__bit_depth__(t_val)];\ + *yuv_v=\ + _ubvr[__RVALUE_##__bit_depth__(t_val)] +\ + _vg[__GVALUE_##__bit_depth__(t_val)] +\ + _vb[__BVALUE_##__bit_depth__(t_val)];\ + + #define UPDATE_UV_PLANES(data,\ x_tm,\ y_tm,\ @@ -330,19 +383,14 @@ }\ for(k=0;k<height_tm;k+=2){\ for(i=0;i<width_tm;i+=2){\ - if(__sampling_type==__PXL_AVERAGE){\ - CALC_TVAL_AVG_##__bit_depth__(t_val,datapi,datapi_next)\ - }\ - else\ - t_val=*datapi;\ - *yuv_u=\ - _ur[__RVALUE_##__bit_depth__(t_val)] +\ - _ug[__GVALUE_##__bit_depth__(t_val)] +\ - _ubvr[__BVALUE_##__bit_depth__(t_val)];\ - *yuv_v=\ - _ubvr[__RVALUE_##__bit_depth__(t_val)] +\ - _vg[__GVALUE_##__bit_depth__(t_val)] +\ - _vb[__BVALUE_##__bit_depth__(t_val)];\ + UPDATE_A_UV_PIXEL( yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ datapi+=2;\ if(__sampling_type==__PXL_AVERAGE)\ datapi_next+=2;\ @@ -357,23 +405,130 @@ }\ } +#define UPDATE_UV_PLANES_DBUF( data,\ + data_back,\ + x_tm,\ + y_tm,\ + height_tm,\ + width_tm,\ + yuv,\ + __sampling_type,\ + __bit_depth__){ \ + int k,i;\ + register u_int##__bit_depth__##_t t_val;\ + register unsigned char *yuv_u=yuv->u+x_tm/2+(y_tm*yuv->uv_width)/2,\ + *yuv_v=yuv->v+x_tm/2+(y_tm*yuv->uv_width)/2,\ + *_ur=Ur,*_ug=Ug,*_ubvr=UbVr,\ + *_vg=Vg,*_vb=Vb;\ + register u_int##__bit_depth__##_t *datapi=(u_int##__bit_depth__##_t *)data,\ + *datapi_next=NULL,\ + *datapi_back=(u_int##__bit_depth__##_t *)data_back,\ + *datapi_back_next=NULL;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next=datapi+width_tm;\ + datapi_back_next=datapi_back+width_tm;\ + for(k=0;k<height_tm;k+=2){\ + for(i=0;i<width_tm;i+=2){\ + if(( (*datapi!=*datapi_back) ||\ + (*(datapi+1)!=*(datapi_back+1)) ||\ + (*datapi_next!=*datapi_back_next) ||\ + (*(datapi_next+1)!=*(datapi_back_next+1)))){\ + UPDATE_A_UV_PIXEL( yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ + }\ + datapi+=2;\ + datapi_back+=2;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=2;\ + datapi_back_next+=2;\ + }\ + yuv_u++;\ + yuv_v++;\ + }\ + yuv_u+=(yuv->y_width-width_tm)/2;\ + yuv_v+=(yuv->y_width-width_tm)/2;\ + datapi+=width_tm;\ + datapi_back+=width_tm;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=width_tm;\ + datapi_back_next+=width_tm;\ + }\ + }\ + }\ + else{\ + for(k=0;k<height_tm;k+=2){\ + for(i=0;i<width_tm;i+=2){\ + if ((*datapi!=*datapi_back)){\ + UPDATE_A_UV_PIXEL( yuv_u,\ + yuv_v,\ + t_val,\ + datapi,\ + datapi_next,\ + _ur,_ug,_ubvr,_vg,_vb,\ + __sampling_type,\ + __bit_depth__)\ + }\ + datapi+=2;\ + datapi_back+=2;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=2;\ + datapi_back_next+=2;\ + }\ + yuv_u++;\ + yuv_v++;\ + }\ + yuv_u+=(yuv->y_width-width_tm)/2;\ + yuv_v+=(yuv->y_width-width_tm)/2;\ + datapi+=width_tm;\ + datapi_back+=width_tm;\ + if(__sampling_type==__PXL_AVERAGE){\ + datapi_next+=width_tm;\ + datapi_back_next+=width_tm;\ + }\ + }\ + }\ +} + #define UPDATE_YUV_BUFFER(yuv,\ data,\ + data_back,\ x_tm,\ y_tm,\ width_tm,\ height_tm,\ __sampling_type,\ __color_depth){\ - if((__color_depth==24)||(__color_depth==32)){\ - UPDATE_Y_PLANE(data,x_tm,y_tm,height_tm,width_tm,yuv,32)\ - UPDATE_UV_PLANES(data,x_tm,y_tm,height_tm,width_tm,\ - yuv,__sampling_type,32)\ + if(data_back==NULL){\ + if((__color_depth==24)||(__color_depth==32)){\ + UPDATE_Y_PLANE(data,x_tm,y_tm,height_tm,width_tm,yuv,32)\ + UPDATE_UV_PLANES(data,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,32)\ + }\ + else if(__color_depth==16){\ + UPDATE_Y_PLANE(data,x_tm,y_tm,height_tm,width_tm,yuv,16)\ + UPDATE_UV_PLANES(data,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,16)\ + }\ }\ - else if(__color_depth==16){\ - UPDATE_Y_PLANE(data,x_tm,y_tm,height_tm,width_tm,yuv,16)\ - UPDATE_UV_PLANES(data,x_tm,y_tm,height_tm,width_tm,\ - yuv,__sampling_type,16)\ + else{\ + if((__color_depth==24)||(__color_depth==32)){\ + UPDATE_Y_PLANE_DBUF(data,data_back,x_tm,y_tm,\ + height_tm,width_tm,yuv,32)\ + UPDATE_UV_PLANES_DBUF(data,data_back,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,32)\ + }\ + else if(__color_depth==16){\ + UPDATE_Y_PLANE_DBUF(data,data_back,x_tm,y_tm,\ + height_tm,width_tm,yuv,16)\ + UPDATE_UV_PLANES_DBUF(data,data_back,x_tm,y_tm,height_tm,width_tm,\ + yuv,__sampling_type,16)\ + }\ }\ } diff --git a/recordmydesktop/include/rmdtypes.h b/recordmydesktop/include/rmdtypes.h index 31a0d6d..2e63d29 100644 --- a/recordmydesktop/include/rmdtypes.h +++ b/recordmydesktop/include/rmdtypes.h @@ -270,8 +270,6 @@ typedef struct _ProgData{ #endif /**X related info*/ Display *dpy; //curtrent display - XImage *image; //the image that holds the current full screenshot - XShmSegmentInfo shminfo;//info structure for the image above. /** Mutexes*/ pthread_mutex_t list_mutex[2], //mutexes for concurrency //protection of the lists @@ -310,8 +308,7 @@ typedef struct _ProgData{ //when drawing the dummy pointer unsigned int periodtime,//time that a sound buffer lasts (microsecs) frametime; //time that a frame lasts (microsecs) - char *pxl_data, //the data of image - *window_manager; //name of the window manager at program launch + char *window_manager; //name of the window manager at program launch int list_selector, //selector for the rect_roots damage_event, //damage event base code damage_error, //damage error base code diff --git a/recordmydesktop/src/get_frame.c b/recordmydesktop/src/get_frame.c index 5ab5b8d..6d81436 100644 --- a/recordmydesktop/src/get_frame.c +++ b/recordmydesktop/src/get_frame.c @@ -27,13 +27,120 @@ #include <recordmydesktop.h> +int FirstFrame(ProgData *pdata,XImage **image,XShmSegmentInfo *shminfo, + char **pxl_data){ + + if((pdata->args.noshared)){ + (*image)=XCreateImage(pdata->dpy, + pdata->specs.visual, + pdata->specs.depth, + ZPixmap, + 0, + *pxl_data, + pdata->brwin.rgeom.width, + pdata->brwin.rgeom.height, + 8, + 0); + XInitImage((*image)); + GetZPixmap(pdata->dpy,pdata->specs.root, + (*image)->data, + pdata->brwin.rgeom.x, + pdata->brwin.rgeom.y, + pdata->brwin.rgeom.width, + pdata->brwin.rgeom.height); + *pxl_data=(char *)malloc(pdata->brwin.nbytes); + } + else{ + (*image)=XShmCreateImage(pdata->dpy, + pdata->specs.visual, + pdata->specs.depth, + ZPixmap, + *pxl_data, + shminfo, + pdata->brwin.rgeom.width, + pdata->brwin.rgeom.height); + (*shminfo).shmid=shmget(IPC_PRIVATE, + (*image)->bytes_per_line* + (*image)->height, + IPC_CREAT|0777); + if((*shminfo).shmid==-1){ + fprintf(stderr,"Failed to obtain Shared Memory segment!\n"); + return 12; + } + (*shminfo).shmaddr=(*image)->data=shmat((*shminfo).shmid, + NULL,0); + (*shminfo).readOnly = False; + if(!XShmAttach(pdata->dpy,shminfo)){ + fprintf(stderr,"Failed to attach shared memory to proccess.\n"); + return 12; + } + XShmGetImage(pdata->dpy, + pdata->specs.root, + (*image), + pdata->brwin.rgeom.x, + pdata->brwin.rgeom.y, + AllPlanes); + } + + UPDATE_YUV_BUFFER((&pdata->enc_data->yuv), + ((unsigned char*)((*image))->data),NULL, + (pdata->enc_data->x_offset),(pdata->enc_data->y_offset), + (pdata->brwin.rgeom.width),(pdata->brwin.rgeom.height), + (pdata->args.no_quick_subsample), + pdata->specs.depth); + + return 0; +} + void *GetFrame(ProgData *pdata){ int tlist_sel=0; uint msk_ret; WGeometry mouse_pos_abs,mouse_pos_rel,mouse_pos_temp; Window root_ret,child_ret; XFixesCursorImage *xcim=NULL; + XImage *image=NULL,*image_back=NULL; //the image that holds + //the current full screenshot + XShmSegmentInfo shminfo,shminfo_back;//info structure for the image above. + int init_img1=0,init_img2=0, + d_buff=pdata->args.full_shots, + img_sel=1; + char *pxl_data=NULL,*pxl_data_back=NULL; + if((init_img1=FirstFrame(pdata,&image,&shminfo,&pxl_data)!=0)){ + if(pdata->args.encOnTheFly){ + if(remove(pdata->args.filename)){ + perror("Error while removing file:\n"); + } + else{ + fprintf(stderr,"SIGABRT received,file %s removed\n", + pdata->args.filename); + } + } + else{ + PurgeCache(pdata->cache_data,!pdata->args.nosound); + } + exit(init_img1); + } + if(d_buff){ + if((init_img2=FirstFrame(pdata,&image_back,&shminfo_back, + &pxl_data_back)!=0)){ + if(pdata->args.encOnTheFly){ + if(remove(pdata->args.filename)){ + perror("Error while removing file:\n"); + } + else{ + fprintf(stderr,"SIGABRT received,file %s removed\n", + pdata->args.filename); + } + } + else{ + PurgeCache(pdata->cache_data,!pdata->args.nosound); + } + exit(init_img2); + } + + } + if (image_back==NULL)fprintf(stderr,"heres %d\n",init_img2);fflush(stderr); mouse_pos_abs.x=mouse_pos_temp.x=0; mouse_pos_abs.y=mouse_pos_temp.y=0; mouse_pos_abs.width=mouse_pos_temp.width=pdata->dummy_p_size; @@ -54,6 +161,8 @@ void *GetFrame(ProgData *pdata){ pthread_mutex_unlock(&pause_mutex); } } + if(d_buff) + img_sel=(img_sel)?0:1; capture_busy=1; //mutexes and lists with changes are useless when full_shots is enabled if(!pdata->args.full_shots){ @@ -108,20 +217,28 @@ void *GetFrame(ProgData *pdata){ &pdata->rect_root[tlist_sel], &pdata->brwin, pdata->enc_data, - pdata->image->data, + image->data, pdata->args.noshared, - &pdata->shminfo, + &shminfo, pdata->shm_opcode, pdata->args.no_quick_subsample); else{ + unsigned char *front_buff=(!img_sel)?((unsigned char*)image->data): + ((unsigned char*)image_back->data); + unsigned char *back_buff=(!d_buff)?NULL:((img_sel)? + ((unsigned char*)image->data): + ((unsigned char*)image_back->data)); + if(!pdata->args.noshared) - XShmGetImage(pdata->dpy,pdata->specs.root,pdata->image, + XShmGetImage(pdata->dpy,pdata->specs.root, + ((!img_sel)?image:image_back), (pdata->brwin.rgeom.x), (pdata->brwin.rgeom.y),AllPlanes); + if(pdata->args.noshared){ GetZPixmap( pdata->dpy, pdata->specs.root, - pdata->image->data, + image->data, pdata->brwin.rgeom.x, pdata->brwin.rgeom.y, pdata->brwin.rgeom.width, @@ -129,7 +246,7 @@ void *GetFrame(ProgData *pdata){ } pthread_mutex_lock(&pdata->yuv_mutex); UPDATE_YUV_BUFFER((&pdata->enc_data->yuv), - ((unsigned char*)pdata->image->data), + front_buff,back_buff, (pdata->enc_data->x_offset), (pdata->enc_data->y_offset), (pdata->brwin.rgeom.width), @@ -200,6 +317,11 @@ void *GetFrame(ProgData *pdata){ pthread_mutex_lock(&pdata->img_buff_ready_mutex); pthread_cond_broadcast(&pdata->image_buffer_ready); pthread_mutex_unlock(&pdata->img_buff_ready_mutex); + if(!pdata->args.noshared){ + XShmDetach (pdata->dpy, &shminfo); + shmdt (shminfo.shmaddr); + shmctl (shminfo.shmid, IPC_RMID, 0); + } pthread_exit(&errno); } diff --git a/recordmydesktop/src/initialize_data.c b/recordmydesktop/src/initialize_data.c index ede8855..7358b34 100644 --- a/recordmydesktop/src/initialize_data.c +++ b/recordmydesktop/src/initialize_data.c @@ -59,8 +59,7 @@ int InitializeData(ProgData *pdata, pdata->dummy_p_size=16; } - if((pdata->args.noshared)) - pdata->pxl_data=(char *)malloc(pdata->brwin.nbytes); + pdata->rect_root[0]=pdata->rect_root[1]=NULL; pthread_mutex_init(&pdata->list_mutex[0],NULL); @@ -89,56 +88,6 @@ int InitializeData(ProgData *pdata, pause_cond=&pdata->pause_cond; Running=&pdata->running; - if((pdata->args.noshared)){ - pdata->image=XCreateImage(pdata->dpy, - pdata->specs.visual, - pdata->specs.depth, - ZPixmap, - 0, - pdata->pxl_data, - pdata->brwin.rgeom.width, - pdata->brwin.rgeom.height, - 8, - 0); - XInitImage(pdata->image); - GetZPixmap(pdata->dpy,pdata->specs.root, - pdata->image->data, - pdata->brwin.rgeom.x, - pdata->brwin.rgeom.y, - pdata->brwin.rgeom.width, - pdata->brwin.rgeom.height); - } - if((!pdata->args.noshared)){ - pdata->image=XShmCreateImage(pdata->dpy, - pdata->specs.visual, - pdata->specs.depth, - ZPixmap, - pdata->pxl_data, - &pdata->shminfo, - pdata->brwin.rgeom.width, - pdata->brwin.rgeom.height); - pdata->shminfo.shmid=shmget(IPC_PRIVATE, - pdata->image->bytes_per_line* - pdata->image->height, - IPC_CREAT|0777); - if(pdata->shminfo.shmid==-1){ - fprintf(stderr,"Failed to obtain Shared Memory segment!\n"); - return 12; - } - pdata->shminfo.shmaddr=pdata->image->data=shmat(pdata->shminfo.shmid, - NULL,0); - pdata->shminfo.readOnly = False; - if(!XShmAttach(pdata->dpy,&pdata->shminfo)){ - fprintf(stderr,"Failed to attach shared memory to proccess.\n"); - return 12; - } - XShmGetImage(pdata->dpy, - pdata->specs.root, - pdata->image, - pdata->brwin.rgeom.x, - pdata->brwin.rgeom.y, - AllPlanes); - } if(!pdata->args.nosound){ if(!pdata->args.use_jack){ FixBufferSize(&pdata->args.buffsize); @@ -207,12 +156,7 @@ int InitializeData(ProgData *pdata, pdata->enc_data->yuv.v[i]=pdata->enc_data->yuv.u[i]=127; } - UPDATE_YUV_BUFFER((&pdata->enc_data->yuv), - ((unsigned char*)pdata->image->data), - (pdata->enc_data->x_offset),(pdata->enc_data->y_offset), - (pdata->brwin.rgeom.width),(pdata->brwin.rgeom.height), - (pdata->args.no_quick_subsample), - pdata->specs.depth); + pdata->frametime=(1000000)/pdata->args.fps; return 0; diff --git a/recordmydesktop/src/recordmydesktop.c b/recordmydesktop/src/recordmydesktop.c index 036bf5a..b92e934 100644 --- a/recordmydesktop/src/recordmydesktop.c +++ b/recordmydesktop/src/recordmydesktop.c @@ -31,7 +31,7 @@ int main(int argc,char **argv){ ProgData pdata; - int exit_status=0; + exit_status=0; if(XInitThreads ()==0){ fprintf(stderr,"Couldn't initialize thread support!\n"); exit(7); @@ -106,11 +106,7 @@ int main(int argc,char **argv){ rmdThreads(&pdata); fprintf(stderr,"."); - if(!pdata.args.noshared){ - XShmDetach (pdata.dpy, &pdata.shminfo); - shmdt (&pdata.shminfo.shmaddr); - shmctl (pdata.shminfo.shmid, IPC_RMID, 0); - } + fprintf(stderr,"\n"); //encode and then cleanup cache diff --git a/recordmydesktop/src/update_image.c b/recordmydesktop/src/update_image.c index 7a2895f..e365555 100644 --- a/recordmydesktop/src/update_image.c +++ b/recordmydesktop/src/update_image.c @@ -65,7 +65,7 @@ void UpdateImage(Display * dpy, temp->geom.height); } pthread_mutex_lock(yuv_mutex); - UPDATE_YUV_BUFFER(yuv,dtap, + UPDATE_YUV_BUFFER(yuv,dtap,NULL, (temp->geom.x-brwin->rgeom.x+enc->x_offset), (temp->geom.y-brwin->rgeom.y+enc->y_offset), (temp->geom.width),(temp->geom.height), |