summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a>2007-05-08 04:20:33 +0000
committeriovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a>2007-05-08 04:20:33 +0000
commit6690076b0c1d40ec0b0990b31092b4a459a71669 (patch)
tree80c4a7c132449ce7113a6d226959b798d0be3a03
parent92d58558179beff08d52ac152c3a3da8a1a367cb (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
-rw-r--r--recordmydesktop/include/recordmydesktop.h2
-rw-r--r--recordmydesktop/include/rmdmacro.h197
-rw-r--r--recordmydesktop/include/rmdtypes.h5
-rw-r--r--recordmydesktop/src/get_frame.c132
-rw-r--r--recordmydesktop/src/initialize_data.c60
-rw-r--r--recordmydesktop/src/recordmydesktop.c8
-rw-r--r--recordmydesktop/src/update_image.c2
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),
© All Rights Reserved