diff options
-rw-r--r-- | rMD-exp/include/recordmydesktop.h | 19 | ||||
-rw-r--r-- | rMD-exp/src/cache_frame.c | 5 | ||||
-rw-r--r-- | rMD-exp/src/encode_image_buffer.c | 2 | ||||
-rw-r--r-- | rMD-exp/src/load_cache.c | 160 | ||||
-rw-r--r-- | rMD-exp/src/poll_damage.c | 1 | ||||
-rw-r--r-- | rMD-exp/src/recordmydesktop.c | 20 |
6 files changed, 199 insertions, 8 deletions
diff --git a/rMD-exp/include/recordmydesktop.h b/rMD-exp/include/recordmydesktop.h index e0eb0d9..0eafa01 100644 --- a/rMD-exp/include/recordmydesktop.h +++ b/rMD-exp/include/recordmydesktop.h @@ -268,6 +268,7 @@ typedef struct _ProgData{ //default 4+4+2+2+2=14!bad! //me add pad, make god of 2 happy! typedef struct _FrameHeader{ + char frame_prefix[4];//always FRAM u_int32_t frameno,//number of frame(cached frames) current_total;//number of frames that should have been //taken at time of caching this one @@ -562,6 +563,24 @@ int capture_busy, free(t_buf);\ };\ +#define INIT_FRAME(frame_t,fheader_t,yuv_t){\ + (frame_t)->header=(fheader_t);\ + (frame_t)->YBlocks=malloc(256);\ + (frame_t)->UBlocks=malloc(64);\ + (frame_t)->VBlocks=malloc(64);\ + (frame_t)->YData=malloc((yuv_t)->y_width*(yuv_t)->y_height);\ + (frame_t)->UData=malloc((yuv_t)->uv_width*(yuv_t)->uv_height);\ + (frame_t)->VData=malloc((yuv_t)->uv_width*(yuv_t)->uv_height);\ +}; + +#define CLEAR_FRAME(frame_t){\ + free((frame_t)->YBlocks);\ + free((frame_t)->UBlocks);\ + free((frame_t)->VBlocks);\ + free((frame_t)->YData);\ + free((frame_t)->UData);\ + free((frame_t)->VData);\ +}; /**Function prototypes*/ diff --git a/rMD-exp/src/cache_frame.c b/rMD-exp/src/cache_frame.c index 8a1e0ca..c83b54b 100644 --- a/rMD-exp/src/cache_frame.c +++ b/rMD-exp/src/cache_frame.c @@ -150,13 +150,14 @@ void *CacheImageBuffer(void *pdata){ gzsetparams (fp,1,Z_FILTERED); else gzsetparams (fp,0,Z_FILTERED); + strncpy(fheader.frame_prefix,"FRAM",4); fheader.frameno=++frameno; fheader.current_total=frames_total; fheader.Ynum=ynum; fheader.Unum=unum; fheader.Vnum=vnum; fheader.pad=0; - gzwrite(fp,(void*)&fheader,16); + gzwrite(fp,(void*)&fheader,sizeof(FrameHeader)); //flush indexes if(ynum)gzwrite(fp,yblocks,ynum); if(unum)gzwrite(fp,ublocks,unum); @@ -189,7 +190,7 @@ void *CacheImageBuffer(void *pdata){ free(yuv[i].u); free(yuv[i].v); } -// fprintf(stderr,"Saved %d frames in a total of %d requests",frameno,frames_total); + fprintf(stderr,"Saved %d frames in a total of %d requests",frameno,frames_total); gzclose(fp); pthread_exit(&errno); } diff --git a/rMD-exp/src/encode_image_buffer.c b/rMD-exp/src/encode_image_buffer.c index 38a1d77..2718d0e 100644 --- a/rMD-exp/src/encode_image_buffer.c +++ b/rMD-exp/src/encode_image_buffer.c @@ -30,8 +30,8 @@ void *EncodeImageBuffer(void *pdata){ pthread_mutex_init(&pmut,NULL); pthread_mutex_init(&imut,NULL); while(((ProgData *)pdata)->running){ - encoder_busy=1; pthread_cond_wait(&((ProgData *)pdata)->image_buffer_ready,&imut); + encoder_busy=1; if(Paused) pthread_cond_wait(&((ProgData *)pdata)->pause_cond,&pmut);//this may not be needed pthread_mutex_lock(&((ProgData *)pdata)->yuv_mutex); diff --git a/rMD-exp/src/load_cache.c b/rMD-exp/src/load_cache.c index dbe6057..246b14e 100644 --- a/rMD-exp/src/load_cache.c +++ b/rMD-exp/src/load_cache.c @@ -27,16 +27,174 @@ #include <recordmydesktop.h> +void LoadBlock(unsigned char *dest,unsigned char *source,int blockno,int width, int height,int divisor){ + int j, + block_i=blockno/divisor,//place on the grid + block_k=blockno%divisor; + + for(j=0;j<height/divisor;j++)//we copy rows + memcpy( &dest[block_i*(width*height/divisor)+j*width+block_k*width/divisor], + &source[j*width/divisor], + width/divisor); +// gzread(fp,(void *)&dest[block_i*(width*height/divisor)+j*width+block_k*width/divisor],width/divisor); +// ; +} + void *LoadCache(void *pdata){ + yuv_buffer *yuv=&((ProgData *)pdata)->enc_data->yuv; + gzFile *ifp=((ProgData *)pdata)->cache_data->ifp; + FILE *afp=((ProgData *)pdata)->cache_data->afp; + FrameHeader fheader; + CachedFrame frame; + int j=0, + thread_exit=0,//0 success, -1 couldn't find files,1 couldn't remove + divisor=16, + blockszy=0,//size of y plane block in bytes + blockszuv=0;//size of u,v plane blocks in bytes + //we allocate the frame that we will use + INIT_FRAME(&frame,&fheader,yuv) + //and the we open our files + ifp=gzopen(((ProgData *)pdata)->cache_data->imgdata,"rb"); + if(ifp==NULL){ + thread_exit=-1; + pthread_exit(&thread_exit); + } + + if(!((ProgData *)pdata)->args.nosound){ + afp=fopen(((ProgData *)pdata)->cache_data->audiodata,"rb"); + if(afp==NULL){ + thread_exit=-1; + pthread_exit(&thread_exit); + } + } +// int first=10; + + //recalculate the divisor since it is not saved + while(((((ProgData *)pdata)->brwin.rgeom.width* + ((ProgData *)pdata)->brwin.rgeom.width ) + /pow(divisor,2)) + <=1024){ + divisor/=2; + if(divisor==2) + break; + } + //these two are likely to be the same, but not guaranteed, especially on + //low resolutions + blockszy=(yuv->y_width*yuv->y_height )/pow(divisor,2); + blockszuv=(yuv->uv_width*yuv->uv_height)/pow(divisor/2,2); + + + while(((ProgData *)pdata)->running){ + int framesize=0; +// if(first){ + if(gzread(ifp,frame.header,sizeof(FrameHeader))==sizeof(FrameHeader)){ +// fprintf(stderr,"1:%c%c%c%c \n1: %d \n1: %d \n1: %d \n1: %d \n1: %d \n1: %d\n", +// frame.header->frame_prefix[0],frame.header->frame_prefix[1],frame.header->frame_prefix[2],frame.header->frame_prefix[3], +// frame.header->frameno,frame.header->current_total +// ,frame.header->Ynum,frame.header->Unum,frame.header->Vnum,frame.header->pad);fflush(stderr); + fprintf(stderr,"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b %d of %d",frame.header->frameno,frame.header->current_total); + if( (frame.header->Ynum<=pow(divisor,2)) && + (frame.header->Unum<=pow(divisor/2,2)) && + (frame.header->Vnum<=pow(divisor/2,2)) && + (gzread(ifp,frame.YBlocks,frame.header->Ynum)==frame.header->Ynum) && + (gzread(ifp,frame.UBlocks,frame.header->Unum)==frame.header->Unum) && + (gzread(ifp,frame.VBlocks,frame.header->Vnum)==frame.header->Vnum) && + (gzread(ifp,frame.YData,blockszy*frame.header->Ynum)==blockszy*frame.header->Ynum) && + (gzread(ifp,frame.UData,(blockszuv*frame.header->Unum))==(blockszuv*frame.header->Unum)) && + (gzread(ifp,frame.VData,(blockszuv*frame.header->Vnum))==(blockszuv*frame.header->Vnum))){ + framesize+=sizeof(FrameHeader) + +frame.header->Ynum+frame.header->Unum+frame.header->Vnum + +blockszy*frame.header->Ynum+(blockszuv*frame.header->Unum) + +(blockszuv*frame.header->Vnum); +// fprintf(stderr,"OK! %d \n%d %d %d\n",framesize,blockszy,blockszuv,sizeof(FrameHeader));fflush(stderr); + + pthread_mutex_lock(&((ProgData *)pdata)->yuv_mutex); + + //load the blocks for each buffer + if(frame.header->Ynum) + for(j=0;j<frame.header->Ynum;j++) + LoadBlock( yuv->y, + &frame.YData[j*blockszy], + frame.YBlocks[j], + yuv->y_width, + yuv->y_height, + divisor); + if(frame.header->Unum) + for(j=0;j<frame.header->Unum;j++) + LoadBlock( yuv->u, + &frame.UData[j*blockszuv], + frame.UBlocks[j], + yuv->uv_width, + yuv->uv_height, + divisor/2); + if(frame.header->Vnum) + for(j=0;j<frame.header->Vnum;j++) + LoadBlock( yuv->v, + &frame.VData[j*blockszuv], + frame.VBlocks[j], + yuv->uv_width, + yuv->uv_height, + divisor/2); + pthread_mutex_unlock(&((ProgData *)pdata)->yuv_mutex); + + while(encoder_busy){ + usleep(100); + } + pthread_cond_broadcast(&((ProgData *)pdata)->image_buffer_ready); + while(encoder_busy){ + usleep(100); + } + } + else{ +// first=0; + raise(SIGINT); + continue; + } + } + else{ +// first=0; + raise(SIGINT); + continue; + } + +// } + + //call loading func{ + //if avd>=0 + //load image from cache + //signal buffer + ////if avd<0 + //load sound from cache + //signal buffer + //} +// sleep(1); + } + CLEAR_FRAME(&frame) + gzclose(ifp); + if(remove(((ProgData *)pdata)->cache_data->imgdata)){ + fprintf(stderr,"Couldn't remove temporary file %s",((ProgData *)pdata)->cache_data->imgdata); + thread_exit=1; + } + if(!((ProgData *)pdata)->args.nosound){ + fclose(afp); + if(remove(((ProgData *)pdata)->cache_data->audiodata)){ + fprintf(stderr,"Couldn't remove temporary file %s",((ProgData *)pdata)->cache_data->audiodata); + thread_exit=1; + } + } + if(remove(((ProgData *)pdata)->cache_data->projname)){ + fprintf(stderr,"Couldn't remove temporary directory %s",((ProgData *)pdata)->cache_data->projname); + thread_exit=1; + } + pthread_exit(&thread_exit); - pthread_exit(&errno); } diff --git a/rMD-exp/src/poll_damage.c b/rMD-exp/src/poll_damage.c index 73742f5..1878439 100644 --- a/rMD-exp/src/poll_damage.c +++ b/rMD-exp/src/poll_damage.c @@ -52,6 +52,7 @@ void *PollDamage(void *pdata){ } } } + XDamageDestroy(((ProgData *)pdata)->dpy,damage); pthread_exit(&errno); } diff --git a/rMD-exp/src/recordmydesktop.c b/rMD-exp/src/recordmydesktop.c index 9d05bf0..a90a953 100644 --- a/rMD-exp/src/recordmydesktop.c +++ b/rMD-exp/src/recordmydesktop.c @@ -260,9 +260,8 @@ int main(int argc,char **argv){ shmctl (shminfo.shmid, IPC_RMID, 0); } fprintf(stderr,"\n"); + - if(pdata.args.full_shots || inserts!=1)//otherwise it will hang - XCloseDisplay(pdata.dpy); /** Encoding */ @@ -271,11 +270,18 @@ int main(int argc,char **argv){ pdata.running=1; InitEncoder(&pdata,&enc_data,1); - //load encoding and flushing threads pthread_create(&image_encode_t,NULL,EncodeImageBuffer,(void *)&pdata); - if(!pdata.args.nosound) + if(!pdata.args.nosound){ + //before we start loading again + //we need to free any left-overs + while(pdata.sound_buffer!=NULL){ + free(pdata.sound_buffer->data); + pdata.sound_buffer=pdata.sound_buffer->next; + } pthread_create(&sound_encode_t,NULL,EncodeSoundBuffer,(void *)&pdata); + + } pthread_create(&flush_to_ogg_t,NULL,FlushToOgg,(void *)&pdata); @@ -293,7 +299,9 @@ int main(int argc,char **argv){ //} //join and finish + pthread_join(load_cache_t,NULL); + pthread_cond_broadcast(&pdata.image_buffer_ready); pthread_join(image_encode_t,NULL); if(!pdata.args.nosound) pthread_join(sound_encode_t,NULL); @@ -303,6 +311,10 @@ int main(int argc,char **argv){ } /**@_______________________________________________@*/ + //This can happen earlier, but in some cases it might get stuck. + //So we must make sure the recording is not wasted. + XFlush(pdata.dpy); + XCloseDisplay(pdata.dpy); if(Aborted){ if(remove(pdata.args.filename)){ |