diff options
| -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), | 
