summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rMD-exp/include/recordmydesktop.h19
-rw-r--r--rMD-exp/src/cache_frame.c5
-rw-r--r--rMD-exp/src/encode_image_buffer.c2
-rw-r--r--rMD-exp/src/load_cache.c160
-rw-r--r--rMD-exp/src/poll_damage.c1
-rw-r--r--rMD-exp/src/recordmydesktop.c20
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)){
© All Rights Reserved