diff options
author | iovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a> | 2006-10-29 01:36:39 +0000 |
---|---|---|
committer | iovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a> | 2006-10-29 01:36:39 +0000 |
commit | 3606df694f1ec074a4ca322a3c8e39e498960951 (patch) | |
tree | 2a32d9cb8568f03e3c95a1c6d15c7447fc597704 /rMD-exp | |
parent | 5076dbf5c8974316119d6bad42c413a3e3bf5ec9 (diff) |
removed checksums(replaced with per -byte comparison) ,due to fundamental problem in the method.caching scheme is complete(for now). divisor is always 16
git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@125 f606c939-3180-4ac9-a4b8-4b8779d57d0a
Diffstat (limited to 'rMD-exp')
-rw-r--r-- | rMD-exp/include/recordmydesktop.h | 43 | ||||
-rw-r--r-- | rMD-exp/src/cache_frame.c | 74 | ||||
-rw-r--r-- | rMD-exp/src/load_cache.c | 21 | ||||
-rw-r--r-- | rMD-exp/src/parseargs.c | 10 | ||||
-rw-r--r-- | rMD-exp/src/rmd_cache.c | 6 |
5 files changed, 80 insertions, 74 deletions
diff --git a/rMD-exp/include/recordmydesktop.h b/rMD-exp/include/recordmydesktop.h index e78b11a..be10596 100644 --- a/rMD-exp/include/recordmydesktop.h +++ b/rMD-exp/include/recordmydesktop.h @@ -37,7 +37,7 @@ #include <string.h> #include <errno.h> #include <math.h> -#include <unistd.h> +#include <unistd.h> #include <fcntl.h> #include <time.h> #include <signal.h> @@ -79,7 +79,7 @@ //do not be confused -//this is useless and obsolete. +//this is useless and obsolete. //There are no plans for other fotmats enum {UNSPECIFIED,OGG_THEORA_VORBIS}; @@ -87,7 +87,7 @@ enum {UNSPECIFIED,OGG_THEORA_VORBIS}; /**Structs*/ typedef struct _DisplaySpecs{ //this struct holds some basic information - int screen; //about the display,needed mostly for + int screen; //about the display,needed mostly for uint width; //validity checks at startup uint height; Window root; @@ -103,7 +103,7 @@ typedef struct _WGeometry{ //basic geometry of a window or area int y; int width; int height; -}WGeometry; +}WGeometry; typedef struct _RectArea{ //an area that has been damaged gets stored WGeometry geom; //in a list comprised of structs of this type @@ -130,7 +130,7 @@ typedef struct _ProgArgs{ int encoding; //encoding(default OGG_THEORA_VORBIS) int cursor_color; //black or white=>1 or 0 int have_dummy_cursor;//disable/enable drawing of the dummy cursor - int xfixes_cursor; //disable/enable drawing of a cursor obtained + int xfixes_cursor; //disable/enable drawing of a cursor obtained //through the xfixes extension float fps; //desired framerate(default 15) unsigned int frequency; //desired frequency (default 22050) @@ -146,16 +146,16 @@ typedef struct _ProgArgs{ int dropframes; //option for theora encoder int encOnTheFly; //encode while recording, no caching(default 0) char *workdir; //directory to be used for cache files(default $HOME) - + int zerocompression;//image data are always flushed uncompressed }ProgArgs; -//this struct holds anything related to encoding AND -//writting out to file. +//this struct holds anything related to encoding AND +//writting out to file. typedef struct _EncData{ ogg_stream_state m_ogg_ts;//theora ogg_stream_state m_ogg_vs;//vorbis - ogg_page m_ogg_pg;//this could be avoided since + ogg_page m_ogg_pg;//this could be avoided since // it is used only while initializing ogg_packet m_ogg_pckt1;//theora stream ogg_packet m_ogg_pckt2;//vorbis stream @@ -167,7 +167,7 @@ typedef struct _EncData{ //vorbis data vorbis_info m_vo_inf; vorbis_comment m_vo_cmmnt; - vorbis_dsp_state m_vo_dsp; + vorbis_dsp_state m_vo_dsp; vorbis_block m_vo_block; //these should be 0, since area is quantized //before input @@ -197,7 +197,7 @@ typedef struct _CacheData{ }CacheData; //sound buffer -//sound keeps coming so we que it in this list +//sound keeps coming so we que it in this list //which we then traverse typedef struct _SndBuffer{ signed char *data; @@ -205,9 +205,9 @@ typedef struct _SndBuffer{ }SndBuffer; //this structure holds any data related to the program -//It's usage is mostly to be given as an argument to the -//threads,so they will have access to the program data, avoiding -//at the same time usage of any globals. +//It's usage is mostly to be given as an argument to the +//threads,so they will have access to the program data, avoiding +//at the same time usage of any globals. typedef struct _ProgData{ ProgArgs args;//the program arguments DisplaySpecs specs;//Display specific information @@ -219,9 +219,9 @@ typedef struct _ProgData{ //data is casted to unsigned for later use in YUV buffer int dummy_p_size;//initially 16x16,always square unsigned char npxl;//this is the no pixel convention when drawing the dummy pointer - char *datamain,//the data of image + char *datamain,//the data of image *datash,//the data of shimage - *datatemp;//buffer for the temporary image,which will be + *datatemp;//buffer for the temporary image,which will be //preallocated in case shared memory is not used. RectArea *rect_root[2];//the interchanging list roots for storing the changed regions int list_selector,//selector for the above @@ -239,7 +239,7 @@ typedef struct _ProgData{ pthread_mutex_t list_mutex[2],//mutexes for concurrency protection of the lists sound_buffer_mutex, libogg_mutex,//libogg is not thread safe - yuv_mutex;//this might not be needed since we only have + yuv_mutex;//this might not be needed since we only have //one read-only and one write-only thread //also on previous versions, y component was looped separately //and then u and v so this was needed to avoid wrong coloring to render @@ -287,8 +287,8 @@ typedef struct _FrameHeader{ typedef struct _CachedFrame{ FrameHeader *header; unsigned char *YBlocks;//identifying number on the grid, starting at top left - unsigned char *UBlocks;// >> >> - unsigned char *VBlocks;// >> >> + unsigned char *UBlocks;// >> >> + unsigned char *VBlocks;// >> >> unsigned char *YData;//pointer to data for the blocks that have changed, unsigned char *UData;//which have to be remapped on the buffer when reading unsigned char *VData; @@ -308,7 +308,7 @@ unsigned char Yr[256],Yg[256],Yb[256], unsigned int inserts,//total insertions in the lists frames_total,//frames calculated by total time expirations frames_lost;//the value of shame -//used to determine frame drop which can +//used to determine frame drop which can //happen on failure to receive a signal over a condition variable int capture_busy, encoder_busy; @@ -383,7 +383,8 @@ int capture_busy, (args)->display=NULL;\ (args)->windowid=(args)->x=(args)->y\ =(args)->width=(args)->height=(args)->quietmode\ - =(args)->nosound=(args)->full_shots=(args)->encOnTheFly=0;\ + =(args)->nosound=(args)->full_shots=(args)->encOnTheFly\ + =(args)->zerocompression=0;\ (args)->noshared=1;\ (args)->dropframes=(args)->nocondshared=0;\ (args)->no_quick_subsample=1;\ diff --git a/rMD-exp/src/cache_frame.c b/rMD-exp/src/cache_frame.c index 45fb660..f0a7b15 100644 --- a/rMD-exp/src/cache_frame.c +++ b/rMD-exp/src/cache_frame.c @@ -32,7 +32,7 @@ void MakeChecksums(unsigned char *buf,int width,int height,int divisor,unsigned for(i=0;i<divisor;i++){ for(k=0;k<divisor;k++){ - int A=1,B=0; + int A=1,B=0; for(j=0;j<height/divisor;j++){ for(m=0;m<width/divisor;m++){ A+=buf[i*(width*height/divisor)+j*width+k*width/divisor+m]; @@ -42,15 +42,40 @@ void MakeChecksums(unsigned char *buf,int width,int height,int divisor,unsigned A=A%65521; B=B%65521; checksums[i*divisor+k]=B*65536+A; +// A = (A & 0xffff) + (A >> 16) * (15); +// B = (B & 0xffff) + (B >> 16) * (15); +// +// if (A >= 65521) +// A -= 65521; +// +// B = (B & 0xffff) + (B >> 16) * (15); +// if (B >= 65521) +// B -= 65521; +// checksums[i*divisor+k]= ((B << 16) | A) ; + + } } } +int CompareBlocks(unsigned char *incoming,unsigned char *old,int blockno,int width, int height,int divisor){ + int j,i, + block_i=blockno/divisor,//place on the grid + block_k=blockno%divisor; + + for(j=0;j<height/divisor;j++)//we copy rows + for(i=0;i<width/divisor;i++) + if(incoming[block_i*(width*height/divisor)+j*width+block_k*width/divisor+i]!= + old[block_i*(width*height/divisor)+j*width+block_k*width/divisor+i]) + return 1; + return 0; +} + void FlushBlock(unsigned char *buf,int blockno,int width, int height,int divisor,gzFile *fp){ int j, block_i=blockno/divisor,//place on the grid block_k=blockno%divisor; - + for(j=0;j<height/divisor;j++)//we flush in rows gzwrite(fp,(void *)&buf[block_i*(width*height/divisor)+j*width+block_k*width/divisor],width/divisor); @@ -62,38 +87,22 @@ void *CacheImageBuffer(void *pdata){ pthread_mutex_init(&imut,NULL); yuv_buffer yuv[2]; gzFile *fp=((ProgData *)pdata)->cache_data->ifp; - + if(fp==NULL)exit(13); - unsigned short int checksums_y[2][256], - checksums_u[2][64], - checksums_v[2][64]; int i,current=0,divisor=16,firstrun=1,frameno=0; - //we want to make sure that each block has a sufficient - //number of bytes, so that the checksum will wrap - //around 65521. - while(((((ProgData *)pdata)->brwin.rgeom.width* - ((ProgData *)pdata)->brwin.rgeom.width ) - /pow(divisor,2)) - <=1024){ - divisor/=2; - if(divisor==2) - break; - } - - for(i=0;i<2;i++){ yuv[i].y_width=((ProgData *)pdata)->enc_data->yuv.y_width; yuv[i].y_height=((ProgData *)pdata)->enc_data->yuv.y_height; yuv[i].uv_width=((ProgData *)pdata)->enc_data->yuv.uv_width; yuv[i].uv_height=((ProgData *)pdata)->enc_data->yuv.uv_height; - + yuv[i].y=(unsigned char *)malloc(yuv[i].y_width*yuv[i].y_height); yuv[i].u=(unsigned char *)malloc(yuv[i].uv_width*yuv[i].uv_height); yuv[i].v=(unsigned char *)malloc(yuv[i].uv_width*yuv[i].uv_height); } - + while(((ProgData *)pdata)->running){ int prev; @@ -118,9 +127,6 @@ void *CacheImageBuffer(void *pdata){ //release main buffer pthread_mutex_unlock(&((ProgData *)pdata)->yuv_mutex); //get checksums for new - MakeChecksums(yuv[current].y,yuv[current].y_width,yuv[current].y_height,divisor,checksums_y[current]); - MakeChecksums(yuv[current].u,yuv[current].uv_width,yuv[current].uv_height,divisor/2,checksums_u[current]); - MakeChecksums(yuv[current].v,yuv[current].uv_width,yuv[current].uv_height,divisor/2,checksums_v[current]); //find and flush different blocks if(firstrun){ @@ -141,29 +147,33 @@ void *CacheImageBuffer(void *pdata){ } else{ for(j=0;j<pow(divisor,2);j++){ - if(checksums_y[current][j]!=checksums_y[prev][j]){ + if(CompareBlocks(yuv[current].y,yuv[prev].y,j,yuv[current].y_width,yuv[current].y_height,divisor)){ ynum++; yblocks[ynum-1]=j; } } for(j=0;j<pow(divisor/2,2);j++){ - if(checksums_u[current][j]!=checksums_u[prev][j]){ + if(CompareBlocks(yuv[current].u,yuv[prev].u,j,yuv[current].uv_width,yuv[current].uv_height,divisor/2)){ unum++; ublocks[unum-1]=j; } - } + } for(j=0;j<pow(divisor/2,2);j++){ - if(checksums_v[current][j]!=checksums_v[prev][j]){ + if(CompareBlocks(yuv[current].v,yuv[prev].v,j,yuv[current].uv_width,yuv[current].uv_height,divisor/2)){ vnum++; vblocks[vnum-1]=j; } } + } /**WRITE FRAME TO DISK*/ - if(ynum+unum+vnum>(pow(divisor,2)+pow(divisor/2,2)*2)/10) - gzsetparams (fp,1,Z_FILTERED); - else - gzsetparams (fp,0,Z_FILTERED); + if(!((ProgData *)pdata)->args.zerocompression){ + if(ynum+unum+vnum>(pow(divisor,2)+pow(divisor/2,2)*2)/10) + 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; diff --git a/rMD-exp/src/load_cache.c b/rMD-exp/src/load_cache.c index 1c5b29a..9ef75a6 100644 --- a/rMD-exp/src/load_cache.c +++ b/rMD-exp/src/load_cache.c @@ -31,7 +31,7 @@ void LoadBlock(unsigned char *dest,unsigned char *source,int blockno,int width, 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], @@ -66,7 +66,7 @@ void *LoadCache(void *pdata){ thread_exit=-1; pthread_exit(&thread_exit); } - + if(!((ProgData *)pdata)->args.nosound){ afp=fopen(((ProgData *)pdata)->cache_data->audiodata,"rb"); if(afp==NULL){ @@ -74,26 +74,17 @@ void *LoadCache(void *pdata){ pthread_exit(&thread_exit); } } - //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); //this will be used now to define if we proccess audio or video - //on any given loop. + //on any given loop. ((ProgData *)pdata)->avd=0; //If sound finishes first,we go on with the video. //If video ends we will do one more run to flush audio in the ogg file - + while(((ProgData *)pdata)->running){ //video load and encoding if(((ProgData *)pdata)->avd<=0 || ((ProgData *)pdata)->args.nosound || audio_end){ @@ -103,7 +94,7 @@ void *LoadCache(void *pdata){ SyncEncodeImageBuffer((ProgData *)pdata); } else if(gzread(ifp,frame.header,sizeof(FrameHeader))==sizeof(FrameHeader)){ - //sync + //sync missing_frames+=frame.header->current_total-(extra_frames+frame.header->frameno); fprintf(stdout,"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" @@ -192,4 +183,4 @@ void *LoadCache(void *pdata){ } - + diff --git a/rMD-exp/src/parseargs.c b/rMD-exp/src/parseargs.c index 746df5c..a8ac033 100644 --- a/rMD-exp/src/parseargs.c +++ b/rMD-exp/src/parseargs.c @@ -36,7 +36,7 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ "\t -v_quality n| -s_quality n| -v_bitrate n| --no-framedrop| -dummy-cursor color|\n" "\t --no-cursor| -freq N(number>0)| -channels N(number>0)| -device SOUND_DEVICE|\n" "\t --nosound| --with-shared| --no-cond-shared| -shared-threshold n| --full-shots|\n" - "\t --quick-subsampling| -workdir DIR| -o filename]^filename\n\n\n" + "\t --quick-subsampling| -workdir DIR| --zero-compression| -o filename]^filename\n\n\n" "General Options:\n" "\t-h or --help\t\tPrint this help and exit.\n" @@ -73,6 +73,7 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ "\t-s_quality n\t\tDesired audio quality(-1 to 10).\n\n" "Misc Options:\n" + "\t--zero-compression\tImage data are always cached uncompressed.\n" "\t-workdir DIR\t\tLocation where a temporary directory will be created to hold project files(default $HOME).\n" "\t-delay n[H|h|M|m]\tNumber of secs(default),minutes or hours before capture starts(number can be float)\n" "\t-o filename\t\tName of recorded video(default out.ogg).\n" @@ -279,7 +280,7 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ return 1; } arg_return->have_dummy_cursor=1; - arg_return->xfixes_cursor=0; + arg_return->xfixes_cursor=0; } else{ fprintf(stderr,"Argument Usage: -dummy-cursor [black|white]\n"); @@ -397,6 +398,9 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ else if(!strcmp(argv[i],"--on-the-fly-encoding")){ arg_return->encOnTheFly=1; } + else if(!strcmp(argv[i],"--zero-compression")){ + arg_return->zerocompression=1; + } else if(!strcmp(argv[i],"--help")||!strcmp(argv[i],"-h")){ fprintf(stderr,"%s",usage); return 1; @@ -408,7 +412,7 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ else{ fprintf(stderr,"\n\tError parsing arguments.\n\tType --help or -h for usage.\n\n"); return 1; - } + } } return 0; } diff --git a/rMD-exp/src/rmd_cache.c b/rMD-exp/src/rmd_cache.c index bebd29e..9cb76d5 100644 --- a/rMD-exp/src/rmd_cache.c +++ b/rMD-exp/src/rmd_cache.c @@ -84,7 +84,7 @@ void InitCacheData(ProgData *pdata,EncData *enc_data_t,CacheData *cache_data_t){ fprintf(stderr,"Could not create temporary directory %s !!!\n",cache_data_t->projname); exit(13); } - cache_data_t->ifp=gzopen(cache_data_t->imgdata,"wb1f"); + cache_data_t->ifp=gzopen(cache_data_t->imgdata,"wb0f"); if(cache_data_t->ifp==NULL){ fprintf(stderr,"Could not create temporary file %s !!!\n",cache_data_t->imgdata); exit(13); @@ -96,7 +96,7 @@ void InitCacheData(ProgData *pdata,EncData *enc_data_t,CacheData *cache_data_t){ exit(13); } } - + } - + |