summaryrefslogtreecommitdiff
path: root/rMD-exp
diff options
context:
space:
mode:
authoriovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a>2006-10-29 01:36:39 +0000
committeriovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a>2006-10-29 01:36:39 +0000
commit3606df694f1ec074a4ca322a3c8e39e498960951 (patch)
tree2a32d9cb8568f03e3c95a1c6d15c7447fc597704 /rMD-exp
parent5076dbf5c8974316119d6bad42c413a3e3bf5ec9 (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.h43
-rw-r--r--rMD-exp/src/cache_frame.c74
-rw-r--r--rMD-exp/src/load_cache.c21
-rw-r--r--rMD-exp/src/parseargs.c10
-rw-r--r--rMD-exp/src/rmd_cache.c6
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);
}
}
-
+
}
-
+
© All Rights Reserved