summaryrefslogtreecommitdiff
path: root/recordmydesktop
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-06-19 03:47:43 -0700
committerVito Caputo <vcaputo@pengaru.com>2020-06-20 15:58:17 -0700
commit2e5fdc7f842eacce7b41eab794c4bfe97761e381 (patch)
tree4f11cd5aa2196a85c531c1eeb6c75ddb4b190465 /recordmydesktop
parentc903c20a8554bd5a56fbe95f6598662e9fc0d2b6 (diff)
*: just some fast and nasty reformatting
If I'm going to actually be modifying this program substantially and possibly maintaining some fork of it, it's gotta be formmatted how I prefer. This is by no means done or perfect, rmd_types.h in particular is quite the mess, I will be revisiting this issue...
Diffstat (limited to 'recordmydesktop')
-rw-r--r--recordmydesktop/src/rmd.c271
-rw-r--r--recordmydesktop/src/rmd_cache.c328
-rw-r--r--recordmydesktop/src/rmd_cache_audio.c122
-rw-r--r--recordmydesktop/src/rmd_cache_frame.c526
-rw-r--r--recordmydesktop/src/rmd_capture_sound.c227
-rw-r--r--recordmydesktop/src/rmd_encode_cache.c54
-rw-r--r--recordmydesktop/src/rmd_encode_image_buffer.c109
-rw-r--r--recordmydesktop/src/rmd_encode_sound_buffer.c273
-rw-r--r--recordmydesktop/src/rmd_error.c37
-rw-r--r--recordmydesktop/src/rmd_flush_to_ogg.c338
-rw-r--r--recordmydesktop/src/rmd_frame.c206
-rw-r--r--recordmydesktop/src/rmd_get_frame.c994
-rw-r--r--recordmydesktop/src/rmd_getzpixmap.c149
-rw-r--r--recordmydesktop/src/rmd_init_encoder.c608
-rw-r--r--recordmydesktop/src/rmd_initialize_data.c379
-rw-r--r--recordmydesktop/src/rmd_jack.c218
-rw-r--r--recordmydesktop/src/rmd_load_cache.c527
-rw-r--r--recordmydesktop/src/rmd_make_dummy_pointer.c113
-rw-r--r--recordmydesktop/src/rmd_math.c7
-rw-r--r--recordmydesktop/src/rmd_opendev.c265
-rw-r--r--recordmydesktop/src/rmd_parseargs.c875
-rw-r--r--recordmydesktop/src/rmd_poll_events.c240
-rw-r--r--recordmydesktop/src/rmd_queryextensions.c86
-rw-r--r--recordmydesktop/src/rmd_rectinsert.c846
-rw-r--r--recordmydesktop/src/rmd_register_callbacks.c68
-rw-r--r--recordmydesktop/src/rmd_rescue.c199
-rw-r--r--recordmydesktop/src/rmd_setbrwindow.c313
-rw-r--r--recordmydesktop/src/rmd_shortcuts.c216
-rw-r--r--recordmydesktop/src/rmd_specsfile.c244
-rw-r--r--recordmydesktop/src/rmd_threads.c225
-rw-r--r--recordmydesktop/src/rmd_timer.c83
-rw-r--r--recordmydesktop/src/rmd_types.h396
-rw-r--r--recordmydesktop/src/rmd_update_image.c93
-rw-r--r--recordmydesktop/src/rmd_wm_check.c71
-rw-r--r--recordmydesktop/src/rmd_wm_is_compositing.c40
-rw-r--r--recordmydesktop/src/rmd_yuv_utils.c47
-rw-r--r--recordmydesktop/src/rmd_yuv_utils.h32
37 files changed, 4805 insertions, 5020 deletions
diff --git a/recordmydesktop/src/rmd.c b/recordmydesktop/src/rmd.c
index 339244b..f7c806f 100644
--- a/recordmydesktop/src/rmd.c
+++ b/recordmydesktop/src/rmd.c
@@ -46,148 +46,139 @@
#include <string.h>
#include <errno.h>
-int main(int argc,char **argv){
- ProgData pdata;
- int exit_status = 0;
-
- rmdSetupDefaultArgs(&pdata.args);
-
- if (!rmdParseArgs(argc, argv, &pdata.args)) {
- exit(1);
- }
- if (pdata.args.rescue_path != NULL) {
- exit(rmdRescue(pdata.args.rescue_path));
- }
- if(XInitThreads ()==0){
- fprintf(stderr,"Couldn't initialize thread support!\n");
- exit(7);
- }
- if(pdata.args.display!=NULL){
- pdata.dpy = XOpenDisplay(pdata.args.display);
- XSetErrorHandler(rmdErrorHandler);
- }
- else{
- fprintf(stderr,"No display specified for connection!\n");
- exit(8);
- }
- if (pdata.dpy == NULL) {
- fprintf(stderr, "Cannot connect to X server %s\n",pdata.args.display);
- exit(9);
- }
- else{
- EncData enc_data;
- CacheData cache_data;
+int main(int argc, char **argv){
+ ProgData pdata;
+ EncData enc_data;
+ CacheData cache_data;
+ int exit_status = 0;
+
#ifdef HAVE_LIBJACK
- JackData jdata;
+ JackData jdata;
- // Give jack access to program data, mainly for program state
- jdata.pdata = &pdata;
- pdata.jdata = &jdata;
+ // Give jack access to program data, mainly for program state
+ jdata.pdata = &pdata;
+ pdata.jdata = &jdata;
#endif
- // Query display specs
- pdata.specs.screen = DefaultScreen(pdata.dpy);
- pdata.specs.width = DisplayWidth(pdata.dpy, pdata.specs.screen);
- pdata.specs.height = DisplayHeight(pdata.dpy, pdata.specs.screen);
- pdata.specs.root = RootWindow(pdata.dpy, pdata.specs.screen);
- pdata.specs.visual = DefaultVisual(pdata.dpy, pdata.specs.screen);
- pdata.specs.gc = DefaultGC(pdata.dpy, pdata.specs.screen);
- pdata.specs.depth = DefaultDepth(pdata.dpy, pdata.specs.screen);
-
- if((pdata.specs.depth!=32)&&
- (pdata.specs.depth!=24)&&
- (pdata.specs.depth!=16)){
- fprintf(stderr,"Only 32bpp,24bpp and 16bpp"
- " color depth modes are currently supported.\n");
- exit(10);
- }
- if (!rmdSetBRWindow(pdata.dpy, &pdata.brwin, &pdata.specs, &pdata.args))
- exit(11);
-
- if( !pdata.args.nowmcheck &&
- rmdWMIsCompositing( pdata.dpy, pdata.specs.screen ) ) {
-
- fprintf(stderr,"\nDetected compositing window manager.\n"
- "Reverting to full screen capture at every frame.\n"
- "To disable this check run with --no-wm-check\n"
- "(though that is not advised, since it will "
- "probably produce faulty results).\n\n");
- pdata.args.full_shots=1;
- pdata.args.noshared=0;
-
- }
-
- rmdQueryExtensions(pdata.dpy,
- &pdata.args,
- &pdata.damage_event,
- &pdata.damage_error,
- &pdata.shm_opcode);
-
-
- if((exit_status=rmdInitializeData(&pdata,&enc_data,&cache_data))==0){
-
- if(!strcmp(pdata.args.pause_shortcut,
- pdata.args.stop_shortcut)||
- rmdRegisterShortcut(pdata.dpy,
- pdata.specs.root,
- pdata.args.pause_shortcut,
- &(pdata.pause_key)) ||
- rmdRegisterShortcut(pdata.dpy,
- pdata.specs.root,
- pdata.args.stop_shortcut,
- &(pdata.stop_key))){
-
- fprintf(stderr,"Invalid shortcut,"
- " or shortcuts are the same!\n\n"
- "Using defaults.\n");
-
- rmdRegisterShortcut(pdata.dpy,
- pdata.specs.root,
- "Control+Mod1+p",
- &(pdata.pause_key));
- rmdRegisterShortcut(pdata.dpy,
- pdata.specs.root,
- "Control+Mod1+s",
- &(pdata.stop_key));
- }
-
- //this is where the capturing happens.
- rmdThreads(&pdata);
-
- XCloseDisplay(pdata.dpy);
- fprintf(stderr,".\n");
-
- //encode and then cleanup cache
- if(!pdata.args.encOnTheFly && !pdata.args.no_encode){
- if (!pdata.aborted) {
- rmdEncodeCache(&pdata);
- }
- fprintf(stderr,"Cleanning up cache...\n");
- if(rmdPurgeCache(pdata.cache_data,!pdata.args.nosound))
- fprintf(stderr,"Some error occured "
- "while cleaning up cache!\n");
- fprintf(stderr,"Done!!!\n");
- }
-
-
- if (pdata.aborted && pdata.args.encOnTheFly) {
- if(remove(pdata.args.filename)){
- perror("Error while removing file:\n");
- return 1;
- }
- else{
- fprintf(stderr,"SIGABRT received,file %s removed\n",
- pdata.args.filename);
- return 0;
- }
- }
- else
- fprintf(stderr,"Goodbye!\n");
-
-
- rmdCleanUp();
- }
- }
-
- return exit_status;
+ rmdSetupDefaultArgs(&pdata.args);
+
+ if (!rmdParseArgs(argc, argv, &pdata.args))
+ exit(1);
+
+ if (pdata.args.rescue_path != NULL)
+ exit(rmdRescue(pdata.args.rescue_path));
+
+ if (XInitThreads()==0) {
+ fprintf(stderr, "Couldn't initialize thread support!\n");
+ exit(7);
+ }
+
+ if (pdata.args.display != NULL) {
+ pdata.dpy = XOpenDisplay(pdata.args.display);
+ XSetErrorHandler(rmdErrorHandler);
+ } else {
+ fprintf(stderr, "No display specified for connection!\n");
+ exit(8);
+ }
+
+ if (pdata.dpy == NULL) {
+ fprintf(stderr, "Cannot connect to X server %s\n", pdata.args.display);
+ exit(9);
+ }
+
+ // Query display specs
+ pdata.specs.screen = DefaultScreen(pdata.dpy);
+ pdata.specs.width = DisplayWidth(pdata.dpy, pdata.specs.screen);
+ pdata.specs.height = DisplayHeight(pdata.dpy, pdata.specs.screen);
+ pdata.specs.root = RootWindow(pdata.dpy, pdata.specs.screen);
+ pdata.specs.visual = DefaultVisual(pdata.dpy, pdata.specs.screen);
+ pdata.specs.gc = DefaultGC(pdata.dpy, pdata.specs.screen);
+ pdata.specs.depth = DefaultDepth(pdata.dpy, pdata.specs.screen);
+
+ if (pdata.specs.depth != 32 && pdata.specs.depth != 24 && pdata.specs.depth != 16) {
+ fprintf(stderr,
+ "Only 32bpp, 24bpp, and 16bpp"
+ " color depth modes are currently supported.\n");
+ exit(10);
+ }
+
+ if (!rmdSetBRWindow(pdata.dpy, &pdata.brwin, &pdata.specs, &pdata.args))
+ exit(11);
+
+ if (!pdata.args.nowmcheck && rmdWMIsCompositing( pdata.dpy, pdata.specs.screen ) ) {
+
+ fprintf(stderr, "\nDetected compositing window manager.\n"
+ "Reverting to full screen capture at every frame.\n"
+ "To disable this check run with --no-wm-check\n"
+ "(though that is not advised, since it will "
+ "probably produce faulty results).\n\n");
+ pdata.args.full_shots=1;
+ pdata.args.noshared=0;
+ }
+
+ rmdQueryExtensions( pdata.dpy,
+ &pdata.args,
+ &pdata.damage_event,
+ &pdata.damage_error,
+ &pdata.shm_opcode);
+
+ exit_status = rmdInitializeData(&pdata, &enc_data, &cache_data);
+ if (exit_status)
+ exit(exit_status);
+
+ if ( !strcmp(pdata.args.pause_shortcut, pdata.args.stop_shortcut) ||
+ rmdRegisterShortcut( pdata.dpy, pdata.specs.root,
+ pdata.args.pause_shortcut,
+ &(pdata.pause_key)) ||
+ rmdRegisterShortcut( pdata.dpy,
+ pdata.specs.root,
+ pdata.args.stop_shortcut,
+ &(pdata.stop_key))) {
+
+ fprintf(stderr, "Invalid shortcut, or shortcuts are the same!\n\nUsing defaults.\n");
+
+ rmdRegisterShortcut( pdata.dpy,
+ pdata.specs.root,
+ "Control+Mod1+p",
+ &(pdata.pause_key));
+
+ rmdRegisterShortcut( pdata.dpy,
+ pdata.specs.root,
+ "Control+Mod1+s",
+ &(pdata.stop_key));
+ }
+
+ //this is where the capturing happens.
+ rmdThreads(&pdata);
+
+ XCloseDisplay(pdata.dpy);
+ fprintf(stderr, ".\n");
+
+ //encode and then cleanup cache
+ if (!pdata.args.encOnTheFly && !pdata.args.no_encode) {
+ if (!pdata.aborted)
+ rmdEncodeCache(&pdata);
+
+ fprintf(stderr,"Cleanning up cache...\n");
+ if (rmdPurgeCache(pdata.cache_data,!pdata.args.nosound))
+ fprintf(stderr,"Some error occured while cleaning up cache!\n");
+
+ fprintf(stderr,"Done!!!\n");
+ }
+
+ if (pdata.aborted && pdata.args.encOnTheFly) {
+ if (remove(pdata.args.filename)) {
+ perror("Error while removing file:\n");
+ return 1;
+ } else {
+ fprintf(stderr, "SIGABRT received,file %s removed\n",
+ pdata.args.filename);
+ return 0;
+ }
+ } else
+ fprintf(stderr,"Goodbye!\n");
+
+ rmdCleanUp();
+
+ return exit_status;
}
diff --git a/recordmydesktop/src/rmd_cache.c b/recordmydesktop/src/rmd_cache.c
index 61111b7..22c7200 100644
--- a/recordmydesktop/src/rmd_cache.c
+++ b/recordmydesktop/src/rmd_cache.c
@@ -49,180 +49,176 @@
*
*/
static void rmdCacheFileN(char *name, char **newname, int n) { // Nth cache file
- char numbuf[8];
- strcpy(*newname,name);
- strcat(*newname,".");
- snprintf( numbuf, 8, "%d", n );
- strcat(*newname,numbuf);
-}
+ char numbuf[8];
-int rmdSwapCacheFilesWrite(char *name,int n,gzFile **fp,FILE **ucfp){
- char *newname=malloc(strlen(name)+10);
- rmdCacheFileN(name,&newname,n);
- if(*fp==NULL){
- fflush(*ucfp);
- fclose(*ucfp);
- *ucfp=fopen(newname,"wb");
- }
- else{
- gzflush(*fp,Z_FINISH);
- gzclose(*fp);
- *fp=gzopen(newname,"wb0f");
- }
- free(newname);
- return ((*fp==NULL)&&(*ucfp==NULL));
+ strcpy(*newname, name);
+ strcat(*newname, ".");
+ snprintf(numbuf, 8, "%d", n);
+ strcat(*newname, numbuf);
}
-int rmdSwapCacheFilesRead(char *name,int n,gzFile **fp,FILE **ucfp){
- char *newname=malloc(strlen(name)+10);
- rmdCacheFileN(name,&newname,n);
- if(*fp==NULL){
- fclose(*ucfp);
- *ucfp=fopen(newname,"rb");
- }
- else{
-
- gzclose(*fp);
- *fp=gzopen(newname,"rb");
- }
- free(newname);
- return ((*fp==NULL)&&(*ucfp==NULL));
+int rmdSwapCacheFilesWrite(char *name, int n, gzFile **fp, FILE **ucfp) {
+ char *newname = malloc(strlen(name) + 10);
+
+ rmdCacheFileN(name, &newname, n);
+ if (*fp == NULL) {
+ fflush(*ucfp);
+ fclose(*ucfp);
+ *ucfp = fopen(newname, "wb");
+ } else {
+ gzflush(*fp, Z_FINISH);
+ gzclose(*fp);
+ *fp = gzopen(newname, "wb0f");
+ }
+ free(newname);
+
+ return ((*fp == NULL) && (*ucfp == NULL));
}
-int rmdPurgeCache(CacheData *cache_data_t,int sound){
- struct stat buff;
- char *fname;
- fname=malloc(strlen(cache_data_t->imgdata)+10);
- strcpy(fname,cache_data_t->imgdata);
- int exit_value=0;
- int nth_cache=1;
-
- while (stat(fname,&buff)==0){
- if(remove(fname)){
- fprintf(stderr,"Couldn't remove temporary file %s",
- cache_data_t->imgdata);
- exit_value=1;
- }
- rmdCacheFileN(cache_data_t->imgdata,&fname,nth_cache);
- nth_cache++;
- }
- free(fname);
- if(sound){
- if(remove(cache_data_t->audiodata)){
- fprintf(stderr,"Couldn't remove temporary file %s",
- cache_data_t->audiodata);
- exit_value=1;
- }
- }
- if(remove(cache_data_t->specsfile)){
- fprintf(stderr,"Couldn't remove temporary file %s",
- cache_data_t->specsfile);
- exit_value=1;
- }
- if(remove(cache_data_t->projname)){
- fprintf(stderr,"Couldn't remove temporary directory %s",
- cache_data_t->projname);
- exit_value=1;
- }
- return exit_value;
+int rmdSwapCacheFilesRead(char *name, int n, gzFile **fp, FILE **ucfp) {
+ char *newname = malloc(strlen(name) + 10);
+
+ rmdCacheFileN(name, &newname, n);
+ if (*fp == NULL) {
+ fclose(*ucfp);
+ *ucfp = fopen(newname, "rb");
+ } else {
+ gzclose(*fp);
+ *fp = gzopen(newname, "rb");
+ }
+ free(newname);
+
+ return ((*fp == NULL) && (*ucfp == NULL));
}
-void rmdInitCacheData(ProgData *pdata,
- EncData *enc_data_t,
- CacheData *cache_data_t){
- int width,height,offset_x,offset_y,pid;
- char pidbuf[8];
-
- //we set the buffer only since there's
- //no need to initialize the encoder from now.
- width=((pdata->brwin.rrect.width + 15) >>4)<<4;
- height=((pdata->brwin.rrect.height + 15) >>4)<<4;
- offset_x=((width-pdata->brwin.rrect.width)/2)&~1;
- offset_y=((height-pdata->brwin.rrect.height)/2)&~1;
-
- (pdata)->enc_data=enc_data_t;
-
- enc_data_t->yuv.y=(unsigned char *)malloc(height*width);
- enc_data_t->yuv.u=(unsigned char *)malloc(height*width/4);
- enc_data_t->yuv.v=(unsigned char *)malloc(height*width/4);
- enc_data_t->yuv.y_width=width;
- enc_data_t->yuv.y_height=height;
- enc_data_t->yuv.y_stride=width;
-
- enc_data_t->yuv.uv_width=width/2;
- enc_data_t->yuv.uv_height=height/2;
- enc_data_t->yuv.uv_stride=width/2;
- enc_data_t->x_offset=offset_x;
- enc_data_t->y_offset=offset_y;
-
-
- //now we set the cache files
- (pdata)->cache_data=cache_data_t;
-
- cache_data_t->workdir=(pdata->args).workdir;
- pid=getpid();
-
- snprintf( pidbuf, 8, "%d", pid );
- //names are stored relatively to current dir(i.e. no chdir)
- cache_data_t->projname=malloc(strlen(cache_data_t->workdir)+
- 12+strlen(pidbuf)+3);
- //projname
- strcpy(cache_data_t->projname,cache_data_t->workdir);
- strcat(cache_data_t->projname,"/");
- strcat(cache_data_t->projname,"rMD-session-");
- strcat(cache_data_t->projname,pidbuf);
- strcat(cache_data_t->projname,"/");
- //image data
- cache_data_t->imgdata=malloc(strlen(cache_data_t->projname)+11);
- strcpy(cache_data_t->imgdata,cache_data_t->projname);
- strcat(cache_data_t->imgdata,"img.out");
- //audio data
- cache_data_t->audiodata=malloc(strlen(cache_data_t->projname)+10);
- strcpy(cache_data_t->audiodata,cache_data_t->projname);
- strcat(cache_data_t->audiodata,"audio.pcm");
- //specsfile
- cache_data_t->specsfile=malloc(strlen(cache_data_t->projname)+10);
- strcpy(cache_data_t->specsfile,cache_data_t->projname);
- strcat(cache_data_t->specsfile,"specs.txt");
-
- //now that've got out buffers and our filenames we start
- //creating the needed files
-
- if(mkdir(cache_data_t->projname,0777)){
- fprintf(stderr,"Could not create temporary directory %s !!!\n",
- cache_data_t->projname);
- exit(13);
- }
- if(!pdata->args.zerocompression){
- 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);
- }
- }
- else{
- cache_data_t->uncifp=fopen(cache_data_t->imgdata,"wb0f");
- if(cache_data_t->uncifp==NULL){
- fprintf(stderr,"Could not create temporary file %s !!!\n",
- cache_data_t->imgdata);
- exit(13);
- }
- }
- if(!pdata->args.nosound){
- cache_data_t->afp=fopen(cache_data_t->audiodata,"wb");
- if(cache_data_t->afp==NULL){
- fprintf(stderr,"Could not create temporary file %s !!!\n",
- cache_data_t->audiodata);
- exit(13);
- }
- }
- if(rmdWriteSpecsFile(pdata)){
- fprintf(stderr,"Could not write specsfile %s !!!\n",
- cache_data_t->specsfile);
- exit(13);
- }
+int rmdPurgeCache(CacheData *cache_data_t, int sound) {
+ struct stat buff;
+ char *fname;
+ int exit_value = 0;
+ int nth_cache = 1;
+
+ fname = malloc(strlen(cache_data_t->imgdata) + 10);
+ strcpy(fname, cache_data_t->imgdata);
+
+ while (stat(fname, &buff) == 0) {
+ if (remove(fname)) {
+ fprintf(stderr, "Couldn't remove temporary file %s", cache_data_t->imgdata);
+ exit_value = 1;
+ }
+ rmdCacheFileN(cache_data_t->imgdata, &fname, nth_cache);
+ nth_cache++;
+ }
+
+ free(fname);
+
+ if (sound) {
+ if (remove(cache_data_t->audiodata)) {
+ fprintf(stderr, "Couldn't remove temporary file %s", cache_data_t->audiodata);
+ exit_value = 1;
+ }
+ }
+
+ if (remove(cache_data_t->specsfile)) {
+ fprintf(stderr, "Couldn't remove temporary file %s", cache_data_t->specsfile);
+ exit_value = 1;
+ }
+
+ if (remove(cache_data_t->projname)) {
+ fprintf(stderr, "Couldn't remove temporary directory %s", cache_data_t->projname);
+ exit_value = 1;
+ }
+
+ return exit_value;
+}
+void rmdInitCacheData(ProgData *pdata, EncData *enc_data_t, CacheData *cache_data_t) {
+ int width, height, offset_x, offset_y, pid;
+ char pidbuf[8];
+
+ //we set the buffer only since there's
+ //no need to initialize the encoder from now.
+ width = ((pdata->brwin.rrect.width + 15) >>4)<<4;
+ height = ((pdata->brwin.rrect.height + 15) >>4)<<4;
+ offset_x = ((width-pdata->brwin.rrect.width)/2)&~1;
+ offset_y = ((height-pdata->brwin.rrect.height)/2)&~1;
+
+ (pdata)->enc_data = enc_data_t;
+
+ enc_data_t->yuv.y = (unsigned char *)malloc(height*width);
+ enc_data_t->yuv.u = (unsigned char *)malloc(height*width/4);
+ enc_data_t->yuv.v = (unsigned char *)malloc(height*width/4);
+ enc_data_t->yuv.y_width = width;
+ enc_data_t->yuv.y_height = height;
+ enc_data_t->yuv.y_stride = width;
+
+ enc_data_t->yuv.uv_width = width/2;
+ enc_data_t->yuv.uv_height = height/2;
+ enc_data_t->yuv.uv_stride = width/2;
+ enc_data_t->x_offset = offset_x;
+ enc_data_t->y_offset = offset_y;
+
+ //now we set the cache files
+ (pdata)->cache_data = cache_data_t;
+
+ cache_data_t->workdir = (pdata->args).workdir;
+ pid = getpid();
+
+ snprintf( pidbuf, 8, "%d", pid );
+ //names are stored relatively to current dir(i.e. no chdir)
+ cache_data_t->projname = malloc(strlen(cache_data_t->workdir) + 12 + strlen(pidbuf) + 3);
+ //projname
+ strcpy(cache_data_t->projname, cache_data_t->workdir);
+ strcat(cache_data_t->projname, "/");
+ strcat(cache_data_t->projname, "rMD-session-");
+ strcat(cache_data_t->projname, pidbuf);
+ strcat(cache_data_t->projname, "/");
+ //image data
+ cache_data_t->imgdata = malloc(strlen(cache_data_t->projname) + 11);
+ strcpy(cache_data_t->imgdata, cache_data_t->projname);
+ strcat(cache_data_t->imgdata, "img.out");
+ //audio data
+ cache_data_t->audiodata = malloc(strlen(cache_data_t->projname) + 10);
+ strcpy(cache_data_t->audiodata, cache_data_t->projname);
+ strcat(cache_data_t->audiodata, "audio.pcm");
+ //specsfile
+ cache_data_t->specsfile = malloc(strlen(cache_data_t->projname) + 10);
+ strcpy(cache_data_t->specsfile, cache_data_t->projname);
+ strcat(cache_data_t->specsfile, "specs.txt");
+
+ //now that've got out buffers and our filenames we start
+ //creating the needed files
+
+ if (mkdir(cache_data_t->projname, 0777)) {
+ fprintf(stderr, "Could not create temporary directory %s !!!\n", cache_data_t->projname);
+ exit(13);
+ }
+
+ if (!pdata->args.zerocompression) {
+ 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);
+ }
+ } else {
+ cache_data_t->uncifp = fopen(cache_data_t->imgdata, "wb0f");
+ if (cache_data_t->uncifp == NULL) {
+ fprintf(stderr, "Could not create temporary file %s !!!\n", cache_data_t->imgdata);
+ exit(13);
+ }
+ }
+
+ if (!pdata->args.nosound) {
+ cache_data_t->afp = fopen(cache_data_t->audiodata, "wb");
+ if (cache_data_t->afp == NULL) {
+ fprintf(stderr, "Could not create temporary file %s !!!\n", cache_data_t->audiodata);
+ exit(13);
+ }
+ }
+
+ if (rmdWriteSpecsFile(pdata)) {
+ fprintf(stderr, "Could not write specsfile %s !!!\n", cache_data_t->specsfile);
+ exit(13);
+ }
}
diff --git a/recordmydesktop/src/rmd_cache_audio.c b/recordmydesktop/src/rmd_cache_audio.c
index aad5496..042c734 100644
--- a/recordmydesktop/src/rmd_cache_audio.c
+++ b/recordmydesktop/src/rmd_cache_audio.c
@@ -38,75 +38,73 @@
-void *rmdCacheSoundBuffer(ProgData *pdata){
+void *rmdCacheSoundBuffer(ProgData *pdata) {
+ size_t write_size = pdata->periodsize * pdata->sound_framesize;
+
+#ifdef HAVE_LIBJACK
+ if (pdata->args.use_jack)
+ write_size = pdata->sound_framesize * pdata->jdata->buffersize;
+#endif
+
//We are simply going to throw sound on the disk.
//It's sound is tiny compared to that of image, so
//compressing would reducethe overall size by only an
//insignificant fraction.
+
#ifdef HAVE_LIBJACK
- void *jackbuf=NULL;
- if(pdata->args.use_jack){
- jackbuf=malloc(pdata->sound_framesize*pdata->jdata->buffersize);
- }
+ void *jackbuf = NULL;
+ if (pdata->args.use_jack)
+ jackbuf=malloc(pdata->sound_framesize * pdata->jdata->buffersize);
#endif
- while((pdata->running)){
- SndBuffer *buff=NULL;
-
- if (pdata->paused) {
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
- }
- if(!pdata->args.use_jack){
- if(pdata->sound_buffer==NULL){
- pdata->v_enc_thread_waiting=1;
- pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
- pthread_cond_wait(&pdata->sound_data_read,
- &pdata->snd_buff_ready_mutex);
- pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
- pdata->v_enc_thread_waiting=0;
- }
- if(pdata->sound_buffer==NULL || !pdata->running){
- break;
- }
- pthread_mutex_lock(&pdata->sound_buffer_mutex);
- buff=pdata->sound_buffer;
- //advance the list
- pdata->sound_buffer=pdata->sound_buffer->next;
- pthread_mutex_unlock(&pdata->sound_buffer_mutex);
- fwrite(buff->data,1,pdata->periodsize*pdata->sound_framesize,
- pdata->cache_data->afp);
- free(buff->data);
- free(buff);
- }
- else{
+
+ while (pdata->running) {
+ SndBuffer *buff = NULL;
+
+ if (pdata->paused) {
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ }
+
+ if (!pdata->args.use_jack) {
+ if (pdata->sound_buffer == NULL) {
+ pdata->v_enc_thread_waiting = 1;
+ pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
+ pthread_cond_wait(&pdata->sound_data_read, &pdata->snd_buff_ready_mutex);
+ pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
+ pdata->v_enc_thread_waiting = 0;
+ }
+
+ if (pdata->sound_buffer == NULL || !pdata->running)
+ break;
+
+ pthread_mutex_lock(&pdata->sound_buffer_mutex);
+ buff = pdata->sound_buffer;
+ //advance the list
+ pdata->sound_buffer = pdata->sound_buffer->next;
+ pthread_mutex_unlock(&pdata->sound_buffer_mutex);
+ fwrite(buff->data, 1, write_size, pdata->cache_data->afp);
+ free(buff->data);
+ free(buff);
+ } else {
#ifdef HAVE_LIBJACK
- if((*jack_ringbuffer_read_space)(pdata->jdata->sound_buffer)>=
- (pdata->sound_framesize*pdata->jdata->buffersize)){
- (*jack_ringbuffer_read)(pdata->jdata->sound_buffer,
- jackbuf,
- (pdata->sound_framesize*
- pdata->jdata->buffersize));
- fwrite(jackbuf,1,(pdata->sound_framesize*
- pdata->jdata->buffersize),
- pdata->cache_data->afp);
- }
- else{
- pdata->v_enc_thread_waiting=1;
- pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
- pthread_cond_wait(&pdata->sound_data_read,
- &pdata->snd_buff_ready_mutex);
- pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
- pdata->v_enc_thread_waiting=0;
- continue;
- }
+ if ((*jack_ringbuffer_read_space)(pdata->jdata->sound_buffer) >= write_size) {
+ (*jack_ringbuffer_read)(pdata->jdata->sound_buffer, jackbuf, write_size);
+ fwrite(jackbuf, 1, write_size, pdata->cache_data->afp);
+ } else {
+ pdata->v_enc_thread_waiting=1;
+ pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
+ pthread_cond_wait(&pdata->sound_data_read, &pdata->snd_buff_ready_mutex);
+ pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
+ pdata->v_enc_thread_waiting=0;
+
+ continue;
+ }
#endif
- }
- pdata->avd-=pdata->periodtime;
- }
+ }
+ pdata->avd-=pdata->periodtime;
+ }
- fclose(pdata->cache_data->afp);
- pthread_exit(&errno);
+ fclose(pdata->cache_data->afp);
+ pthread_exit(&errno);
}
-
-
diff --git a/recordmydesktop/src/rmd_cache_frame.c b/recordmydesktop/src/rmd_cache_frame.c
index 18ae934..3c4c219 100644
--- a/recordmydesktop/src/rmd_cache_frame.c
+++ b/recordmydesktop/src/rmd_cache_frame.c
@@ -44,266 +44,272 @@
#define CACHE_FILE_SIZE_LIMIT (500 * 1024 * 1024)
-static int rmdFlushBlock(unsigned char *buf,
- int blockno,
- int width,
- int height,
- int blockwidth,
- gzFile *fp,
- FILE *ucfp,
- int flush) {
- int j,i,
- bytes_written=0,
- block_i=(!blockwidth)?0:(blockno/(width/blockwidth)),//place on the grid
- block_k=(!blockwidth)?0:(blockno%(width/blockwidth));
- register unsigned char *buf_reg=(&buf[(block_i*
- width+
- block_k)*blockwidth]);
- static unsigned char out_buffer[CACHE_OUT_BUFFER_SIZE];
- static unsigned int out_buffer_bytes=0;
-
- if(out_buffer_bytes+pow(blockwidth,2)>=CACHE_OUT_BUFFER_SIZE ||
- (flush && out_buffer_bytes)){
- if(ucfp==NULL)
- gzwrite(fp,(void *)out_buffer,out_buffer_bytes);
- else
- fwrite((void *)out_buffer,1,out_buffer_bytes,ucfp);
- bytes_written=out_buffer_bytes;
- out_buffer_bytes=0;
- }
- if(!flush){
- register unsigned char *out_buf_reg=&out_buffer[out_buffer_bytes];
- for(j=0;j<blockwidth;j++){
- for(i=0;i<blockwidth;i++)
- (*out_buf_reg++)=(*buf_reg++);
- out_buffer_bytes+=blockwidth;
- buf_reg+=width-blockwidth;
- }
- }
-
- return bytes_written;
+static int rmdFlushBlock(
+ unsigned char *buf,
+ int blockno,
+ int width,
+ int height,
+ int blockwidth,
+ gzFile *fp,
+ FILE *ucfp,
+ int flush) {
+
+ int j,i,
+ bytes_written=0,
+ block_i=(!blockwidth)?0:(blockno/(width/blockwidth)),//place on the grid
+ block_k=(!blockwidth)?0:(blockno%(width/blockwidth));
+ register unsigned char *buf_reg = (&buf[(block_i * width + block_k) * blockwidth]);
+ static unsigned char out_buffer[CACHE_OUT_BUFFER_SIZE];
+ static unsigned int out_buffer_bytes=0;
+
+ if (out_buffer_bytes+pow(blockwidth,2)>=CACHE_OUT_BUFFER_SIZE || (flush && out_buffer_bytes)) {
+ if (ucfp==NULL)
+ gzwrite(fp,(void *)out_buffer,out_buffer_bytes);
+ else
+ fwrite((void *)out_buffer,1,out_buffer_bytes,ucfp);
+
+ bytes_written=out_buffer_bytes;
+ out_buffer_bytes=0;
+ }
+ if (!flush) {
+ register unsigned char *out_buf_reg=&out_buffer[out_buffer_bytes];
+
+ for(j=0;j<blockwidth;j++) {
+
+ for(i=0;i<blockwidth;i++)
+ (*out_buf_reg++)=(*buf_reg++);
+
+ out_buffer_bytes+=blockwidth;
+ buf_reg+=width-blockwidth;
+ }
+ }
+
+ return bytes_written;
}
-void *rmdCacheImageBuffer(ProgData *pdata){
-
- gzFile *fp=NULL;
- FILE *ucfp=NULL;
- int index_entry_size=sizeof(u_int32_t),
- blocknum_x=pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
- blocknum_y=pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH,
- firstrun=1,
- frameno=0,
- nbytes=0,
- nth_cache=1;
- u_int32_t ynum,unum,vnum,
- y_short_blocks[blocknum_x*blocknum_y],
- u_short_blocks[blocknum_x*blocknum_y],
- v_short_blocks[blocknum_x*blocknum_y];
- unsigned long long int total_bytes = 0;
- unsigned long long int total_received_bytes = 0;
-
- if(!pdata->args.zerocompression){
- fp=pdata->cache_data->ifp;
- if(fp==NULL)exit(13);
- }
- else{
- ucfp=pdata->cache_data->uncifp;
- if(ucfp==NULL)exit(13);
- }
-
-
- while(pdata->running){
- int j;
- FrameHeader fheader;
- ynum=unum=vnum=0;
-
- pdata->th_enc_thread_waiting=1;
- pthread_mutex_lock(&pdata->img_buff_ready_mutex);
- pthread_cond_wait(&pdata->image_buffer_ready,
- &pdata->img_buff_ready_mutex);
- pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
- pdata->th_enc_thread_waiting=0;
-
- if (pdata->paused) {
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
- }
-
- pthread_mutex_lock(&pdata->yuv_mutex);
-
- //find and flush different blocks
- if(firstrun){
- firstrun=0;
- for(j=0;j<blocknum_x*blocknum_y;j++){
- ynum++;
- yblocks[ynum-1]=1;
- y_short_blocks[ynum-1]=j;
- unum++;
- ublocks[unum-1]=1;
- u_short_blocks[ynum-1]=j;
- vnum++;
- vblocks[vnum-1]=1;
- v_short_blocks[ynum-1]=j;
- }
- }
- else{
- /**COMPRESS ARRAYS*/
- for(j=0;j<blocknum_x*blocknum_y;j++){
- if(yblocks[j]){
- ynum++;
- y_short_blocks[ynum-1]=j;
- }
- if(ublocks[j]){
- unum++;
- u_short_blocks[unum-1]=j;
- }
- if(vblocks[j]){
- vnum++;
- v_short_blocks[vnum-1]=j;
- }
- }
- }
-
- /**WRITE FRAME TO DISK*/
- if(!pdata->args.zerocompression){
- if(ynum*4+unum+vnum>(blocknum_x*blocknum_y*6)/10)
- gzsetparams (fp,1,Z_FILTERED);
- else
- gzsetparams (fp,0,Z_FILTERED);
- }
-
- strncpy(fheader.frame_prefix,"FRAM",4);
- fheader.frameno=++frameno;
- fheader.current_total = pdata->frames_total;
-
- fheader.Ynum=ynum;
- fheader.Unum=unum;
- fheader.Vnum=vnum;
- if(!pdata->args.zerocompression){
- nbytes+=gzwrite(fp,(void*)&fheader,sizeof(FrameHeader));
- //flush indexes
- if(ynum)nbytes+=gzwrite(fp,
- (void*)y_short_blocks,
- ynum*index_entry_size);
- if(unum)nbytes+=gzwrite(fp,
- (void*)u_short_blocks,
- unum*index_entry_size);
- if(vnum)nbytes+=gzwrite(fp,
- (void*)v_short_blocks,
- vnum*index_entry_size);
- }
- else{
- nbytes+=sizeof(FrameHeader)*
- fwrite((void*)&fheader,sizeof(FrameHeader),1,ucfp);
- //flush indexes
- if(ynum)nbytes+=index_entry_size*
- fwrite(y_short_blocks,index_entry_size,ynum,ucfp);
- if(unum)nbytes+=index_entry_size*
- fwrite(u_short_blocks,index_entry_size,unum,ucfp);
- if(vnum)nbytes+=index_entry_size*
- fwrite(v_short_blocks,index_entry_size,vnum,ucfp);
- }
- //flush the blocks for each buffer
- if(ynum){
- for(j=0;j<ynum;j++)
- nbytes+=rmdFlushBlock(pdata->enc_data->yuv.y,y_short_blocks[j],
- pdata->enc_data->yuv.y_width,
- pdata->enc_data->yuv.y_height,
- Y_UNIT_WIDTH,
- fp,
- ucfp,
- 0);
- }
- if(unum){
- for(j=0;j<unum;j++)
- nbytes+=rmdFlushBlock(pdata->enc_data->yuv.u,u_short_blocks[j],
- pdata->enc_data->yuv.uv_width,
- pdata->enc_data->yuv.uv_height,
- UV_UNIT_WIDTH,
- fp,
- ucfp,
- 0);
- }
- if(vnum){
- for(j=0;j<vnum;j++)
- nbytes+=rmdFlushBlock(pdata->enc_data->yuv.v,v_short_blocks[j],
- pdata->enc_data->yuv.uv_width,
- pdata->enc_data->yuv.uv_height,
- UV_UNIT_WIDTH,
- fp,
- ucfp,
- 0);
- }
- //release main buffer
- pthread_mutex_unlock(&pdata->yuv_mutex);
-
- nbytes+=rmdFlushBlock(NULL,0,0,0,0,fp,ucfp,1);
- /**@________________@**/
- pdata->avd+=pdata->frametime;
- if(nbytes>CACHE_FILE_SIZE_LIMIT){
- if(rmdSwapCacheFilesWrite(pdata->cache_data->imgdata,
- nth_cache,&fp,&ucfp)){
- fprintf(stderr,"New cache file could not be created.\n"
- "Ending recording...\n");
- fflush(stderr);
- raise(SIGINT); //if for some reason we cannot make a new file
- //we have to stop. If we are out of space,
- //which means
- //that encoding cannot happen either,
- //InitEncoder will cause an abrupt end with an
- //error code and the cache will remain intact.
- //If we've chosen separate two-stages,
- //the program will make a
- //clean exit.
- //In either case data will be preserved so if
- //space is freed the recording
- //can be proccessed later.
- }
- total_bytes += nbytes;
- nth_cache++;
- nbytes=0;
- }
- }
- total_bytes += nbytes;
-
- {
- unsigned int bytes_per_pixel = pdata->specs.depth >= 24 ? 4 : 2;
- unsigned int pixels_per_frame = pdata->brwin.rrect.width * pdata->brwin.rrect.height;
-
- total_received_bytes = ((unsigned long long int)frameno) * bytes_per_pixel * pixels_per_frame;
- }
-
- if(total_received_bytes){
- double percent_of_data_left = (total_bytes / (double)total_received_bytes) * 100;
-
- fprintf(stderr,
- "\n"
- "*********************************************\n"
- "\n"
- "Cached %llu MB, from %llu MB that were received.\n"
- "Average cache compression ratio: %.1f %%\n"
- "\n"
- "*********************************************\n",
- total_bytes / BYTES_PER_MB,
- total_received_bytes / BYTES_PER_MB,
- 100 - percent_of_data_left);
-
- }
-
- fprintf(stderr,
- "Saved %d frames in a total of %d requests\n",
- frameno,
- pdata->frames_total);
- fflush(stderr);
-
- if(!pdata->args.zerocompression){
- gzflush(fp,Z_FINISH);
- gzclose(fp);
- }
- else{
- fflush(ucfp);
- fclose(ucfp);
- }
- pthread_exit(&errno);
+void *rmdCacheImageBuffer(ProgData *pdata) {
+
+ gzFile *fp=NULL;
+ FILE *ucfp=NULL;
+ int index_entry_size=sizeof(u_int32_t),
+ blocknum_x=pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
+ blocknum_y=pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH,
+ firstrun=1,
+ frameno=0,
+ nbytes=0,
+ nth_cache=1;
+ u_int32_t ynum,unum,vnum,
+ y_short_blocks[blocknum_x*blocknum_y],
+ u_short_blocks[blocknum_x*blocknum_y],
+ v_short_blocks[blocknum_x*blocknum_y];
+ unsigned long long int total_bytes = 0;
+ unsigned long long int total_received_bytes = 0;
+
+ if (!pdata->args.zerocompression) {
+ fp=pdata->cache_data->ifp;
+
+ if (fp==NULL)
+ exit(13);
+ } else {
+ ucfp=pdata->cache_data->uncifp;
+
+ if (ucfp==NULL)
+ exit(13);
+ }
+
+ while (pdata->running) {
+ int j;
+
+ FrameHeader fheader;
+ ynum=unum=vnum=0;
+
+ pdata->th_enc_thread_waiting=1;
+ pthread_mutex_lock(&pdata->img_buff_ready_mutex);
+ pthread_cond_wait(&pdata->image_buffer_ready, &pdata->img_buff_ready_mutex);
+ pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
+ pdata->th_enc_thread_waiting=0;
+
+ if (pdata->paused) {
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ }
+
+ pthread_mutex_lock(&pdata->yuv_mutex);
+
+ //find and flush different blocks
+ if (firstrun) {
+ firstrun=0;
+ for(j=0;j<blocknum_x*blocknum_y;j++) {
+ ynum++;
+ yblocks[ynum-1]=1;
+ y_short_blocks[ynum-1]=j;
+ unum++;
+ ublocks[unum-1]=1;
+ u_short_blocks[ynum-1]=j;
+ vnum++;
+ vblocks[vnum-1]=1;
+ v_short_blocks[ynum-1]=j;
+ }
+ } else {
+ /**COMPRESS ARRAYS*/
+ for(j=0;j<blocknum_x*blocknum_y;j++) {
+ if (yblocks[j]) {
+ ynum++;
+ y_short_blocks[ynum-1]=j;
+ }
+ if (ublocks[j]) {
+ unum++;
+ u_short_blocks[unum-1]=j;
+ }
+ if (vblocks[j]) {
+ vnum++;
+ v_short_blocks[vnum-1]=j;
+ }
+ }
+ }
+
+ /**WRITE FRAME TO DISK*/
+ if (!pdata->args.zerocompression) {
+ if (ynum*4+unum+vnum>(blocknum_x*blocknum_y*6)/10)
+ gzsetparams (fp,1,Z_FILTERED);
+ else
+ gzsetparams (fp,0,Z_FILTERED);
+ }
+
+ strncpy(fheader.frame_prefix,"FRAM",4);
+ fheader.frameno=++frameno;
+ fheader.current_total = pdata->frames_total;
+
+ fheader.Ynum=ynum;
+ fheader.Unum=unum;
+ fheader.Vnum=vnum;
+
+ if (!pdata->args.zerocompression) {
+ nbytes+=gzwrite(fp,(void*)&fheader,sizeof(FrameHeader));
+ //flush indexes
+ if (ynum)
+ nbytes+=gzwrite(fp, (void*)y_short_blocks, ynum*index_entry_size);
+
+ if (unum)
+ nbytes+=gzwrite(fp, (void*)u_short_blocks, unum*index_entry_size);
+
+ if (vnum)
+ nbytes+=gzwrite(fp, (void*)v_short_blocks, vnum*index_entry_size);
+ } else {
+ nbytes+=sizeof(FrameHeader)*
+ fwrite((void*)&fheader,sizeof(FrameHeader),1,ucfp);
+ //flush indexes
+ if (ynum)
+ nbytes+=index_entry_size* fwrite(y_short_blocks,index_entry_size,ynum,ucfp);
+
+ if (unum)
+ nbytes+=index_entry_size* fwrite(u_short_blocks,index_entry_size,unum,ucfp);
+
+ if (vnum)
+ nbytes+=index_entry_size* fwrite(v_short_blocks,index_entry_size,vnum,ucfp);
+ }
+ //flush the blocks for each buffer
+ if (ynum) {
+ for(j=0;j<ynum;j++)
+ nbytes+=rmdFlushBlock( pdata->enc_data->yuv.y,y_short_blocks[j],
+ pdata->enc_data->yuv.y_width,
+ pdata->enc_data->yuv.y_height,
+ Y_UNIT_WIDTH,
+ fp,
+ ucfp,
+ 0);
+ }
+
+ if (unum) {
+ for(j=0;j<unum;j++)
+ nbytes+=rmdFlushBlock( pdata->enc_data->yuv.u,u_short_blocks[j],
+ pdata->enc_data->yuv.uv_width,
+ pdata->enc_data->yuv.uv_height,
+ UV_UNIT_WIDTH,
+ fp,
+ ucfp,
+ 0);
+ }
+
+ if (vnum) {
+ for(j=0;j<vnum;j++)
+ nbytes+=rmdFlushBlock( pdata->enc_data->yuv.v,v_short_blocks[j],
+ pdata->enc_data->yuv.uv_width,
+ pdata->enc_data->yuv.uv_height,
+ UV_UNIT_WIDTH,
+ fp,
+ ucfp,
+ 0);
+ }
+
+ //release main buffer
+ pthread_mutex_unlock(&pdata->yuv_mutex);
+
+ nbytes+=rmdFlushBlock(NULL,0,0,0,0,fp,ucfp,1);
+ /**@________________@**/
+ pdata->avd+=pdata->frametime;
+
+ if (nbytes>CACHE_FILE_SIZE_LIMIT) {
+ if (rmdSwapCacheFilesWrite(pdata->cache_data->imgdata, nth_cache,&fp,&ucfp)) {
+ fprintf(stderr,"New cache file could not be created.\n"
+ "Ending recording...\n");
+ fflush(stderr);
+ raise(SIGINT); //if for some reason we cannot make a new file
+ //we have to stop. If we are out of space,
+ //which means
+ //that encoding cannot happen either,
+ //InitEncoder will cause an abrupt end with an
+ //error code and the cache will remain intact.
+ //If we've chosen separate two-stages,
+ //the program will make a
+ //clean exit.
+ //In either case data will be preserved so if
+ //space is freed the recording
+ //can be proccessed later.
+ }
+ total_bytes += nbytes;
+ nth_cache++;
+ nbytes=0;
+ }
+ }
+ total_bytes += nbytes;
+
+ {
+ unsigned int bytes_per_pixel = pdata->specs.depth >= 24 ? 4 : 2;
+ unsigned int pixels_per_frame = pdata->brwin.rrect.width * pdata->brwin.rrect.height;
+
+ total_received_bytes = ((unsigned long long int)frameno) * bytes_per_pixel * pixels_per_frame;
+ }
+
+ if (total_received_bytes) {
+ double percent_of_data_left = (total_bytes / (double)total_received_bytes) * 100;
+
+ fprintf(stderr, "\n"
+ "*********************************************\n"
+ "\n"
+ "Cached %llu MB, from %llu MB that were received.\n"
+ "Average cache compression ratio: %.1f %%\n"
+ "\n"
+ "*********************************************\n",
+ total_bytes / BYTES_PER_MB,
+ total_received_bytes / BYTES_PER_MB,
+ 100 - percent_of_data_left);
+
+ }
+
+ fprintf(stderr, "Saved %d frames in a total of %d requests\n",
+ frameno,
+ pdata->frames_total);
+ fflush(stderr);
+
+ if (!pdata->args.zerocompression) {
+ gzflush(fp,Z_FINISH);
+ gzclose(fp);
+ } else {
+ fflush(ucfp);
+ fclose(ucfp);
+ }
+
+ pthread_exit(&errno);
}
diff --git a/recordmydesktop/src/rmd_capture_sound.c b/recordmydesktop/src/rmd_capture_sound.c
index e4498c0..c1faa44 100644
--- a/recordmydesktop/src/rmd_capture_sound.c
+++ b/recordmydesktop/src/rmd_capture_sound.c
@@ -40,140 +40,135 @@
#include <stdlib.h>
-void *rmdCaptureSound(ProgData *pdata){
+void *rmdCaptureSound(ProgData *pdata) {
#ifdef HAVE_LIBASOUND
- int frames=pdata->periodsize;
+ int frames=pdata->periodsize;
#endif
- //start capturing only after first frame is taken
- usleep(pdata->frametime);
+ //start capturing only after first frame is taken
+ usleep(pdata->frametime);
- while(pdata->running){
- int sret=0;
- SndBuffer *newbuf,*tmp;
- if (pdata->paused) {
+ while (pdata->running) {
+ int sret=0;
+ SndBuffer *newbuf,*tmp;
+
+ if (pdata->paused) {
#ifdef HAVE_LIBASOUND
- if(!pdata->hard_pause){
- snd_pcm_pause(pdata->sound_handle,1);
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
- snd_pcm_pause(pdata->sound_handle,0);
- }
- else{//device doesn't support pause(is this the norm?mine doesn't)
- snd_pcm_close(pdata->sound_handle);
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
- pdata->sound_handle=
- rmdOpenDev(pdata->args.device,
- &pdata->args.channels,
- &pdata->args.frequency,
- &pdata->args.buffsize,
- NULL,
- NULL,
- NULL//let's hope that the device capabilities
- //didn't magically change
- );
- if(pdata->sound_handle==NULL){
- fprintf(stderr,"Couldn't reopen sound device.Exiting\n");
- pdata->running = FALSE;
- errno=3;
- pthread_exit(&errno);
- }
- }
+ if (!pdata->hard_pause) {
+ snd_pcm_pause(pdata->sound_handle,1);
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ snd_pcm_pause(pdata->sound_handle,0);
+ } else {//device doesn't support pause(is this the norm?mine doesn't)
+ snd_pcm_close(pdata->sound_handle);
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ pdata->sound_handle=
+ rmdOpenDev(pdata->args.device,
+ &pdata->args.channels,
+ &pdata->args.frequency,
+ &pdata->args.buffsize,
+ NULL,
+ NULL,
+ NULL//let's hope that the device capabilities
+ //didn't magically change
+ );
+ if (pdata->sound_handle==NULL) {
+ fprintf(stderr,"Couldn't reopen sound device.Exiting\n");
+ pdata->running = FALSE;
+ errno=3;
+ pthread_exit(&errno);
+ }
+ }
#else
- close(pdata->sound_handle);
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
- pdata->sound_handle=
- rmdOpenDev(pdata->args.device,
- pdata->args.channels,
- pdata->args.frequency);
- if(pdata->sound_handle<0){
- fprintf(stderr,"Couldn't reopen sound device.Exiting\n");
- pdata->running = FALSE;
- errno=3;
- pthread_exit(&errno);
- }
+ close(pdata->sound_handle);
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ pdata->sound_handle=
+ rmdOpenDev(pdata->args.device,
+ pdata->args.channels,
+ pdata->args.frequency);
+ if (pdata->sound_handle<0) {
+ fprintf(stderr,"Couldn't reopen sound device.Exiting\n");
+ pdata->running = FALSE;
+ errno=3;
+ pthread_exit(&errno);
+ }
#endif
- }
+ }
- //create new buffer
- newbuf=(SndBuffer *)malloc(sizeof(SndBuffer));
+ //create new buffer
+ newbuf=(SndBuffer *)malloc(sizeof(SndBuffer));
#ifdef HAVE_LIBASOUND
- newbuf->data=(signed char *)malloc(frames*pdata->sound_framesize);
+ newbuf->data=(signed char *)malloc(frames*pdata->sound_framesize);
#else
- newbuf->data=(signed char *)malloc(((pdata->args.buffsize<<1)*
- pdata->args.channels));
+ newbuf->data=(signed char *)malloc(((pdata->args.buffsize<<1)*
+ pdata->args.channels));
#endif
- newbuf->next=NULL;
+ newbuf->next=NULL;
- //read data into new buffer
+ //read data into new buffer
#ifdef HAVE_LIBASOUND
- while(sret<frames){
- int temp_sret=snd_pcm_readi(pdata->sound_handle,
- newbuf->data+pdata->sound_framesize*sret,
- frames-sret);
- if(temp_sret==-EPIPE){
- fprintf(stderr,"%s: Overrun occurred.\n",
- snd_strerror(temp_sret));
- snd_pcm_prepare(pdata->sound_handle);
- }
- else if (temp_sret<0){
- fprintf(stderr,"An error occured while reading sound data:\n"
- " %s\n",
- snd_strerror(temp_sret));
- snd_pcm_prepare(pdata->sound_handle);
- }
- else
- sret+=temp_sret;
- }
+ while (sret<frames) {
+ int temp_sret=snd_pcm_readi(pdata->sound_handle,
+ newbuf->data+pdata->sound_framesize*sret,
+ frames-sret);
+ if (temp_sret==-EPIPE) {
+ fprintf(stderr,"%s: Overrun occurred.\n",
+ snd_strerror(temp_sret));
+ snd_pcm_prepare(pdata->sound_handle);
+ } else if (temp_sret<0) {
+ fprintf(stderr,"An error occured while reading sound data:\n"
+ " %s\n",
+ snd_strerror(temp_sret));
+ snd_pcm_prepare(pdata->sound_handle);
+ } else
+ sret+=temp_sret;
+ }
#else
- sret=0;
- //oss recording loop
- do{
- int temp_sret=read(pdata->sound_handle,
- &newbuf->data[sret],
- ((pdata->args.buffsize<<1)*
- pdata->args.channels)-sret);
- if(temp_sret<0){
- fprintf(stderr,"An error occured while reading from soundcard"
- "%s\n"
- "Error description:\n"
- "%s\n",pdata->args.device,strerror(errno));
- }
- else
- sret+=temp_sret;
- }while(sret<((pdata->args.buffsize<<1)*
- pdata->args.channels));
+ sret=0;
+ //oss recording loop
+ do {
+ int temp_sret=read(pdata->sound_handle,
+ &newbuf->data[sret],
+ ((pdata->args.buffsize<<1)*
+ pdata->args.channels)-sret);
+ if (temp_sret<0) {
+ fprintf(stderr,"An error occured while reading from soundcard"
+ "%s\n"
+ "Error description:\n"
+ "%s\n",pdata->args.device,strerror(errno));
+ } else
+ sret+=temp_sret;
+ } while (sret<((pdata->args.buffsize<<1)*
+ pdata->args.channels));
#endif
- //queue the new buffer
- pthread_mutex_lock(&pdata->sound_buffer_mutex);
- tmp=pdata->sound_buffer;
- if(pdata->sound_buffer==NULL)
- pdata->sound_buffer=newbuf;
- else{
- while(tmp->next!=NULL)
- tmp=tmp->next;
- tmp->next=newbuf;
- }
- pthread_mutex_unlock(&pdata->sound_buffer_mutex);
+ //queue the new buffer
+ pthread_mutex_lock(&pdata->sound_buffer_mutex);
+ tmp=pdata->sound_buffer;
+ if (pdata->sound_buffer==NULL)
+ pdata->sound_buffer=newbuf;
+ else {
+ while (tmp->next!=NULL)
+ tmp=tmp->next;
+
+ tmp->next=newbuf;
+ }
+ pthread_mutex_unlock(&pdata->sound_buffer_mutex);
- //signal that there are data to be proccessed
- pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
- pthread_cond_signal(&pdata->sound_data_read);
- pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
- }
+ //signal that there are data to be proccessed
+ pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
+ pthread_cond_signal(&pdata->sound_data_read);
+ pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
+ }
#ifdef HAVE_LIBASOUND
- snd_pcm_close(pdata->sound_handle);
+ snd_pcm_close(pdata->sound_handle);
#else
- close(pdata->sound_handle);
+ close(pdata->sound_handle);
#endif
- pthread_exit(&errno);
+ pthread_exit(&errno);
}
-
-
-
diff --git a/recordmydesktop/src/rmd_encode_cache.c b/recordmydesktop/src/rmd_encode_cache.c
index adf6063..fdcb782 100644
--- a/recordmydesktop/src/rmd_encode_cache.c
+++ b/recordmydesktop/src/rmd_encode_cache.c
@@ -40,35 +40,33 @@
void rmdEncodeCache(ProgData *pdata){
- pthread_t flush_to_ogg_t,
- load_cache_t;
- fprintf(stderr,"STATE:ENCODING\n");fflush(stderr);
- fprintf(stderr,"Encoding started!\nThis may take several minutes.\n"
- "Pressing Ctrl-C will cancel the procedure"
- " (resuming will not be possible, but\n"
- "any portion of the video, which is already encoded won't be deleted).\n"
- "Please wait...\n");
- pdata->running = TRUE;
- rmdInitEncoder(pdata,pdata->enc_data,1);
- //load encoding and flushing threads
- 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(&flush_to_ogg_t,NULL,(void *)rmdFlushToOgg,(void *)pdata);
+ pthread_t flush_to_ogg_t, load_cache_t;
- //start loading image and audio
- pthread_create(&load_cache_t,NULL,(void *)rmdLoadCache,(void *)pdata);
+ fprintf(stderr,"STATE:ENCODING\n");
+ fprintf(stderr, "Encoding started!\nThis may take several minutes.\n"
+ "Pressing Ctrl-C will cancel the procedure"
+ " (resuming will not be possible, but\n"
+ "any portion of the video, which is already encoded won't be deleted).\n"
+ "Please wait...\n");
- //join and finish
- pthread_join(load_cache_t,NULL);
- fprintf(stderr,"Encoding finished!\nWait a moment please...\n");
- pthread_join(flush_to_ogg_t,NULL);
-
-}
+ pdata->running = TRUE;
+ rmdInitEncoder(pdata,pdata->enc_data,1);
+ //load encoding and flushing threads
+ 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(&flush_to_ogg_t,NULL,(void *)rmdFlushToOgg,(void *)pdata);
+ //start loading image and audio
+ pthread_create(&load_cache_t,NULL,(void *)rmdLoadCache,(void *)pdata);
+ //join and finish
+ pthread_join(load_cache_t,NULL);
+ fprintf(stderr,"Encoding finished!\nWait a moment please...\n");
+ pthread_join(flush_to_ogg_t,NULL);
+}
diff --git a/recordmydesktop/src/rmd_encode_image_buffer.c b/recordmydesktop/src/rmd_encode_image_buffer.c
index 9c984ea..b96db25 100644
--- a/recordmydesktop/src/rmd_encode_image_buffer.c
+++ b/recordmydesktop/src/rmd_encode_image_buffer.c
@@ -32,65 +32,62 @@
#include <errno.h>
-void *rmdEncodeImageBuffer(ProgData *pdata){
- pdata->th_encoding_clean=0;
- while(pdata->running){
- pdata->th_enc_thread_waiting=1;
- pthread_mutex_lock(&pdata->img_buff_ready_mutex);
- pthread_cond_wait(&pdata->image_buffer_ready,
- &pdata->img_buff_ready_mutex);
- pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
- pdata->th_enc_thread_waiting=0;
- pdata->encoder_busy = TRUE;
- if (pdata->paused) {
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
- }
- pthread_mutex_lock(&pdata->yuv_mutex);
+void *rmdEncodeImageBuffer(ProgData *pdata) {
+ pdata->th_encoding_clean=0;
+ while (pdata->running) {
+ pdata->th_enc_thread_waiting=1;
+ pthread_mutex_lock(&pdata->img_buff_ready_mutex);
+ pthread_cond_wait(&pdata->image_buffer_ready,
+ &pdata->img_buff_ready_mutex);
+ pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
+ pdata->th_enc_thread_waiting=0;
+ pdata->encoder_busy = TRUE;
+ if (pdata->paused) {
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ }
+ pthread_mutex_lock(&pdata->yuv_mutex);
- if(theora_encode_YUVin(&pdata->enc_data->m_th_st,
- &pdata->enc_data->yuv)){
- fprintf(stderr,"Encoder not ready!\n");
- pthread_mutex_unlock(&pdata->yuv_mutex);
- }
- else{
- pthread_mutex_unlock(&pdata->yuv_mutex);
- if(theora_encode_packetout(&pdata->enc_data->m_th_st,0,
- &pdata->enc_data->m_ogg_pckt1)==1){
- pthread_mutex_lock(&pdata->libogg_mutex);
- ogg_stream_packetin(&pdata->enc_data->m_ogg_ts,
- &pdata->enc_data->m_ogg_pckt1);
- pthread_mutex_unlock(&pdata->libogg_mutex);
- pdata->avd+=pdata->frametime;
- }
- }
- pdata->encoder_busy = FALSE;
- }
- //last packet
- pdata->th_encoding_clean=1;
- pthread_mutex_lock(&pdata->theora_lib_mutex);
- pthread_cond_signal(&pdata->theora_lib_clean);
- pthread_mutex_unlock(&pdata->theora_lib_mutex);
- pthread_exit(&errno);
+ if (theora_encode_YUVin(&pdata->enc_data->m_th_st, &pdata->enc_data->yuv)) {
+ fprintf(stderr,"Encoder not ready!\n");
+ pthread_mutex_unlock(&pdata->yuv_mutex);
+ } else {
+ pthread_mutex_unlock(&pdata->yuv_mutex);
+ if (theora_encode_packetout(&pdata->enc_data->m_th_st, 0, &pdata->enc_data->m_ogg_pckt1)==1) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ ogg_stream_packetin(&pdata->enc_data->m_ogg_ts,
+ &pdata->enc_data->m_ogg_pckt1);
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ pdata->avd+=pdata->frametime;
+ }
+ }
+ pdata->encoder_busy = FALSE;
+ }
+ //last packet
+ pdata->th_encoding_clean=1;
+ pthread_mutex_lock(&pdata->theora_lib_mutex);
+ pthread_cond_signal(&pdata->theora_lib_clean);
+ pthread_mutex_unlock(&pdata->theora_lib_mutex);
+ pthread_exit(&errno);
}
//this function is meant to be called normally
//not through a thread of it's own
-void rmdSyncEncodeImageBuffer(ProgData *pdata){
- if(theora_encode_YUVin(&pdata->enc_data->m_th_st,
- &pdata->enc_data->yuv)){
- fprintf(stderr,"Encoder not ready!\n");
- }
- else{
- if(theora_encode_packetout(&pdata->enc_data->m_th_st,!pdata->running,
- &pdata->enc_data->m_ogg_pckt1)==1){
- pthread_mutex_lock(&pdata->libogg_mutex);
- ogg_stream_packetin(&pdata->enc_data->m_ogg_ts,
- &pdata->enc_data->m_ogg_pckt1);
- if(!pdata->running)pdata->enc_data->m_ogg_ts.e_o_s=1;
- pthread_mutex_unlock(&pdata->libogg_mutex);
- pdata->avd+=pdata->frametime;
- }
- }
+void rmdSyncEncodeImageBuffer(ProgData *pdata) {
+ if (theora_encode_YUVin(&pdata->enc_data->m_th_st, &pdata->enc_data->yuv)) {
+ fprintf(stderr,"Encoder not ready!\n");
+ return;
+ }
+
+ if (theora_encode_packetout(&pdata->enc_data->m_th_st, !pdata->running, &pdata->enc_data->m_ogg_pckt1)==1) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ ogg_stream_packetin(&pdata->enc_data->m_ogg_ts, &pdata->enc_data->m_ogg_pckt1);
+
+ if (!pdata->running)
+ pdata->enc_data->m_ogg_ts.e_o_s=1;
+
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ pdata->avd+=pdata->frametime;
+ }
}
diff --git a/recordmydesktop/src/rmd_encode_sound_buffer.c b/recordmydesktop/src/rmd_encode_sound_buffer.c
index 1d88a59..c68eae0 100644
--- a/recordmydesktop/src/rmd_encode_sound_buffer.c
+++ b/recordmydesktop/src/rmd_encode_sound_buffer.c
@@ -36,158 +36,145 @@
#include <errno.h>
-void *rmdEncodeSoundBuffer(ProgData *pdata){
- int sampread=pdata->periodsize;
+void *rmdEncodeSoundBuffer(ProgData *pdata) {
+ int sampread=pdata->periodsize;
#ifdef HAVE_LIBJACK
- void *jackbuf=NULL;
- if(pdata->args.use_jack){
- jackbuf=malloc(pdata->sound_framesize*pdata->jdata->buffersize);
- }
+ void *jackbuf=NULL;
+
+ if (pdata->args.use_jack) {
+ jackbuf=malloc(pdata->sound_framesize*pdata->jdata->buffersize);
+ }
#endif
- pdata->v_encoding_clean=0;
- while((pdata->running)){
- float **vorbis_buffer;
- int count=0,i,j;
- SndBuffer *buff=NULL;
-
- if (pdata->paused) {
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
- }
- if(!pdata->args.use_jack){
- if(pdata->sound_buffer==NULL){
- pdata->v_enc_thread_waiting=1;
- pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
- pthread_cond_wait(&pdata->sound_data_read,
- &pdata->snd_buff_ready_mutex);
- pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
- pdata->v_enc_thread_waiting=0;
- }
- if(pdata->sound_buffer==NULL || !pdata->running)
- break;
- pthread_mutex_lock(&pdata->sound_buffer_mutex);
- buff=pdata->sound_buffer;
- //advance the list
- pdata->sound_buffer=pdata->sound_buffer->next;
- pthread_mutex_unlock(&pdata->sound_buffer_mutex);
-
- vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,
- sampread);
-
- for(i=0;i<sampread;i++){
- for(j=0;j<pdata->args.channels;j++){
- vorbis_buffer[j][i]=((buff->data[count+1]<<8)|
- (0x00ff&(int)buff->data[count]))/
- 32768.f;
- count+=2;
- }
- }
- free(buff->data);
- free(buff);
- }
- else{
+
+ pdata->v_encoding_clean=0;
+ while ((pdata->running)) {
+ float **vorbis_buffer;
+ int count=0,i,j;
+ SndBuffer *buff=NULL;
+
+ if (pdata->paused) {
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ }
+ if (!pdata->args.use_jack) {
+ if (pdata->sound_buffer==NULL) {
+ pdata->v_enc_thread_waiting=1;
+ pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
+ pthread_cond_wait(&pdata->sound_data_read,
+ &pdata->snd_buff_ready_mutex);
+ pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
+ pdata->v_enc_thread_waiting=0;
+ }
+
+ if (pdata->sound_buffer==NULL || !pdata->running)
+ break;
+
+ pthread_mutex_lock(&pdata->sound_buffer_mutex);
+ buff=pdata->sound_buffer;
+ //advance the list
+ pdata->sound_buffer=pdata->sound_buffer->next;
+ pthread_mutex_unlock(&pdata->sound_buffer_mutex);
+
+ vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp, sampread);
+
+ for (i=0;i<sampread;i++) {
+ for (j=0;j<pdata->args.channels;j++) {
+ vorbis_buffer[j][i]=((buff->data[count+1]<<8)| (0x00ff&(int)buff->data[count]))/ 32768.f;
+ count+=2;
+ }
+ }
+ free(buff->data);
+ free(buff);
+ } else {
#ifdef HAVE_LIBJACK
- if((*jack_ringbuffer_read_space)(pdata->jdata->sound_buffer)>=
- (pdata->sound_framesize*pdata->jdata->buffersize)){
- (*jack_ringbuffer_read)(pdata->jdata->sound_buffer,
- jackbuf,
- (pdata->sound_framesize*
- pdata->jdata->buffersize));
- vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,
- sampread);
- for(j=0;j<pdata->args.channels;j++){
- for(i=0;i<sampread;i++){
- vorbis_buffer[j][i]=((float*)jackbuf)[count];
- count++;
- }
- }
- }
- else{
- pdata->v_enc_thread_waiting=1;
- pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
- pthread_cond_wait(&pdata->sound_data_read,
- &pdata->snd_buff_ready_mutex);
- pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
- pdata->v_enc_thread_waiting=0;
- continue;
- }
+ if ((*jack_ringbuffer_read_space)(pdata->jdata->sound_buffer)>=
+ (pdata->sound_framesize*pdata->jdata->buffersize)) {
+ (*jack_ringbuffer_read)(pdata->jdata->sound_buffer,
+ jackbuf,
+ (pdata->sound_framesize*
+ pdata->jdata->buffersize));
+ vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,
+ sampread);
+ for (j=0;j<pdata->args.channels;j++) {
+ for (i=0;i<sampread;i++) {
+ vorbis_buffer[j][i]=((float*)jackbuf)[count];
+ count++;
+ }
+ }
+ } else {
+ pdata->v_enc_thread_waiting=1;
+ pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
+ pthread_cond_wait(&pdata->sound_data_read,
+ &pdata->snd_buff_ready_mutex);
+ pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
+ pdata->v_enc_thread_waiting=0;
+ continue;
+ }
#endif
- }
- vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread);
-
- pthread_mutex_lock(&pdata->libogg_mutex);
- while(vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp,
- &pdata->enc_data->m_vo_block)==1){
+ }
+ vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread);
- vorbis_analysis(&pdata->enc_data->m_vo_block,NULL);
- vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block);
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ while (vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_vo_block)==1) {
- while(vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp,
- &pdata->enc_data->m_ogg_pckt2)){
- ogg_stream_packetin(&pdata->enc_data->m_ogg_vs,
- &pdata->enc_data->m_ogg_pckt2);
- }
- }
- pthread_mutex_unlock(&pdata->libogg_mutex);
+ vorbis_analysis(&pdata->enc_data->m_vo_block,NULL);
+ vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block);
- pdata->avd-=pdata->periodtime;
+ while (vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_ogg_pckt2)) {
+ ogg_stream_packetin(&pdata->enc_data->m_ogg_vs, &pdata->enc_data->m_ogg_pckt2);
+ }
+ }
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ pdata->avd-=pdata->periodtime;
+ }
- }
-
- pdata->v_encoding_clean=1;
- pthread_mutex_lock(&pdata->vorbis_lib_mutex);
- pthread_cond_signal(&pdata->vorbis_lib_clean);
- pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
- pthread_exit(&errno);
+ pdata->v_encoding_clean=1;
+ pthread_mutex_lock(&pdata->vorbis_lib_mutex);
+ pthread_cond_signal(&pdata->vorbis_lib_clean);
+ pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
+ pthread_exit(&errno);
}
-void rmdSyncEncodeSoundBuffer(ProgData *pdata,signed char *buff){
- float **vorbis_buffer;
- int count=0,i,j;
- int sampread=(buff!=NULL)?pdata->periodsize:0;
-
- vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,sampread);
-
- if(!pdata->args.use_jack){
- for(i=0;i<sampread;i++){
- for(j=0;j<pdata->args.channels;j++){
- vorbis_buffer[j][i]=((buff[count+1]<<8)|
- (0x00ff&(int)buff[count]))/
- 32768.f;
- count+=2;
- }
- }
- }
- else{
- for(j=0;j<pdata->args.channels;j++){
- for(i=0;i<sampread;i++){
- vorbis_buffer[j][i]=((float*)buff)[count];
- count++;
- }
- }
- }
-
- vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread);
-
- pthread_mutex_lock(&pdata->libogg_mutex);
- while(vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp,
- &pdata->enc_data->m_vo_block)==1){
-
- vorbis_analysis(&pdata->enc_data->m_vo_block,NULL);
- vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block);
-
- while(vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp,
- &pdata->enc_data->m_ogg_pckt2)){
- ogg_stream_packetin(&pdata->enc_data->m_ogg_vs,
- &pdata->enc_data->m_ogg_pckt2);
- }
- }
- pthread_mutex_unlock(&pdata->libogg_mutex);
-
- if(!pdata->running)pdata->enc_data->m_ogg_vs.e_o_s=1;
-
- pdata->avd-=pdata->periodtime;
+void rmdSyncEncodeSoundBuffer(ProgData *pdata,signed char *buff) {
+ float **vorbis_buffer;
+ int count=0,i,j;
+ int sampread=(buff!=NULL)?pdata->periodsize:0;
+
+ vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,sampread);
+
+ if (!pdata->args.use_jack) {
+ for (i=0;i<sampread;i++) {
+ for (j=0;j<pdata->args.channels;j++) {
+ vorbis_buffer[j][i]=((buff[count+1]<<8)| (0x00ff&(int)buff[count]))/ 32768.f;
+ count+=2;
+ }
+ }
+ } else {
+ for (j=0;j<pdata->args.channels;j++) {
+ for (i=0;i<sampread;i++) {
+ vorbis_buffer[j][i]=((float*)buff)[count];
+ count++;
+ }
+ }
+ }
+
+ vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread);
+
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ while (vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_vo_block)==1) {
+
+ vorbis_analysis(&pdata->enc_data->m_vo_block,NULL);
+ vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block);
+
+ while (vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp, &pdata->enc_data->m_ogg_pckt2))
+ ogg_stream_packetin(&pdata->enc_data->m_ogg_vs, &pdata->enc_data->m_ogg_pckt2);
+ }
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+
+ if (!pdata->running)
+ pdata->enc_data->m_ogg_vs.e_o_s=1;
+
+ pdata->avd-=pdata->periodtime;
}
-
diff --git a/recordmydesktop/src/rmd_error.c b/recordmydesktop/src/rmd_error.c
index 44144bf..e9705cc 100644
--- a/recordmydesktop/src/rmd_error.c
+++ b/recordmydesktop/src/rmd_error.c
@@ -35,26 +35,25 @@
-int rmdErrorHandler( Display *dpy, XErrorEvent *e )
+int rmdErrorHandler(Display *dpy, XErrorEvent *e)
{
- char error_desc[1024];
- XGetErrorText(dpy,e->error_code,error_desc,sizeof(error_desc));
- fprintf(stderr,"X Error: %s\n",error_desc);
- fflush(stderr);
- if((e->error_code==BadWindow)&&(e->request_code==X_GetWindowAttributes)){
- fprintf(stderr,"BadWindow on XGetWindowAttributes.\nIgnoring...\n");
- fflush(stderr);
- return 0;
- }
- else if((e->error_code==BadAccess)&&(e->request_code==X_GrabKey)){
- fprintf(stderr,"Bad Access on XGrabKey.\n"
- "Shortcut already assigned.\n");
- fflush(stderr);
- return 0;
- }
- else
- exit(1);
-}
+ char error_desc[1024];
+
+ XGetErrorText(dpy,e->error_code,error_desc,sizeof(error_desc));
+ fprintf(stderr,"X Error: %s\n",error_desc);
+ fflush(stderr);
+ if ((e->error_code==BadWindow)&&(e->request_code==X_GetWindowAttributes)) {
+ fprintf(stderr,"BadWindow on XGetWindowAttributes.\nIgnoring...\n");
+ fflush(stderr);
+ return 0;
+ }
+ if ((e->error_code==BadAccess)&&(e->request_code==X_GrabKey)) {
+ fprintf(stderr,"Bad Access on XGrabKey.\n" "Shortcut already assigned.\n");
+ fflush(stderr);
+ return 0;
+ }
+ exit(1);
+}
diff --git a/recordmydesktop/src/rmd_flush_to_ogg.c b/recordmydesktop/src/rmd_flush_to_ogg.c
index 9a443b1..fa6b42e 100644
--- a/recordmydesktop/src/rmd_flush_to_ogg.c
+++ b/recordmydesktop/src/rmd_flush_to_ogg.c
@@ -45,176 +45,184 @@
//both streams at every time in
//order to do correct multiplexing
static void ogg_page_cp(ogg_page *new, ogg_page *old) {
- int i=0;
- register unsigned char *newp,*oldp;
-
- new->header_len=old->header_len;
- new->header=malloc(new->header_len);
- new->body_len=old->body_len;
- new->body=malloc(new->body_len);
-
- newp=new->header;
- oldp=old->header;
- for(i=0;i<new->header_len;i++)
- *(newp++)=*(oldp++);
- newp=new->body;
- oldp=old->body;
- for(i=0;i<new->body_len;i++)
- *(newp++)=*(oldp++);
+ int i=0;
+ register unsigned char *newp,*oldp;
+
+ new->header_len=old->header_len;
+ new->header=malloc(new->header_len);
+ new->body_len=old->body_len;
+ new->body=malloc(new->body_len);
+
+ newp=new->header;
+ oldp=old->header;
+ for(i=0;i<new->header_len;i++)
+ *(newp++)=*(oldp++);
+ newp=new->body;
+ oldp=old->body;
+ for(i=0;i<new->body_len;i++)
+ *(newp++)=*(oldp++);
}
//free our copy
static void ogg_page_cp_free(ogg_page *pg) {
- pg->header_len=pg->body_len=0;
- free(pg->header);
- free(pg->body);
+ pg->header_len=pg->body_len=0;
+ free(pg->header);
+ free(pg->body);
}
-void *rmdFlushToOgg(ProgData *pdata){
- int videoflag=0,audioflag=0;
- double video_bytesout=0,audio_bytesout=0;
- ogg_page videopage,//owned by libogg
- videopage_copy,//owned by the application
- audiopage,//owned by libogg
- audiopage_copy;//owned by the application
-
- double audiotime=0;
- double videotime=0;
- int working=1,
- th_st_fin=0,
- v_st_fin=(pdata->args.nosound);
- while(working){
- int audio_or_video=0;
- if(pdata->running){
- pthread_mutex_lock(&pdata->libogg_mutex);
- if(!videoflag){
- videoflag=ogg_stream_pageout(&pdata->enc_data->m_ogg_ts,
- &videopage);
- videotime=(videoflag)?
- theora_granule_time(&pdata->enc_data->m_th_st,
- ogg_page_granulepos(&videopage)):-1;
- if(videoflag)ogg_page_cp(&videopage_copy,&videopage);
- }
- if(!pdata->args.nosound)
- if(!audioflag){
- audioflag=ogg_stream_pageout(&pdata->enc_data->m_ogg_vs,
- &audiopage);
- audiotime=(audioflag)?
- vorbis_granule_time(&pdata->enc_data->m_vo_dsp,
- ogg_page_granulepos(&audiopage)):-1;
- if(audioflag)ogg_page_cp(&audiopage_copy,&audiopage);
- }
- pthread_mutex_unlock(&pdata->libogg_mutex);
- }
- else{
- if(!th_st_fin && !videoflag){
- pthread_mutex_lock(&pdata->libogg_mutex);
- videoflag=ogg_stream_flush(&pdata->enc_data->m_ogg_ts,
- &videopage);
- videotime=(videoflag)?
- theora_granule_time(&pdata->enc_data->m_th_st,
- ogg_page_granulepos(&videopage)):-1;
- if(videoflag)ogg_page_cp(&videopage_copy,&videopage);
- pthread_mutex_unlock(&pdata->libogg_mutex);
- //we need the last page to properly close the stream
- if(!videoflag){
- if(!pdata->th_encoding_clean){
- pthread_mutex_lock(&pdata->theora_lib_mutex);
- pthread_cond_wait(&pdata->theora_lib_clean,
- &pdata->theora_lib_mutex);
- pthread_mutex_unlock(&pdata->theora_lib_mutex);
- }
- rmdSyncEncodeImageBuffer(pdata);
- }
- }
- if(!pdata->args.nosound && !v_st_fin &&!audioflag){
- pthread_mutex_lock(&pdata->libogg_mutex);
- audioflag=ogg_stream_flush(&pdata->enc_data->m_ogg_vs,
- &audiopage);
- audiotime=(audioflag)?
- vorbis_granule_time(&pdata->enc_data->m_vo_dsp,
- ogg_page_granulepos(&audiopage)):-1;
- if(audioflag)ogg_page_cp(&audiopage_copy,&audiopage);
- pthread_mutex_unlock(&pdata->libogg_mutex);
- //we need the last page to properly close the stream
- if(!audioflag){
- if(!pdata->v_encoding_clean){
- pthread_mutex_lock(&pdata->vorbis_lib_mutex);
- pthread_cond_wait(&pdata->vorbis_lib_clean,
- &pdata->vorbis_lib_mutex);
- pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
- }
- rmdSyncEncodeSoundBuffer(pdata,NULL);
- }
- }
- }
- if(th_st_fin)videoflag=0;
- if(v_st_fin)audioflag=0;
- if((!audioflag && !v_st_fin && !pdata->args.nosound)||
- (!videoflag && !th_st_fin)){
- usleep(10000);
- continue;
- }
- if(!audioflag){
- audio_or_video=1;
- }
- else if(!videoflag) {
- audio_or_video=0;
- }
- else{
- if(audiotime<videotime)
- audio_or_video=0;
- else
- audio_or_video=1;
- }
- if(audio_or_video==1){
- video_bytesout+=fwrite(videopage_copy.header,1,
- videopage_copy.header_len,
- pdata->enc_data->fp);
- video_bytesout+=fwrite(videopage_copy.body,1,
- videopage_copy.body_len,
- pdata->enc_data->fp);
- videoflag=0;
- if(!pdata->running){
- pthread_mutex_lock(&pdata->libogg_mutex);
- if(ogg_page_eos(&videopage_copy))
- th_st_fin=1;
- pthread_mutex_unlock(&pdata->libogg_mutex);
- }
- ogg_page_cp_free(&videopage_copy);
- }
- else{
- audio_bytesout+=fwrite(audiopage_copy.header,1,
- audiopage_copy.header_len,
- pdata->enc_data->fp);
- audio_bytesout+=fwrite(audiopage_copy.body,1,
- audiopage_copy.body_len,
- pdata->enc_data->fp);
- audioflag=0;
- if(!pdata->running){
- pthread_mutex_lock(&pdata->libogg_mutex);
- if(ogg_page_eos(&audiopage_copy))
- v_st_fin=1;
- pthread_mutex_unlock(&pdata->libogg_mutex);
- }
- ogg_page_cp_free(&audiopage_copy);
- }
- working=(!th_st_fin || !v_st_fin);
-
- }
- pthread_mutex_lock(&pdata->libogg_mutex);
- ogg_stream_clear(&pdata->enc_data->m_ogg_ts);
- if(!pdata->args.nosound)
- ogg_stream_clear(&pdata->enc_data->m_ogg_vs);
- pthread_mutex_unlock(&pdata->libogg_mutex);
+void *rmdFlushToOgg(ProgData *pdata) {
+ int videoflag=0,audioflag=0;
+ double video_bytesout=0,audio_bytesout=0;
+ ogg_page videopage,//owned by libogg
+ videopage_copy,//owned by the application
+ audiopage,//owned by libogg
+ audiopage_copy;//owned by the application
+
+ double audiotime=0;
+ double videotime=0;
+ int working=1,
+ th_st_fin=0,
+ v_st_fin=(pdata->args.nosound);
+ while (working) {
+ int audio_or_video=0;
+ if (pdata->running) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ if (!videoflag) {
+ videoflag=ogg_stream_pageout(&pdata->enc_data->m_ogg_ts,
+ &videopage);
+ videotime=(videoflag)?
+ theora_granule_time(&pdata->enc_data->m_th_st,
+ ogg_page_granulepos(&videopage)):-1;
+ if (videoflag)ogg_page_cp(&videopage_copy,&videopage);
+ }
+ if (!pdata->args.nosound)
+ if (!audioflag) {
+ audioflag=ogg_stream_pageout(&pdata->enc_data->m_ogg_vs,
+ &audiopage);
+ audiotime=(audioflag)?
+ vorbis_granule_time(&pdata->enc_data->m_vo_dsp,
+ ogg_page_granulepos(&audiopage)):-1;
+ if (audioflag)ogg_page_cp(&audiopage_copy,&audiopage);
+ }
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ } else {
+ if (!th_st_fin && !videoflag) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ videoflag=ogg_stream_flush(&pdata->enc_data->m_ogg_ts,
+ &videopage);
+ videotime=(videoflag)?
+ theora_granule_time(&pdata->enc_data->m_th_st,
+ ogg_page_granulepos(&videopage)):-1;
+ if (videoflag)ogg_page_cp(&videopage_copy,&videopage);
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ //we need the last page to properly close the stream
+ if (!videoflag) {
+ if (!pdata->th_encoding_clean) {
+ pthread_mutex_lock(&pdata->theora_lib_mutex);
+ pthread_cond_wait(&pdata->theora_lib_clean,
+ &pdata->theora_lib_mutex);
+ pthread_mutex_unlock(&pdata->theora_lib_mutex);
+ }
+ rmdSyncEncodeImageBuffer(pdata);
+ }
+ }
+ if (!pdata->args.nosound && !v_st_fin &&!audioflag) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ audioflag=ogg_stream_flush(&pdata->enc_data->m_ogg_vs,
+ &audiopage);
+ audiotime=(audioflag)?
+ vorbis_granule_time(&pdata->enc_data->m_vo_dsp,
+ ogg_page_granulepos(&audiopage)):-1;
+ if (audioflag)ogg_page_cp(&audiopage_copy,&audiopage);
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ //we need the last page to properly close the stream
+ if (!audioflag) {
+ if (!pdata->v_encoding_clean) {
+ pthread_mutex_lock(&pdata->vorbis_lib_mutex);
+ pthread_cond_wait(&pdata->vorbis_lib_clean,
+ &pdata->vorbis_lib_mutex);
+ pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
+ }
+ rmdSyncEncodeSoundBuffer(pdata,NULL);
+ }
+ }
+ }
+ if (th_st_fin)
+ videoflag=0;
+
+ if (v_st_fin)
+ audioflag=0;
+
+ if ((!audioflag && !v_st_fin && !pdata->args.nosound) || (!videoflag && !th_st_fin)) {
+ usleep(10000);
+ continue;
+ }
+
+ if (!audioflag) {
+ audio_or_video=1;
+ } else if (!videoflag) {
+ audio_or_video=0;
+ } else {
+ if (audiotime<videotime)
+ audio_or_video=0;
+ else
+ audio_or_video=1;
+ }
+
+ if (audio_or_video==1) {
+ video_bytesout+=fwrite( videopage_copy.header,1,
+ videopage_copy.header_len,
+ pdata->enc_data->fp);
+
+ video_bytesout+=fwrite( videopage_copy.body,1,
+ videopage_copy.body_len,
+ pdata->enc_data->fp);
+ videoflag=0;
+
+ if (!pdata->running) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ if (ogg_page_eos(&videopage_copy))
+ th_st_fin=1;
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ }
+ ogg_page_cp_free(&videopage_copy);
+ } else {
+ audio_bytesout+=fwrite( audiopage_copy.header,1,
+ audiopage_copy.header_len,
+ pdata->enc_data->fp);
+
+ audio_bytesout+=fwrite( audiopage_copy.body,1,
+ audiopage_copy.body_len,
+ pdata->enc_data->fp);
+ audioflag=0;
+
+ if (!pdata->running) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ if (ogg_page_eos(&audiopage_copy))
+ v_st_fin=1;
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ }
+ ogg_page_cp_free(&audiopage_copy);
+ }
+ working=(!th_st_fin || !v_st_fin);
+
+ }
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ ogg_stream_clear(&pdata->enc_data->m_ogg_ts);
+
+ if (!pdata->args.nosound)
+ ogg_stream_clear(&pdata->enc_data->m_ogg_vs);
+
+ pthread_mutex_unlock(&pdata->libogg_mutex);
//this always gives me a segfault :(
-// theora_clear(&pdata->enc_data->m_th_st);
-
- if(pdata->enc_data->fp)fclose(pdata->enc_data->fp);
- fprintf(stderr,"\r \nDone.\nWritten %.0f bytes\n"
- "(%.0f of which were video data "
- "and %.0f audio data)\n\n",
- video_bytesout+audio_bytesout,
- video_bytesout,audio_bytesout);
- pthread_exit(&errno);
+// theora_clear(&pdata->enc_data->m_th_st);
+
+ if (pdata->enc_data->fp)
+ fclose(pdata->enc_data->fp);
+
+ fprintf(stderr, "\r \nDone.\nWritten %.0f bytes\n"
+ "(%.0f of which were video data and %.0f audio data)\n\n",
+ video_bytesout+audio_bytesout,
+ video_bytesout,audio_bytesout);
+ pthread_exit(&errno);
}
diff --git a/recordmydesktop/src/rmd_frame.c b/recordmydesktop/src/rmd_frame.c
index 740dacf..ce2e204 100644
--- a/recordmydesktop/src/rmd_frame.c
+++ b/recordmydesktop/src/rmd_frame.c
@@ -38,121 +38,105 @@
#define OUTLINE_WIDTH 1
-void rmdDrawFrame(Display *dpy,
- int screen,
- Window win,
- int width,
- int height){
-
- GC gc;
- XGCValues gcv;
- XColor white, white_e,
- black, black_e ;
- unsigned long gcmask=GCForeground;
-
- XAllocNamedColor(dpy,DefaultColormap(dpy, screen),"white", &white, &white_e);
- XAllocNamedColor(dpy,DefaultColormap(dpy, screen),"black", &black, &black_e);
-
- gcv.foreground = black.pixel;
- gc = XCreateGC(dpy,win, gcmask,&gcv);
- XFillRectangle(dpy,
- win,
- gc,
- OUTLINE_WIDTH,
- OUTLINE_WIDTH,
- width+(BORDER_WIDTH-OUTLINE_WIDTH)*2,
- height+(BORDER_WIDTH-OUTLINE_WIDTH)*2);
- gcv.foreground = white.pixel;
- XChangeGC(dpy,gc,gcmask,&gcv);
- XFillRectangle(dpy,
- win,
- gc,
- BORDER_WIDTH-OUTLINE_WIDTH,
- BORDER_WIDTH-OUTLINE_WIDTH,
- width+OUTLINE_WIDTH*2,
- height+OUTLINE_WIDTH*2);
-
- XFreeGC(dpy, gc);
+void rmdDrawFrame( Display *dpy,
+ int screen,
+ Window win,
+ int width,
+ int height) {
+
+ GC gc;
+ XGCValues gcv;
+ XColor white, white_e, black, black_e;
+ unsigned long gcmask=GCForeground;
+
+ XAllocNamedColor(dpy,DefaultColormap(dpy, screen),"white", &white, &white_e);
+ XAllocNamedColor(dpy,DefaultColormap(dpy, screen),"black", &black, &black_e);
+
+ gcv.foreground = black.pixel;
+ gc = XCreateGC(dpy,win, gcmask,&gcv);
+ XFillRectangle( dpy,
+ win,
+ gc,
+ OUTLINE_WIDTH,
+ OUTLINE_WIDTH,
+ width+(BORDER_WIDTH-OUTLINE_WIDTH)*2,
+ height+(BORDER_WIDTH-OUTLINE_WIDTH)*2);
+ gcv.foreground = white.pixel;
+ XChangeGC(dpy,gc,gcmask,&gcv);
+ XFillRectangle( dpy,
+ win,
+ gc,
+ BORDER_WIDTH-OUTLINE_WIDTH,
+ BORDER_WIDTH-OUTLINE_WIDTH,
+ width+OUTLINE_WIDTH*2,
+ height+OUTLINE_WIDTH*2);
+
+ XFreeGC(dpy, gc);
}
+void rmdMoveFrame( Display *dpy,
+ Window win,
+ int x,
+ int y) {
-void rmdMoveFrame(Display *dpy,
- Window win,
- int x,
- int y){
-
- XMoveWindow(dpy,
- win,
- x-BORDER_WIDTH,
- y-BORDER_WIDTH);
-
-// XSync(pdata->dpy,False);
-
+ XMoveWindow(dpy, win, x-BORDER_WIDTH, y-BORDER_WIDTH);
+// XSync(pdata->dpy,False);
}
-Window rmdFrameInit(Display *dpy,
- int screen,
- Window root,
- int x,
- int y,
- int width,
- int height){
-
- XSetWindowAttributes attribs;
- XColor white, white_e;
- Window win;
- unsigned long valuemask=CWBackPixmap|CWBackPixel|
- CWSaveUnder|CWOverrideRedirect|CWColormap;
-
- XAllocNamedColor(dpy,DefaultColormap(dpy, screen),"white", &white, &white_e);
-
- attribs.background_pixmap=None;
- attribs.background_pixel=white.pixel;
- attribs.save_under=True;
- attribs.override_redirect=True;
- attribs.colormap=DefaultColormap(dpy,screen);
-
- win = XCreateWindow(dpy,
- root,
- x-BORDER_WIDTH,
- y-BORDER_WIDTH,
- width+BORDER_WIDTH*2,
- height+BORDER_WIDTH*2,
- 0,
- CopyFromParent,
- InputOutput,
- CopyFromParent,
- valuemask,
- &attribs);
-
-
- XRectangle rect;
- rect.x=rect.y=BORDER_WIDTH;
- rect.width=width;
- rect.height=height;
-
- XShapeCombineRectangles(dpy,
- win,
- ShapeBounding,
- 0,
- 0,
- &rect,
- 1,
- ShapeSubtract,
- 0);
-
- XMapWindow(dpy, win);
-
- rmdDrawFrame(dpy,screen,win,width,height);
-
- return win;
+Window rmdFrameInit( Display *dpy,
+ int screen,
+ Window root,
+ int x,
+ int y,
+ int width,
+ int height) {
+
+ XSetWindowAttributes attribs;
+ XColor white, white_e;
+ Window win;
+ unsigned long valuemask=CWBackPixmap|CWBackPixel|
+ CWSaveUnder|CWOverrideRedirect|CWColormap;
+
+ XAllocNamedColor(dpy,DefaultColormap(dpy, screen),"white", &white, &white_e);
+
+ attribs.background_pixmap=None;
+ attribs.background_pixel=white.pixel;
+ attribs.save_under=True;
+ attribs.override_redirect=True;
+ attribs.colormap=DefaultColormap(dpy,screen);
+
+ win = XCreateWindow( dpy,
+ root,
+ x-BORDER_WIDTH,
+ y-BORDER_WIDTH,
+ width+BORDER_WIDTH*2,
+ height+BORDER_WIDTH*2,
+ 0,
+ CopyFromParent,
+ InputOutput,
+ CopyFromParent,
+ valuemask,
+ &attribs);
+
+ XRectangle rect;
+ rect.x=rect.y=BORDER_WIDTH;
+ rect.width=width;
+ rect.height=height;
+
+ XShapeCombineRectangles( dpy,
+ win,
+ ShapeBounding,
+ 0,
+ 0,
+ &rect,
+ 1,
+ ShapeSubtract,
+ 0);
+
+ XMapWindow(dpy, win);
+
+ rmdDrawFrame(dpy,screen,win,width,height);
+
+ return win;
}
-
-
-
-
-
-
-
-
diff --git a/recordmydesktop/src/rmd_get_frame.c b/recordmydesktop/src/rmd_get_frame.c
index a14b111..cd61dd2 100644
--- a/recordmydesktop/src/rmd_get_frame.c
+++ b/recordmydesktop/src/rmd_get_frame.c
@@ -52,7 +52,7 @@
data_array[(k_tm*width_img+i_tm-1)*RMD_ULONG_SIZE_T+offset]+\
data_array[((k_tm-1)*width_img+i_tm-1)*RMD_ULONG_SIZE_T+offset])/4)
-#define CLIP_DUMMY_POINTER_AREA(dummy_p_area,brwin,xrect){\
+#define CLIP_DUMMY_POINTER_AREA(dummy_p_area,brwin,xrect) {\
(xrect)->x=((((dummy_p_area).x+\
(dummy_p_area).width>=(brwin)->rrect.x)&&\
((dummy_p_area).x<=(brwin)->rrect.x+\
@@ -83,9 +83,9 @@
(brwin)->rrect.y<(dummy_p_area).height)?\
(brwin)->rrect.height-(dummy_p_area).y+\
(brwin)->rrect.y:(dummy_p_area).height:0;\
- if((xrect)->width>(brwin)->rrect.width)\
+ if ((xrect)->width>(brwin)->rrect.width)\
(xrect)->width=(brwin)->rrect.width;\
- if((xrect)->height>(brwin)->rrect.height)\
+ if ((xrect)->height>(brwin)->rrect.height)\
(xrect)->height=(brwin)->rrect.height;\
}
@@ -97,22 +97,22 @@
height_tm,\
x_offset,\
y_offset,\
- column_discard_stride){\
+ column_discard_stride) {\
int i,k,j=0;\
unsigned char avg0,avg1,avg2,avg3;\
int x_2=x_tm/2,y_2=y_tm/2;\
- for(k=y_offset;k<y_offset+height_tm;k++){\
- for(i=x_offset;i<x_offset+width_tm;i++){\
+ for(k=y_offset;k<y_offset+height_tm;k++) {\
+ for(i=x_offset;i<x_offset+width_tm;i++) {\
j=k*(width_tm+column_discard_stride)+i;\
- yuv->y[x_tm+(i-x_offset)+(k+y_tm-y_offset)*yuv->y_width]=\
- (yuv->y[x_tm+(i-x_offset)+(k-y_offset+y_tm)*yuv->y_width]*\
+ (yuv)->y[x_tm+(i-x_offset)+(k+y_tm-y_offset)*(yuv)->y_width]=\
+ ((yuv)->y[x_tm+(i-x_offset)+(k-y_offset+y_tm)*(yuv)->y_width]*\
(UCHAR_MAX-data[(j*RMD_ULONG_SIZE_T)+__ABYTE])+\
( ( Yr[data[(j*RMD_ULONG_SIZE_T)+__RBYTE]]+\
Yg[data[(j*RMD_ULONG_SIZE_T)+__GBYTE]] +\
Yb[data[(j*RMD_ULONG_SIZE_T)+__BBYTE]] ) % \
( UCHAR_MAX + 1 ) ) * \
data[(j*RMD_ULONG_SIZE_T)+__ABYTE])/UCHAR_MAX ;\
- if((k%2)&&(i%2)){\
+ if ((k%2)&&(i%2)) {\
avg3=AVG_4_PIXELS(data,\
(width_tm+column_discard_stride),\
k,i,__ABYTE);\
@@ -125,18 +125,18 @@
avg0=AVG_4_PIXELS(data,\
(width_tm+column_discard_stride),\
k,i,__BBYTE);\
- yuv->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
- yuv->uv_width]=\
- (yuv->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
- yuv->uv_width]*\
+ (yuv)->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
+ (yuv)->uv_width]=\
+ ((yuv)->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
+ (yuv)->uv_width]*\
(UCHAR_MAX-avg3)+\
( (Ur[avg2] + Ug[avg1] + UbVr[avg0]) % \
( UCHAR_MAX + 1 ) ) * avg3 ) / \
UCHAR_MAX;\
- yuv->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
- yuv->uv_width]=\
- (yuv->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
- yuv->uv_width]*\
+ (yuv)->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
+ (yuv)->uv_width]=\
+ ((yuv)->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\
+ (yuv)->uv_width]*\
(UCHAR_MAX-avg3)+\
( ( UbVr[avg2] + Vg[avg1] + Vb[avg0] ) % \
( UCHAR_MAX + 1 ) ) * avg3 ) / \
@@ -152,13 +152,13 @@
width_tm,\
height_tm,\
buffer_width,\
- __bit_depth__){\
+ __bit_depth__) {\
int k,i;\
register u_int##__bit_depth__##_t\
*datapi=\
((u_int##__bit_depth__##_t *)data)+y_tm*buffer_width+x_tm;\
- for(k=0;k<height_tm;k++){\
- for(i=0;i<width_tm;i++){\
+ for(k=0;k<height_tm;k++) {\
+ for(i=0;i<width_tm;i++) {\
*datapi+=1;\
datapi++;\
}\
@@ -172,8 +172,8 @@
width_tm,\
height_tm,\
buffer_width,\
- __bit_depth__){\
- if((__bit_depth__==24)||(__bit_depth__==32)){\
+ __bit_depth__) {\
+ if ((__bit_depth__==24)||(__bit_depth__==32)) {\
MARK_BUFFER_AREA_C( data,\
x_tm,\
y_tm,\
@@ -182,7 +182,7 @@
buffer_width,\
32)\
}\
- else{\
+ else {\
MARK_BUFFER_AREA_C( data,\
x_tm,\
y_tm,\
@@ -196,108 +196,107 @@
//besides taking the first screenshot, this functions primary purpose is to
//initialize the structures and memory.
-static int rmdFirstFrame(ProgData *pdata,
- XImage **image,
- XShmSegmentInfo *shminfo) {
-
- if((pdata->args.noshared)){
- char *pxl_data;
-
- pxl_data=(char *)malloc(pdata->brwin.nbytes);
-
- (*image)=XCreateImage(pdata->dpy,
- pdata->specs.visual,
- pdata->specs.depth,
- ZPixmap,
- 0,
- pxl_data,
- pdata->brwin.rrect.width,
- pdata->brwin.rrect.height,
- 8,
- 0);
- XInitImage((*image));
- rmdGetZPixmap(pdata->dpy,pdata->specs.root,
- (*image)->data,
- pdata->brwin.rrect.x,
- pdata->brwin.rrect.y,
- pdata->brwin.rrect.width,
- pdata->brwin.rrect.height);
- }
- else{
- (*image)=XShmCreateImage(pdata->dpy,
- pdata->specs.visual,
- pdata->specs.depth,
- ZPixmap,
- NULL,
- shminfo,
- pdata->brwin.rrect.width,
- pdata->brwin.rrect.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.rrect.x,
- pdata->brwin.rrect.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.rrect.width),(pdata->brwin.rrect.height),
- (pdata->args.no_quick_subsample),
- pdata->specs.depth);
-
- return 0;
+static int rmdFirstFrame(ProgData *pdata, XImage **image, XShmSegmentInfo *shminfo) {
+
+ if ((pdata->args.noshared)) {
+ char *pxl_data;
+
+ pxl_data=(char *)malloc(pdata->brwin.nbytes);
+
+ (*image)=XCreateImage( pdata->dpy,
+ pdata->specs.visual,
+ pdata->specs.depth,
+ ZPixmap,
+ 0,
+ pxl_data,
+ pdata->brwin.rrect.width,
+ pdata->brwin.rrect.height,
+ 8,
+ 0);
+ XInitImage((*image));
+ rmdGetZPixmap( pdata->dpy,pdata->specs.root,
+ (*image)->data,
+ pdata->brwin.rrect.x,
+ pdata->brwin.rrect.y,
+ pdata->brwin.rrect.width,
+ pdata->brwin.rrect.height);
+ } else {
+ (*image)=XShmCreateImage( pdata->dpy,
+ pdata->specs.visual,
+ pdata->specs.depth,
+ ZPixmap,
+ NULL,
+ shminfo,
+ pdata->brwin.rrect.width,
+ pdata->brwin.rrect.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.rrect.x,
+ pdata->brwin.rrect.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.rrect.width),(pdata->brwin.rrect.height),
+ (pdata->args.no_quick_subsample),
+ pdata->specs.depth);
+
+ return 0;
}
//make a deep copy
static void rmdBRWinCpy(BRWindow *target, BRWindow *source) {
- target->rect.x=source->rect.x;
- target->rect.y=source->rect.y;
- target->rect.width=source->rect.width;
- target->rect.height=source->rect.height;
- target->rrect.x=source->rrect.x;
- target->rrect.y=source->rrect.y;
- target->rrect.width=source->rrect.width;
- target->rrect.height=source->rrect.height;
- target->nbytes=source->nbytes;
- target->windowid=source->windowid;
+ target->rect.x=source->rect.x;
+ target->rect.y=source->rect.y;
+ target->rect.width=source->rect.width;
+ target->rect.height=source->rect.height;
+ target->rrect.x=source->rrect.x;
+ target->rrect.y=source->rrect.y;
+ target->rrect.width=source->rrect.width;
+ target->rrect.height=source->rrect.height;
+ target->nbytes=source->nbytes;
+ target->windowid=source->windowid;
}
//recenters the capture area to the mouse
//without exiting the display bounding box
-static void rmdMoveCaptureArea(BRWindow *brwin,
- int cursor_x,
- int cursor_y,
- int width,
- int height) {
- int t_x=0,t_y=0;
-
- t_x=cursor_x-brwin->rrect.width/2;
- t_x=(t_x>>1)<<1;
- brwin->rrect.x=(t_x<0)?0:((t_x+brwin->rrect.width>width)?
- width-brwin->rrect.width:t_x);
- t_y=cursor_y-brwin->rrect.height/2;
- t_y=(t_y>>1)<<1;
- brwin->rrect.y=(t_y<0)?0:((t_y+brwin->rrect.height>height)?
- height-brwin->rrect.height:t_y);
+static void rmdMoveCaptureArea( BRWindow *brwin,
+ int cursor_x,
+ int cursor_y,
+ int width,
+ int height) {
+ int t_x=0,t_y=0;
+
+ t_x=cursor_x-brwin->rrect.width/2;
+ t_x=(t_x>>1)<<1;
+ brwin->rrect.x=(t_x<0)?0:((t_x+brwin->rrect.width>width)? width-brwin->rrect.width:t_x);
+ t_y=cursor_y-brwin->rrect.height/2;
+ t_y=(t_y>>1)<<1;
+ brwin->rrect.y=(t_y<0)?0:((t_y+brwin->rrect.height>height)? height-brwin->rrect.height:t_y);
}
/**
@@ -313,398 +312,379 @@ static void rmdMoveCaptureArea(BRWindow *brwin,
*
* \param blocknum_y Height of image in blocks
*/
-static void rmdBlocksFromList (RectArea **root,
- unsigned int x_offset,
- unsigned int y_offset,
- unsigned int blocknum_x,
- unsigned int blocknum_y) {
-
- RectArea *temp;
- int i,
- j,
- blockno,
- row_start,
- row_end,
- column_start,
- column_end;
-
- temp = *root;
-
- for (i = 0; i < blocknum_x * blocknum_y; i++) {
- yblocks[i] = ublocks[i] = vblocks[i] = 0;
- }
-
- while (temp != NULL) {
-
- column_start = ((int)(temp->rect.x - x_offset)) / Y_UNIT_WIDTH;
- column_end = ((int)(temp->rect.x + (temp->rect.width - 1) - x_offset)) / Y_UNIT_WIDTH;
- row_start = ((int)(temp->rect.y - y_offset)) / Y_UNIT_WIDTH;
- row_end = ((int)(temp->rect.y + (temp->rect.height - 1) - y_offset)) / Y_UNIT_WIDTH;
-
- for (i = row_start; i < row_end + 1; i++) {
- for (j = column_start; j < column_end + 1; j++) {
- blockno = i * blocknum_x + j;
- yblocks[blockno] = 1;
- ublocks[blockno] = 1;
- vblocks[blockno] = 1;
- }
- }
-
- temp = temp->next;
- }
+static void rmdBlocksFromList( RectArea **root,
+ unsigned int x_offset,
+ unsigned int y_offset,
+ unsigned int blocknum_x,
+ unsigned int blocknum_y) {
+
+ RectArea *temp = *root;
+ int i, j, blockno, row_start, row_end, column_start, column_end;
+
+ for (i = 0; i < blocknum_x * blocknum_y; i++)
+ yblocks[i] = ublocks[i] = vblocks[i] = 0;
+
+ while (temp != NULL) {
+
+ column_start = ((int)(temp->rect.x - x_offset)) / Y_UNIT_WIDTH;
+ column_end = ((int)(temp->rect.x + (temp->rect.width - 1) - x_offset)) / Y_UNIT_WIDTH;
+ row_start = ((int)(temp->rect.y - y_offset)) / Y_UNIT_WIDTH;
+ row_end = ((int)(temp->rect.y + (temp->rect.height - 1) - y_offset)) / Y_UNIT_WIDTH;
+
+ for (i = row_start; i < row_end + 1; i++) {
+ for (j = column_start; j < column_end + 1; j++) {
+ blockno = i * blocknum_x + j;
+ yblocks[blockno] = 1;
+ ublocks[blockno] = 1;
+ vblocks[blockno] = 1;
+ }
+ }
+
+ temp = temp->next;
+ }
}
-void *rmdGetFrame(ProgData *pdata){
- int i=0,
- blocknum_x=pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
- blocknum_y=pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH;
- unsigned int msk_ret;
- XRectangle mouse_pos_abs,mouse_pos_rel,mouse_pos_temp;
- BRWindow temp_brwin;
- Window root_ret,
- child_ret; //Frame
- 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,
- img_sel,d_buff;
-
- img_sel=d_buff=pdata->args.full_shots;
-
- if((init_img1=rmdFirstFrame(pdata,&image,&shminfo)!=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{
- rmdPurgeCache(pdata->cache_data,!pdata->args.nosound);
- }
- exit(init_img1);
- }
- if(d_buff){
- if((init_img2=rmdFirstFrame(pdata,&image_back,&shminfo_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{
- rmdPurgeCache(pdata->cache_data,!pdata->args.nosound);
- }
- exit(init_img2);
- }
-
- }
-
- if(!pdata->args.noframe){
- pdata->shaped_w=rmdFrameInit(pdata->dpy,
- pdata->specs.screen,
- pdata->specs.root,
- pdata->brwin.rrect.x,
- pdata->brwin.rrect.y,
- pdata->brwin.rrect.width,
- pdata->brwin.rrect.height);
- XSelectInput(pdata->dpy,pdata->shaped_w,ExposureMask);
- }
-
- 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;
- mouse_pos_abs.height=mouse_pos_temp.height=pdata->dummy_p_size;
-
- //This is the the place where we call XSelectInput
- //and arrange so that we listen for damage on all
- //windows
- rmdInitEventsPolling(pdata);
-
- while(pdata->running){
-
- //if we are left behind we must not wait.
- //also before actually pausing we must make sure the streams
- //are synced. sound stops so this should only happen quickly.
- if(pdata->avd>0 || pdata->args.nosound){
- pthread_mutex_lock(&pdata->time_mutex);
- pthread_cond_wait(&pdata->time_cond, &pdata->time_mutex);
- pthread_mutex_unlock(&pdata->time_mutex);
- if (pdata->paused) {
- //this is necessary since event loop processes
- //the shortcuts which will unpause the program
- rmdEventLoop(pdata);
- continue;
- }
- }
- //read all events and construct list with damage
- //events (if not full_shots)
- rmdEventLoop(pdata);
-
- //switch back and front buffers (full_shots only)
- if(d_buff)
- img_sel=(img_sel)?0:1;
- pdata->capture_busy = TRUE;
-
- rmdBRWinCpy(&temp_brwin,&pdata->brwin);
-
-
- if(pdata->args.xfixes_cursor ||
- pdata->args.have_dummy_cursor||
- pdata->args.follow_mouse){
-
-
- // Pointer sequence:
- // * Mark previous position as dirty with rmdRectInsert()
- // * Update to new position
- // * Mark new position as dirty with rmdRectInsert()
- if (!pdata->args.full_shots &&
- mouse_pos_temp.x >=0 &&
- mouse_pos_temp.y >=0 &&
- mouse_pos_temp.width > 0 &&
- mouse_pos_temp.height > 0) {
- rmdRectInsert(&pdata->rect_root,&mouse_pos_temp);
- }
- if(pdata->args.xfixes_cursor){
- xcim=XFixesGetCursorImage(pdata->dpy);
- mouse_pos_abs.x=xcim->x-xcim->xhot;
- mouse_pos_abs.y=xcim->y-xcim->yhot;
- mouse_pos_abs.width=xcim->width;
- mouse_pos_abs.height=xcim->height;
- }
- else{
- XQueryPointer(pdata->dpy,
- pdata->specs.root,
- &root_ret,&child_ret,
- (int *)&mouse_pos_abs.x,(int *)&mouse_pos_abs.y,
- (int *)&mouse_pos_rel.x,(int *)&mouse_pos_rel.y,&msk_ret);
- }
-
- CLIP_DUMMY_POINTER_AREA(mouse_pos_abs, &temp_brwin, &mouse_pos_temp);
- if( mouse_pos_temp.x >=0 &&
- mouse_pos_temp.y >=0 &&
- mouse_pos_temp.width > 0 &&
- mouse_pos_temp.height > 0) {
-
- //there are 3 capture scenarios:
- // * Xdamage
- // * full-shots with double buffering
- // * full-shots on a single buffer
- //The last one cannot be reached through
- //this code (see above how the d_buf variable is set), but
- //even if it could, it would not be of interest regarding the
- //marking of the cursor area. Single buffer means full repaint
- //on every frame so there is no need for marking at all.
-
- if (!pdata->args.full_shots) {
-
- rmdRectInsert(&pdata->rect_root,&mouse_pos_temp);
-
- }
- else if(d_buff){
- unsigned char *back_buff=
- (img_sel)?((unsigned char*)image->data):
- ((unsigned char*)image_back->data);
-
- MARK_BUFFER_AREA( back_buff,
- (mouse_pos_temp.x-
- temp_brwin.rrect.x+
- pdata->enc_data->x_offset),
- (mouse_pos_temp.y-
- temp_brwin.rrect.y+
- pdata->enc_data->y_offset),
- mouse_pos_temp.width,
- mouse_pos_temp.height,
- (temp_brwin.rrect.width),
- pdata->specs.depth)
- }
- }
- }
- if(pdata->args.follow_mouse){
- rmdMoveCaptureArea(&pdata->brwin,
- mouse_pos_abs.x+
- ((pdata->args.xfixes_cursor)?xcim->xhot:0),
- mouse_pos_abs.y+
- ((pdata->args.xfixes_cursor)?xcim->yhot:0),
- pdata->specs.width,
- pdata->specs.height);
- if(!pdata->args.noframe){
- rmdMoveFrame(pdata->dpy,
- pdata->shaped_w,
- temp_brwin.rrect.x,
- temp_brwin.rrect.y);
-
- }
- }
-
- if(!pdata->args.full_shots){
- pthread_mutex_lock(&pdata->yuv_mutex);
- rmdUpdateImage(pdata->dpy,
- &pdata->enc_data->yuv,
- &pdata->specs,
- &pdata->rect_root,
- &temp_brwin,
- pdata->enc_data,
- image->data,
- pdata->args.noshared,
- &shminfo,
- pdata->shm_opcode,
- pdata->args.no_quick_subsample);
- rmdBlocksFromList(&pdata->rect_root,
- temp_brwin.rrect.x,
- temp_brwin.rrect.y,
- pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
- pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH);
- pthread_mutex_unlock(&pdata->yuv_mutex);
- }
- 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,
- ((!img_sel)?image:image_back),
- (temp_brwin.rrect.x),
- (temp_brwin.rrect.y),AllPlanes);
- }
- if(pdata->args.noshared){
- rmdGetZPixmap( pdata->dpy,
- pdata->specs.root,
- image->data,
- temp_brwin.rrect.x,
- temp_brwin.rrect.y,
- temp_brwin.rrect.width,
- temp_brwin.rrect.height);
- }
- pthread_mutex_lock(&pdata->yuv_mutex);
- for(i=0;i<blocknum_x*blocknum_y;i++){
- yblocks[i]=ublocks[i]=vblocks[i]=0;
- }
- UPDATE_YUV_BUFFER((&pdata->enc_data->yuv),
- front_buff,back_buff,
- (pdata->enc_data->x_offset),
- (pdata->enc_data->y_offset),
- (temp_brwin.rrect.width),
- (temp_brwin.rrect.height),
- pdata->args.no_quick_subsample,
- pdata->specs.depth);
- pthread_mutex_unlock(&pdata->yuv_mutex);
- }
- if(pdata->args.xfixes_cursor ||
- pdata->args.have_dummy_cursor){
- int mouse_xoffset,
- mouse_yoffset;
- //avoid segfaults
- CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&temp_brwin,
- &mouse_pos_temp);
- mouse_xoffset=mouse_pos_temp.x-mouse_pos_abs.x;
- mouse_yoffset=mouse_pos_temp.y-mouse_pos_abs.y;
- if((mouse_xoffset<0) || (mouse_xoffset>mouse_pos_abs.width))
- mouse_xoffset=0;
- if((mouse_yoffset<0) || (mouse_yoffset>mouse_pos_abs.height))
- mouse_yoffset=0;
- //draw the cursor
- if((mouse_pos_temp.x>=0)&&
- (mouse_pos_temp.y>=0)&&
- (mouse_pos_temp.width>0)&&
- (mouse_pos_temp.height>0)){
- if(pdata->args.xfixes_cursor){
- XFIXES_POINTER_TO_YUV((&pdata->enc_data->yuv),
- ((unsigned char*)xcim->pixels),
- (mouse_pos_temp.x-
- temp_brwin.rrect.x+
- pdata->enc_data->x_offset),
- (mouse_pos_temp.y-
- temp_brwin.rrect.y+
- pdata->enc_data->y_offset),
- mouse_pos_temp.width,
- mouse_pos_temp.height,
- mouse_xoffset,
- mouse_yoffset,
- (xcim->width-mouse_pos_temp.width));
- }
- else{
- DUMMY_POINTER_TO_YUV((&pdata->enc_data->yuv),
- pdata->dummy_pointer,
- (mouse_pos_temp.x-
- temp_brwin.rrect.x+
- pdata->enc_data->x_offset),
- (mouse_pos_temp.y-
- temp_brwin.rrect.y+
- pdata->enc_data->y_offset),
- mouse_pos_temp.width,
- mouse_pos_temp.height,
- mouse_xoffset,
- mouse_yoffset,
- pdata->npxl);
- }
- if(d_buff){
- //make previous cursor position dirty
- //on the currently front buffer (which
- //will be the back buffer next time it's
- //used)
- unsigned char *front_buff=
- (!img_sel)?((unsigned char*)image->data):
- ((unsigned char*)image_back->data);
-
- MARK_BUFFER_AREA( front_buff,
- (mouse_pos_temp.x-
- temp_brwin.rrect.x+
- pdata->enc_data->x_offset),
- (mouse_pos_temp.y-
- temp_brwin.rrect.y+
- pdata->enc_data->y_offset),
- mouse_pos_temp.width,
- mouse_pos_temp.height,
- (temp_brwin.rrect.width),
- pdata->specs.depth)
- }
-
- }
- if(pdata->args.xfixes_cursor){
- XFree(xcim);
- xcim=NULL;
- }
- }
- if(!pdata->args.full_shots){
- rmdClearList(&pdata->rect_root);
- }
- if (pdata->encoder_busy) {
- pdata->frames_lost++;
- }
- pthread_mutex_lock(&pdata->img_buff_ready_mutex);
- pthread_cond_broadcast(&pdata->image_buffer_ready);
- pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
- pdata->capture_busy = FALSE;
- }
-
- if(!pdata->args.noframe){
- XDestroyWindow(pdata->dpy,pdata->shaped_w);
- }
-
-
- 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);
- if(d_buff){
- XShmDetach (pdata->dpy, &shminfo_back);
- shmdt (shminfo_back.shmaddr);
- shmctl (shminfo_back.shmid, IPC_RMID, 0);
- }
- }
- pthread_exit(&errno);
+void *rmdGetFrame(ProgData *pdata) {
+ int i=0,
+ blocknum_x=pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
+ blocknum_y=pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH;
+ unsigned int msk_ret;
+ XRectangle mouse_pos_abs,mouse_pos_rel,mouse_pos_temp;
+ BRWindow temp_brwin;
+ Window root_ret, child_ret; //Frame
+ 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, img_sel,d_buff;
+
+ img_sel=d_buff=pdata->args.full_shots;
+
+ if ((init_img1 = rmdFirstFrame(pdata,&image,&shminfo) != 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 {
+ rmdPurgeCache(pdata->cache_data,!pdata->args.nosound);
+ }
+
+ exit(init_img1);
+ }
+
+ if (d_buff) {
+ if ((init_img2 = rmdFirstFrame(pdata, &image_back, &shminfo_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 {
+ rmdPurgeCache(pdata->cache_data, !pdata->args.nosound);
+ }
+
+ exit(init_img2);
+ }
+ }
+
+ if (!pdata->args.noframe) {
+ pdata->shaped_w=rmdFrameInit( pdata->dpy,
+ pdata->specs.screen,
+ pdata->specs.root,
+ pdata->brwin.rrect.x,
+ pdata->brwin.rrect.y,
+ pdata->brwin.rrect.width,
+ pdata->brwin.rrect.height);
+
+ XSelectInput(pdata->dpy,pdata->shaped_w,ExposureMask);
+ }
+
+ 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;
+ mouse_pos_abs.height=mouse_pos_temp.height=pdata->dummy_p_size;
+
+ //This is the the place where we call XSelectInput
+ //and arrange so that we listen for damage on all
+ //windows
+ rmdInitEventsPolling(pdata);
+
+ while (pdata->running) {
+
+ //if we are left behind we must not wait.
+ //also before actually pausing we must make sure the streams
+ //are synced. sound stops so this should only happen quickly.
+ if (pdata->avd>0 || pdata->args.nosound) {
+ pthread_mutex_lock(&pdata->time_mutex);
+ pthread_cond_wait(&pdata->time_cond, &pdata->time_mutex);
+ pthread_mutex_unlock(&pdata->time_mutex);
+
+ if (pdata->paused) {
+ //this is necessary since event loop processes
+ //the shortcuts which will unpause the program
+ rmdEventLoop(pdata);
+ continue;
+ }
+ }
+ //read all events and construct list with damage
+ //events (if not full_shots)
+ rmdEventLoop(pdata);
+
+ //switch back and front buffers (full_shots only)
+ if (d_buff)
+ img_sel=(img_sel)?0:1;
+
+ pdata->capture_busy = TRUE;
+
+ rmdBRWinCpy(&temp_brwin,&pdata->brwin);
+
+
+ if ( pdata->args.xfixes_cursor ||
+ pdata->args.have_dummy_cursor||
+ pdata->args.follow_mouse) {
+
+
+ // Pointer sequence:
+ // * Mark previous position as dirty with rmdRectInsert()
+ // * Update to new position
+ // * Mark new position as dirty with rmdRectInsert()
+ if ( !pdata->args.full_shots &&
+ mouse_pos_temp.x >=0 &&
+ mouse_pos_temp.y >=0 &&
+ mouse_pos_temp.width > 0 &&
+ mouse_pos_temp.height > 0) {
+ rmdRectInsert(&pdata->rect_root,&mouse_pos_temp);
+ }
+
+ if (pdata->args.xfixes_cursor) {
+ xcim=XFixesGetCursorImage(pdata->dpy);
+ mouse_pos_abs.x=xcim->x-xcim->xhot;
+ mouse_pos_abs.y=xcim->y-xcim->yhot;
+ mouse_pos_abs.width=xcim->width;
+ mouse_pos_abs.height=xcim->height;
+ } else {
+ XQueryPointer(pdata->dpy,
+ pdata->specs.root,
+ &root_ret,&child_ret,
+ (int *)&mouse_pos_abs.x,(int *)&mouse_pos_abs.y,
+ (int *)&mouse_pos_rel.x,(int *)&mouse_pos_rel.y,&msk_ret);
+ }
+
+ CLIP_DUMMY_POINTER_AREA(mouse_pos_abs, &temp_brwin, &mouse_pos_temp);
+ if ( mouse_pos_temp.x >=0 &&
+ mouse_pos_temp.y >=0 &&
+ mouse_pos_temp.width > 0 &&
+ mouse_pos_temp.height > 0) {
+
+ //there are 3 capture scenarios:
+ // * Xdamage
+ // * full-shots with double buffering
+ // * full-shots on a single buffer
+ //The last one cannot be reached through
+ //this code (see above how the d_buf variable is set), but
+ //even if it could, it would not be of interest regarding the
+ //marking of the cursor area. Single buffer means full repaint
+ //on every frame so there is no need for marking at all.
+
+ if (!pdata->args.full_shots) {
+ rmdRectInsert(&pdata->rect_root,&mouse_pos_temp);
+ } else if (d_buff) {
+ unsigned char *back_buff=
+ (img_sel)?((unsigned char*)image->data):
+ ((unsigned char*)image_back->data);
+
+ MARK_BUFFER_AREA(
+ back_buff,
+ (mouse_pos_temp.x- temp_brwin.rrect.x+ pdata->enc_data->x_offset),
+ (mouse_pos_temp.y- temp_brwin.rrect.y+ pdata->enc_data->y_offset),
+ mouse_pos_temp.width, mouse_pos_temp.height, (temp_brwin.rrect.width),
+ pdata->specs.depth
+ );
+ }
+ }
+ }
+ if (pdata->args.follow_mouse) {
+ rmdMoveCaptureArea( &pdata->brwin,
+ mouse_pos_abs.x+
+ ((pdata->args.xfixes_cursor)?xcim->xhot:0),
+ mouse_pos_abs.y+
+ ((pdata->args.xfixes_cursor)?xcim->yhot:0),
+ pdata->specs.width,
+ pdata->specs.height);
+
+ if (!pdata->args.noframe)
+ rmdMoveFrame( pdata->dpy,
+ pdata->shaped_w,
+ temp_brwin.rrect.x,
+ temp_brwin.rrect.y);
+ }
+
+ if (!pdata->args.full_shots) {
+ pthread_mutex_lock(&pdata->yuv_mutex);
+ rmdUpdateImage( pdata->dpy,
+ &pdata->enc_data->yuv,
+ &pdata->specs,
+ &pdata->rect_root,
+ &temp_brwin,
+ pdata->enc_data,
+ image->data,
+ pdata->args.noshared,
+ &shminfo,
+ pdata->shm_opcode,
+ pdata->args.no_quick_subsample);
+
+ rmdBlocksFromList( &pdata->rect_root,
+ temp_brwin.rrect.x,
+ temp_brwin.rrect.y,
+ pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
+ pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH);
+
+ pthread_mutex_unlock(&pdata->yuv_mutex);
+ } 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,
+ ((!img_sel)?image:image_back),
+ (temp_brwin.rrect.x),
+ (temp_brwin.rrect.y),AllPlanes);
+
+ if (pdata->args.noshared)
+ rmdGetZPixmap( pdata->dpy,
+ pdata->specs.root,
+ image->data,
+ temp_brwin.rrect.x,
+ temp_brwin.rrect.y,
+ temp_brwin.rrect.width,
+ temp_brwin.rrect.height);
+
+ pthread_mutex_lock(&pdata->yuv_mutex);
+ for(i=0;i<blocknum_x*blocknum_y;i++)
+ yblocks[i]=ublocks[i]=vblocks[i]=0;
+
+ UPDATE_YUV_BUFFER( &pdata->enc_data->yuv,
+ front_buff,back_buff,
+ pdata->enc_data->x_offset,
+ pdata->enc_data->y_offset,
+ temp_brwin.rrect.width,
+ temp_brwin.rrect.height,
+ pdata->args.no_quick_subsample,
+ pdata->specs.depth);
+
+ pthread_mutex_unlock(&pdata->yuv_mutex);
+ }
+
+ if (pdata->args.xfixes_cursor || pdata->args.have_dummy_cursor) {
+ int mouse_xoffset, mouse_yoffset;
+ //avoid segfaults
+ CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&temp_brwin, &mouse_pos_temp);
+ mouse_xoffset=mouse_pos_temp.x-mouse_pos_abs.x;
+ mouse_yoffset=mouse_pos_temp.y-mouse_pos_abs.y;
+ if ((mouse_xoffset<0) || (mouse_xoffset>mouse_pos_abs.width))
+ mouse_xoffset=0;
+
+ if ((mouse_yoffset<0) || (mouse_yoffset>mouse_pos_abs.height))
+ mouse_yoffset=0;
+
+ //draw the cursor
+ if ( (mouse_pos_temp.x>=0)&&
+ (mouse_pos_temp.y>=0)&&
+ (mouse_pos_temp.width>0)&&
+ (mouse_pos_temp.height>0)) {
+
+ if (pdata->args.xfixes_cursor) {
+ XFIXES_POINTER_TO_YUV(
+ &pdata->enc_data->yuv,
+ ((unsigned char*)xcim->pixels),
+ (mouse_pos_temp.x-
+ temp_brwin.rrect.x+
+ pdata->enc_data->x_offset),
+ (mouse_pos_temp.y-
+ temp_brwin.rrect.y+
+ pdata->enc_data->y_offset),
+ mouse_pos_temp.width,
+ mouse_pos_temp.height,
+ mouse_xoffset,
+ mouse_yoffset,
+ xcim->width-mouse_pos_temp.width
+ );
+ } else {
+ DUMMY_POINTER_TO_YUV(
+ &pdata->enc_data->yuv,
+ pdata->dummy_pointer,
+ mouse_pos_temp.x- temp_brwin.rrect.x+ pdata->enc_data->x_offset,
+ mouse_pos_temp.y- temp_brwin.rrect.y+ pdata->enc_data->y_offset,
+ mouse_pos_temp.width,
+ mouse_pos_temp.height,
+ mouse_xoffset,
+ mouse_yoffset,
+ pdata->npxl
+ );
+ }
+
+ if (d_buff) {
+ //make previous cursor position dirty
+ //on the currently front buffer (which
+ //will be the back buffer next time it's
+ //used)
+ unsigned char *front_buff = (!img_sel)?((unsigned char*)image->data):
+ ((unsigned char*)image_back->data);
+
+ MARK_BUFFER_AREA(
+ front_buff,
+ mouse_pos_temp.x- temp_brwin.rrect.x+ pdata->enc_data->x_offset,
+ mouse_pos_temp.y- temp_brwin.rrect.y+ pdata->enc_data->y_offset,
+ mouse_pos_temp.width,
+ mouse_pos_temp.height,
+ temp_brwin.rrect.width,
+ pdata->specs.depth
+ );
+ }
+
+ }
+
+ if (pdata->args.xfixes_cursor) {
+ XFree(xcim);
+ xcim=NULL;
+ }
+ }
+
+ if (!pdata->args.full_shots)
+ rmdClearList(&pdata->rect_root);
+
+ if (pdata->encoder_busy)
+ pdata->frames_lost++;
+
+ pthread_mutex_lock(&pdata->img_buff_ready_mutex);
+ pthread_cond_broadcast(&pdata->image_buffer_ready);
+ pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
+ pdata->capture_busy = FALSE;
+ }
+
+ if (!pdata->args.noframe)
+ XDestroyWindow(pdata->dpy,pdata->shaped_w);
+
+ 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);
+ if (d_buff) {
+ XShmDetach (pdata->dpy, &shminfo_back);
+ shmdt (shminfo_back.shmaddr);
+ shmctl (shminfo_back.shmid, IPC_RMID, 0);
+ }
+ }
+ pthread_exit(&errno);
}
-
diff --git a/recordmydesktop/src/rmd_getzpixmap.c b/recordmydesktop/src/rmd_getzpixmap.c
index 89cb48e..fa7c809 100644
--- a/recordmydesktop/src/rmd_getzpixmap.c
+++ b/recordmydesktop/src/rmd_getzpixmap.c
@@ -37,77 +37,84 @@
-int rmdGetZPixmap(Display *dpy,
- Window root,
- char *data,
- int x,
- int y,
- int width,
- int height){
- xGetImageReply reply;
- xGetImageReq *request;
- long nbytes;
-
- LockDisplay(dpy);
- GetReq(GetImage,request);
- request->drawable=root;
- request->x=x;
- request->y=y;
- request->width=width;
- request->height=height;
- request->planeMask=AllPlanes;
- request->format=ZPixmap;
- if((!_XReply(dpy,(xReply *)&reply,0,xFalse))||(!reply.length)){
- UnlockDisplay(dpy);
- SyncHandle();
- return 1;
- }
- nbytes=(long)reply.length<<2;
- _XReadPad(dpy,data,nbytes);
- UnlockDisplay(dpy);
- SyncHandle();
- return 0;
+int rmdGetZPixmap( Display *dpy,
+ Window root,
+ char *data,
+ int x,
+ int y,
+ int width,
+ int height) {
+
+ xGetImageReply reply;
+ xGetImageReq *request;
+ long nbytes;
+
+ LockDisplay(dpy);
+ GetReq(GetImage,request);
+ request->drawable=root;
+ request->x=x;
+ request->y=y;
+ request->width=width;
+ request->height=height;
+ request->planeMask=AllPlanes;
+ request->format=ZPixmap;
+
+ if (!_XReply(dpy,(xReply *)&reply,0,xFalse) || !reply.length) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return 1;
+ }
+
+ nbytes=(long)reply.length<<2;
+ _XReadPad(dpy,data,nbytes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return 0;
}
-int rmdGetZPixmapSHM(Display *dpy,
- Window root,
- XShmSegmentInfo *shminfo,
- int shm_opcode,
- char *data,
- int x,
- int y,
- int width,
- int height){
- xShmGetImageReply reply;
- xShmGetImageReq *request=NULL;
- long nbytes;
-
- LockDisplay(dpy);
- GetReq(ShmGetImage,request);
-
- request->reqType=shm_opcode;
- request->shmReqType=X_ShmGetImage;
- request->shmseg=shminfo->shmseg;
-
- request->drawable=root;
- request->x=x;
- request->y=y;
- request->width=width;
- request->height=height;
- request->planeMask=AllPlanes;
- request->format=ZPixmap;
- request->offset=data-shminfo->shmaddr;
-
- if((!_XReply(dpy,(xReply *)&reply,0,xFalse))||(!reply.length)){
- UnlockDisplay(dpy);
- SyncHandle();
- return 1;
- }
-
- nbytes=(long)reply.length << 2;
- _XReadPad(dpy,data,nbytes);
- UnlockDisplay(dpy);
- SyncHandle();
-
- return 0;
+int rmdGetZPixmapSHM( Display *dpy,
+ Window root,
+ XShmSegmentInfo *shminfo,
+ int shm_opcode,
+ char *data,
+ int x,
+ int y,
+ int width,
+ int height) {
+
+ xShmGetImageReply reply;
+ xShmGetImageReq *request=NULL;
+ long nbytes;
+
+ LockDisplay(dpy);
+ GetReq(ShmGetImage,request);
+
+ request->reqType=shm_opcode;
+ request->shmReqType=X_ShmGetImage;
+ request->shmseg=shminfo->shmseg;
+
+ request->drawable=root;
+ request->x=x;
+ request->y=y;
+ request->width=width;
+ request->height=height;
+ request->planeMask=AllPlanes;
+ request->format=ZPixmap;
+ request->offset=data-shminfo->shmaddr;
+
+ if ((!_XReply(dpy,(xReply *)&reply,0,xFalse))||(!reply.length)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return 1;
+ }
+
+ nbytes=(long)reply.length << 2;
+ _XReadPad(dpy,data,nbytes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return 0;
}
diff --git a/recordmydesktop/src/rmd_init_encoder.c b/recordmydesktop/src/rmd_init_encoder.c
index 036009f..dee0ba3 100644
--- a/recordmydesktop/src/rmd_init_encoder.c
+++ b/recordmydesktop/src/rmd_init_encoder.c
@@ -38,337 +38,313 @@
-
-
static void m_add_fishead_packet(ogg_stream_state *m_ogg_state) {
+ fishead_packet skel_fp;
- fishead_packet skel_fp;
-
- skel_fp.ptime_n=skel_fp.btime_n=0;
- skel_fp.ptime_d=skel_fp.btime_d=1000;
-
- add_fishead_to_stream(m_ogg_state,&skel_fp);
-
+ skel_fp.ptime_n=skel_fp.btime_n=0;
+ skel_fp.ptime_d=skel_fp.btime_d=1000;
+ add_fishead_to_stream(m_ogg_state,&skel_fp);
}
static int rmdIncrementalNaming(char **name) {
- struct stat buff;
- char *base_name__;
- int i=0,
- fname_length=strlen(*name)-4;
-
- base_name__=malloc(fname_length+1);
- strncpy(base_name__,*name,fname_length);
- base_name__[fname_length]='\0';
-
-
- //this will go on an endless loop if you have 65536?
- //files with the same name
- //or it will crash and die.anyone interested in trying ?
- while (stat(*name,&buff)==0){
- //create new name
- char *tname=malloc(strlen(*name)+10);
- char numbuf[8];
-
- strcpy(tname,base_name__);
- strcat(tname,"-");
- i++;
- snprintf( numbuf, 8, "%d", i );
- strcat(tname,numbuf);
- strcat(tname,".ogv");
- //save new name
-
- free(*name);
- *name=malloc(strlen(tname)+1);
- strcpy(*name,tname);
- free(tname);
- }
-
- free(base_name__);
- return 0;
+ struct stat buff;
+ char *base_name__;
+ int i=0, fname_length=strlen(*name)-4;
+
+ base_name__=malloc(fname_length+1);
+ strncpy(base_name__,*name,fname_length);
+ base_name__[fname_length]='\0';
+
+ //this will go on an endless loop if you have 65536?
+ //files with the same name
+ //or it will crash and die.anyone interested in trying ?
+ while (stat(*name,&buff)==0) {
+ //create new name
+ char *tname=malloc(strlen(*name)+10);
+ char numbuf[8];
+
+ strcpy(tname,base_name__);
+ strcat(tname,"-");
+ i++;
+ snprintf( numbuf, 8, "%d", i );
+ strcat(tname,numbuf);
+ strcat(tname,".ogv");
+ //save new name
+
+ free(*name);
+ *name=malloc(strlen(tname)+1);
+ strcpy(*name,tname);
+ free(tname);
+ }
+
+ free(base_name__);
+ return 0;
}
-void rmdInitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready){
-
- int y0,
- y1,
- y2,
- fname_length;
- ogg_stream_state m_ogg_skel;
- ogg_page skel_og_pg;
- fisbone_packet skel_fbv, //video fisbone packet
- skel_fba ; //audio fisbone packet
-
- (pdata)->enc_data=enc_data_t;
-
- fname_length=strlen(pdata->args.filename);
- if(!(fname_length>4 &&
- pdata->args.filename[fname_length-4] == '.' &&
- (pdata->args.filename[fname_length-3] == 'o' ||
- pdata->args.filename[fname_length-3] == 'O') &&
- (pdata->args.filename[fname_length-2] == 'g' ||
- pdata->args.filename[fname_length-2] == 'G') &&
- (pdata->args.filename[fname_length-1] == 'v' ||
- pdata->args.filename[fname_length-1] == 'V'))){
-
- char *new_name=malloc(fname_length+5);
- strcpy(new_name,pdata->args.filename);
- strcat(new_name,".ogv");
-
- free(pdata->args.filename);
- pdata->args.filename=new_name;
-
-
- }
-
- if (!pdata->args.overwrite) {
- rmdIncrementalNaming(&(pdata)->args.filename);
- fprintf(stderr, "Output file: %s\n", pdata->args.filename);
- }
-
- enc_data_t->fp=fopen((pdata)->args.filename,"w");
- if(enc_data_t->fp==NULL){
- fprintf(stderr,"Cannot open file %s for writting!\n",
- (pdata)->args.filename);
- exit(13);
- }
-
- //each stream must have a unique
- srand(time(NULL));
- y0=rand()+1;
- y1=rand()+1;
- y2=rand()+1;
- y2+=(y1==y2);
- y0=(((y0==y1)||(y0==y2))?(y1+y2):y0);
-
- //init ogg streams
- //skeleton first
- ogg_stream_init(&m_ogg_skel,y0);
- m_add_fishead_packet(&m_ogg_skel);
- if(ogg_stream_pageout(&m_ogg_skel,&skel_og_pg)!= 1){
- fprintf (stderr, "Internal Ogg library error.\n");
- exit (2);
- }
- fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
- fwrite(skel_og_pg.body,1,skel_og_pg.body_len,enc_data_t->fp);
-
-
-
- ogg_stream_init(&enc_data_t->m_ogg_ts,y1);
- if(!pdata->args.nosound)
- ogg_stream_init(&enc_data_t->m_ogg_vs,y2);
-
-
- theora_info_init(&enc_data_t->m_th_inf);
- enc_data_t->m_th_inf.frame_width = pdata->brwin.rrect.width;
- enc_data_t->m_th_inf.frame_height = pdata->brwin.rrect.height;
- enc_data_t->m_th_inf.width = ((enc_data_t->m_th_inf.frame_width + 15) >> 4) << 4;
- enc_data_t->m_th_inf.height = ((enc_data_t->m_th_inf.frame_height + 15) >> 4) << 4;
- enc_data_t->m_th_inf.offset_x = 0;
- enc_data_t->m_th_inf.offset_y = 0;
-
- enc_data_t->m_th_inf.fps_numerator = pdata->args.fps * 100.0;
- enc_data_t->m_th_inf.fps_denominator = 100;
- enc_data_t->m_th_inf.aspect_numerator = 1;
- enc_data_t->m_th_inf.aspect_denominator = 1;
-
- enc_data_t->m_th_inf.colorspace = OC_CS_UNSPECIFIED;
- enc_data_t->m_th_inf.pixelformat = OC_PF_420;
-
- enc_data_t->m_th_inf.target_bitrate = pdata->args.v_bitrate;
- enc_data_t->m_th_inf.quality = pdata->args.v_quality;
- enc_data_t->m_th_inf.dropframes_p = 0;
- enc_data_t->m_th_inf.quick_p = 1;
- enc_data_t->m_th_inf.keyframe_auto_p = 1;
- enc_data_t->m_th_inf.keyframe_frequency = 64;
- enc_data_t->m_th_inf.keyframe_frequency_force = 64;
- enc_data_t->m_th_inf.keyframe_data_target_bitrate = enc_data_t->m_th_inf.quality * 1.5;
- enc_data_t->m_th_inf.keyframe_auto_threshold = 80;
- enc_data_t->m_th_inf.keyframe_mindistance = 8;
- enc_data_t->m_th_inf.noise_sensitivity = 1;
- enc_data_t->m_th_inf.sharpness = 2;
-
- theora_encode_init(&enc_data_t->m_th_st,&enc_data_t->m_th_inf);
-
-
- if(!pdata->args.nosound){
- int ret;
- vorbis_info_init(&enc_data_t->m_vo_inf);
- ret = vorbis_encode_init_vbr(&enc_data_t->m_vo_inf,
- pdata->args.channels,
- pdata->args.frequency,
- (float)pdata->args.s_quality*0.1);
- if(ret){
- fprintf(stderr,"Error while setting up vorbis stream quality!\n");
- exit(2);
- }
- vorbis_comment_init(&enc_data_t->m_vo_cmmnt);
- vorbis_analysis_init(&enc_data_t->m_vo_dsp,&enc_data_t->m_vo_inf);
- vorbis_block_init(&enc_data_t->m_vo_dsp,&enc_data_t->m_vo_block);
- }
-
-
- theora_encode_header(&enc_data_t->m_th_st,&enc_data_t->m_ogg_pckt1);
- ogg_stream_packetin(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pckt1);
- if(ogg_stream_pageout(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pg)!=1){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(2);
- }
- fwrite(enc_data_t->m_ogg_pg.header,1,
- enc_data_t->m_ogg_pg.header_len,
- enc_data_t->fp);
- fwrite(enc_data_t->m_ogg_pg.body,1,
- enc_data_t->m_ogg_pg.body_len,
- enc_data_t->fp);
-
- theora_comment_init(&enc_data_t->m_th_cmmnt);
- theora_comment_add_tag(&enc_data_t->m_th_cmmnt,"recordMyDesktop",VERSION);
- theora_encode_comment(&enc_data_t->m_th_cmmnt,&enc_data_t->m_ogg_pckt1);
- ogg_stream_packetin(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pckt1);
- theora_encode_tables(&enc_data_t->m_th_st,&enc_data_t->m_ogg_pckt1);
- ogg_stream_packetin(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pckt1);
-
-
- if(!pdata->args.nosound){
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
-
- vorbis_analysis_headerout(&enc_data_t->m_vo_dsp,
- &enc_data_t->m_vo_cmmnt,
- &header,&header_comm,
- &header_code);
- ogg_stream_packetin(&enc_data_t->m_ogg_vs,&header);
- if(ogg_stream_pageout(&enc_data_t->m_ogg_vs,&enc_data_t->m_ogg_pg)!=1){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(2);
- }
- fwrite(enc_data_t->m_ogg_pg.header,1,
- enc_data_t->m_ogg_pg.header_len,
- enc_data_t->fp);
- fwrite(enc_data_t->m_ogg_pg.body,1,
- enc_data_t->m_ogg_pg.body_len,
- enc_data_t->fp);
-
- ogg_stream_packetin(&enc_data_t->m_ogg_vs,&header_comm);
- ogg_stream_packetin(&enc_data_t->m_ogg_vs,&header_code);
- }
-
- //fishbone packets go here
- memset(&skel_fbv,0,sizeof(skel_fbv));
- skel_fbv.serial_no=enc_data_t->m_ogg_ts.serialno;
- skel_fbv.nr_header_packet=3;
- skel_fbv.granule_rate_n=enc_data_t->m_th_inf.fps_numerator;
- skel_fbv.granule_rate_d=enc_data_t->m_th_inf.fps_denominator;
- skel_fbv.start_granule=0;
- skel_fbv.preroll=0;
- skel_fbv.granule_shift=theora_granule_shift(&enc_data_t->m_th_inf);
- add_message_header_field(&skel_fbv,
- "Content-Type",
- "video/theora");
-
- add_fisbone_to_stream(&m_ogg_skel,&skel_fbv);
-
- if(!pdata->args.nosound){
-
- memset(&skel_fba,0,sizeof(skel_fba));
- skel_fba.serial_no=enc_data_t->m_ogg_vs.serialno;
- skel_fba.nr_header_packet=3;
- skel_fba.granule_rate_n=pdata->args.frequency;
- skel_fba.granule_rate_d=(ogg_int64_t)1;
- skel_fba.start_granule=0;
- skel_fba.preroll=2;
- skel_fba.granule_shift=0;
- add_message_header_field(&skel_fba,
- "Content-Type",
- "audio/vorbis");
-
- add_fisbone_to_stream(&m_ogg_skel,&skel_fba);
-
- }
-
- while(1){
- int result = ogg_stream_flush(&m_ogg_skel, &skel_og_pg);
- if(result<0){
- fprintf (stderr, "Internal Ogg library error.\n");
- exit(2);
- }
- if(result==0)
- break;
- fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
- fwrite(skel_og_pg.body,1,skel_og_pg.body_len,enc_data_t->fp);
+void rmdInitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready) {
+ int y0, y1, y2, fname_length;
+ ogg_stream_state m_ogg_skel;
+ ogg_page skel_og_pg;
+ fisbone_packet skel_fbv, //video fisbone packet
+ skel_fba; //audio fisbone packet
+ const char *fname;
+
+ (pdata)->enc_data=enc_data_t;
+
+ fname = pdata->args.filename;
+ fname_length=strlen(fname);
+ if (!(fname_length>4 && !strcasecmp(&fname[fname_length-3], "ogv"))) {
+
+ char *new_name=malloc(fname_length+5);
+ strcpy(new_name,fname);
+ strcat(new_name,".ogv");
+
+ free(pdata->args.filename);
+ pdata->args.filename=new_name;
}
+ if (!pdata->args.overwrite) {
+ rmdIncrementalNaming(&(pdata)->args.filename);
+ fprintf(stderr, "Output file: %s\n", pdata->args.filename);
+ }
+
+ enc_data_t->fp=fopen((pdata)->args.filename,"w");
+ if (enc_data_t->fp==NULL) {
+ fprintf(stderr,"Cannot open file %s for writting!\n", (pdata)->args.filename);
+ exit(13);
+ }
+ //each stream must have a unique
+ srand(time(NULL));
+ y0=rand()+1;
+ y1=rand()+1;
+ y2=rand()+1;
+ y2+=(y1==y2);
+ y0=(((y0==y1)||(y0==y2))?(y1+y2):y0);
+
+ //init ogg streams
+ //skeleton first
+ ogg_stream_init(&m_ogg_skel,y0);
+ m_add_fishead_packet(&m_ogg_skel);
+ if (ogg_stream_pageout(&m_ogg_skel,&skel_og_pg)!= 1) {
+ fprintf (stderr, "Internal Ogg library error.\n");
+ exit (2);
+ }
+ fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
+ fwrite(skel_og_pg.body,1,skel_og_pg.body_len,enc_data_t->fp);
+
+
+
+ ogg_stream_init(&enc_data_t->m_ogg_ts,y1);
+ if (!pdata->args.nosound)
+ ogg_stream_init(&enc_data_t->m_ogg_vs,y2);
+
+ theora_info_init(&enc_data_t->m_th_inf);
+ enc_data_t->m_th_inf.frame_width = pdata->brwin.rrect.width;
+ enc_data_t->m_th_inf.frame_height = pdata->brwin.rrect.height;
+ enc_data_t->m_th_inf.width = ((enc_data_t->m_th_inf.frame_width + 15) >> 4) << 4;
+ enc_data_t->m_th_inf.height = ((enc_data_t->m_th_inf.frame_height + 15) >> 4) << 4;
+ enc_data_t->m_th_inf.offset_x = 0;
+ enc_data_t->m_th_inf.offset_y = 0;
+
+ enc_data_t->m_th_inf.fps_numerator = pdata->args.fps * 100.0;
+ enc_data_t->m_th_inf.fps_denominator = 100;
+ enc_data_t->m_th_inf.aspect_numerator = 1;
+ enc_data_t->m_th_inf.aspect_denominator = 1;
+
+ enc_data_t->m_th_inf.colorspace = OC_CS_UNSPECIFIED;
+ enc_data_t->m_th_inf.pixelformat = OC_PF_420;
+
+ enc_data_t->m_th_inf.target_bitrate = pdata->args.v_bitrate;
+ enc_data_t->m_th_inf.quality = pdata->args.v_quality;
+ enc_data_t->m_th_inf.dropframes_p = 0;
+ enc_data_t->m_th_inf.quick_p = 1;
+ enc_data_t->m_th_inf.keyframe_auto_p = 1;
+ enc_data_t->m_th_inf.keyframe_frequency = 64;
+ enc_data_t->m_th_inf.keyframe_frequency_force = 64;
+ enc_data_t->m_th_inf.keyframe_data_target_bitrate = enc_data_t->m_th_inf.quality * 1.5;
+ enc_data_t->m_th_inf.keyframe_auto_threshold = 80;
+ enc_data_t->m_th_inf.keyframe_mindistance = 8;
+ enc_data_t->m_th_inf.noise_sensitivity = 1;
+ enc_data_t->m_th_inf.sharpness = 2;
+
+ theora_encode_init(&enc_data_t->m_th_st,&enc_data_t->m_th_inf);
+
+
+ if (!pdata->args.nosound) {
+ int ret;
+ vorbis_info_init(&enc_data_t->m_vo_inf);
+ ret = vorbis_encode_init_vbr( &enc_data_t->m_vo_inf,
+ pdata->args.channels,
+ pdata->args.frequency,
+ (float)pdata->args.s_quality*0.1);
+ if (ret) {
+ fprintf(stderr,"Error while setting up vorbis stream quality!\n");
+ exit(2);
+ }
+ vorbis_comment_init(&enc_data_t->m_vo_cmmnt);
+ vorbis_analysis_init(&enc_data_t->m_vo_dsp,&enc_data_t->m_vo_inf);
+ vorbis_block_init(&enc_data_t->m_vo_dsp,&enc_data_t->m_vo_block);
+ }
- while(1){
- int result = ogg_stream_flush(&enc_data_t->m_ogg_ts,
- &enc_data_t->m_ogg_pg);
- if(result<0){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(2);
- }
- if(result==0)break;
- fwrite(enc_data_t->m_ogg_pg.header,1,
- enc_data_t->m_ogg_pg.header_len,
- enc_data_t->fp);
- fwrite(enc_data_t->m_ogg_pg.body,1,
- enc_data_t->m_ogg_pg.body_len,
- enc_data_t->fp);
- }
-
- if(!pdata->args.nosound){
- while(1){
- int result=ogg_stream_flush(&enc_data_t->m_ogg_vs,
- &enc_data_t->m_ogg_pg);
- if(result<0){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(2);
- }
- if(result==0)break;
- fwrite(enc_data_t->m_ogg_pg.header,1,
- enc_data_t->m_ogg_pg.header_len,
- enc_data_t->fp);
- fwrite(enc_data_t->m_ogg_pg.body,1,
- enc_data_t->m_ogg_pg.body_len,
- enc_data_t->fp);
- }
- }
-
- //skeleton eos
- add_eos_packet_to_stream(&m_ogg_skel);
- if(ogg_stream_flush(&m_ogg_skel,&skel_og_pg)<0){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(2);
- }
- fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
- fwrite(skel_og_pg.body,1,skel_og_pg.body_len,enc_data_t->fp);
-
-
- //theora buffer allocation, if any
- if(!buffer_ready){
- enc_data_t->yuv.y=(unsigned char *)malloc(enc_data_t->m_th_inf.height*
- enc_data_t->m_th_inf.width);
- enc_data_t->yuv.u=(unsigned char *)malloc(enc_data_t->m_th_inf.height*
- enc_data_t->m_th_inf.width/4);
- enc_data_t->yuv.v=(unsigned char *)malloc(enc_data_t->m_th_inf.height*
- enc_data_t->m_th_inf.width/4);
- enc_data_t->yuv.y_width=enc_data_t->m_th_inf.width;
- enc_data_t->yuv.y_height=enc_data_t->m_th_inf.height;
- enc_data_t->yuv.y_stride=enc_data_t->m_th_inf.width;
-
- enc_data_t->yuv.uv_width=enc_data_t->m_th_inf.width/2;
- enc_data_t->yuv.uv_height=enc_data_t->m_th_inf.height/2;
- enc_data_t->yuv.uv_stride=enc_data_t->m_th_inf.width/2;
- enc_data_t->x_offset=enc_data_t->m_th_inf.offset_x;
- enc_data_t->y_offset=enc_data_t->m_th_inf.offset_y;
- }
- theora_info_clear(&enc_data_t->m_th_inf);
-}
+ theora_encode_header(&enc_data_t->m_th_st,&enc_data_t->m_ogg_pckt1);
+ ogg_stream_packetin(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pckt1);
+ if (ogg_stream_pageout(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pg)!=1) {
+ fprintf(stderr,"Internal Ogg library error.\n");
+ exit(2);
+ }
+ fwrite(enc_data_t->m_ogg_pg.header,1,
+ enc_data_t->m_ogg_pg.header_len,
+ enc_data_t->fp);
+ fwrite(enc_data_t->m_ogg_pg.body,1,
+ enc_data_t->m_ogg_pg.body_len,
+ enc_data_t->fp);
+
+ theora_comment_init(&enc_data_t->m_th_cmmnt);
+ theora_comment_add_tag(&enc_data_t->m_th_cmmnt,"recordMyDesktop",VERSION);
+ theora_encode_comment(&enc_data_t->m_th_cmmnt,&enc_data_t->m_ogg_pckt1);
+ ogg_stream_packetin(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pckt1);
+ theora_encode_tables(&enc_data_t->m_th_st,&enc_data_t->m_ogg_pckt1);
+ ogg_stream_packetin(&enc_data_t->m_ogg_ts,&enc_data_t->m_ogg_pckt1);
+
+ if (!pdata->args.nosound) {
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_analysis_headerout(&enc_data_t->m_vo_dsp,
+ &enc_data_t->m_vo_cmmnt,
+ &header,&header_comm,
+ &header_code);
+ ogg_stream_packetin(&enc_data_t->m_ogg_vs,&header);
+ if (ogg_stream_pageout(&enc_data_t->m_ogg_vs,&enc_data_t->m_ogg_pg)!=1) {
+ fprintf(stderr,"Internal Ogg library error.\n");
+ exit(2);
+ }
+
+ fwrite(enc_data_t->m_ogg_pg.header,1,
+ enc_data_t->m_ogg_pg.header_len,
+ enc_data_t->fp);
+
+ fwrite(enc_data_t->m_ogg_pg.body,1,
+ enc_data_t->m_ogg_pg.body_len,
+ enc_data_t->fp);
+
+ ogg_stream_packetin(&enc_data_t->m_ogg_vs,&header_comm);
+ ogg_stream_packetin(&enc_data_t->m_ogg_vs,&header_code);
+ }
+
+ //fishbone packets go here
+ memset(&skel_fbv,0,sizeof(skel_fbv));
+ skel_fbv.serial_no=enc_data_t->m_ogg_ts.serialno;
+ skel_fbv.nr_header_packet=3;
+ skel_fbv.granule_rate_n=enc_data_t->m_th_inf.fps_numerator;
+ skel_fbv.granule_rate_d=enc_data_t->m_th_inf.fps_denominator;
+ skel_fbv.start_granule=0;
+ skel_fbv.preroll=0;
+ skel_fbv.granule_shift=theora_granule_shift(&enc_data_t->m_th_inf);
+ add_message_header_field(&skel_fbv, "Content-Type", "video/theora");
+
+ add_fisbone_to_stream(&m_ogg_skel,&skel_fbv);
+
+ if (!pdata->args.nosound) {
+
+ memset(&skel_fba,0,sizeof(skel_fba));
+ skel_fba.serial_no=enc_data_t->m_ogg_vs.serialno;
+ skel_fba.nr_header_packet=3;
+ skel_fba.granule_rate_n=pdata->args.frequency;
+ skel_fba.granule_rate_d=(ogg_int64_t)1;
+ skel_fba.start_granule=0;
+ skel_fba.preroll=2;
+ skel_fba.granule_shift=0;
+ add_message_header_field(&skel_fba, "Content-Type", "audio/vorbis");
+
+ add_fisbone_to_stream(&m_ogg_skel,&skel_fba);
+ }
+
+ while (1) {
+ int result = ogg_stream_flush(&m_ogg_skel, &skel_og_pg);
+ if (result<0) {
+ fprintf (stderr, "Internal Ogg library error.\n");
+ exit(2);
+ }
+
+ if (result==0)
+ break;
+ fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
+ fwrite(skel_og_pg.body,1,skel_og_pg.body_len,enc_data_t->fp);
+ }
+ while (1) {
+ int result = ogg_stream_flush(&enc_data_t->m_ogg_ts,
+ &enc_data_t->m_ogg_pg);
+ if (result<0) {
+ fprintf(stderr,"Internal Ogg library error.\n");
+ exit(2);
+ }
+
+ if (result==0)
+ break;
+
+ fwrite( enc_data_t->m_ogg_pg.header,1,
+ enc_data_t->m_ogg_pg.header_len,
+ enc_data_t->fp);
+ fwrite( enc_data_t->m_ogg_pg.body,1,
+ enc_data_t->m_ogg_pg.body_len,
+ enc_data_t->fp);
+ }
+ if (!pdata->args.nosound) {
+ while (1) {
+ int result=ogg_stream_flush(&enc_data_t->m_ogg_vs,
+ &enc_data_t->m_ogg_pg);
+ if (result<0) {
+ fprintf(stderr,"Internal Ogg library error.\n");
+ exit(2);
+ }
+
+ if (result==0)
+ break;
+
+ fwrite( enc_data_t->m_ogg_pg.header,1,
+ enc_data_t->m_ogg_pg.header_len,
+ enc_data_t->fp);
+ fwrite( enc_data_t->m_ogg_pg.body,1,
+ enc_data_t->m_ogg_pg.body_len,
+ enc_data_t->fp);
+ }
+ }
+ //skeleton eos
+ add_eos_packet_to_stream(&m_ogg_skel);
+ if (ogg_stream_flush(&m_ogg_skel,&skel_og_pg)<0) {
+ fprintf(stderr,"Internal Ogg library error.\n");
+ exit(2);
+ }
+ fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
+
+
+ //theora buffer allocation, if any
+ if (!buffer_ready) {
+ enc_data_t->yuv.y=(unsigned char *)malloc(enc_data_t->m_th_inf.height*
+ enc_data_t->m_th_inf.width);
+ enc_data_t->yuv.u=(unsigned char *)malloc(enc_data_t->m_th_inf.height*
+ enc_data_t->m_th_inf.width/4);
+ enc_data_t->yuv.v=(unsigned char *)malloc(enc_data_t->m_th_inf.height*
+ enc_data_t->m_th_inf.width/4);
+ enc_data_t->yuv.y_width=enc_data_t->m_th_inf.width;
+ enc_data_t->yuv.y_height=enc_data_t->m_th_inf.height;
+ enc_data_t->yuv.y_stride=enc_data_t->m_th_inf.width;
+
+ enc_data_t->yuv.uv_width=enc_data_t->m_th_inf.width/2;
+ enc_data_t->yuv.uv_height=enc_data_t->m_th_inf.height/2;
+ enc_data_t->yuv.uv_stride=enc_data_t->m_th_inf.width/2;
+ enc_data_t->x_offset=enc_data_t->m_th_inf.offset_x;
+ enc_data_t->y_offset=enc_data_t->m_th_inf.offset_y;
+ }
+ theora_info_clear(&enc_data_t->m_th_inf);
+}
diff --git a/recordmydesktop/src/rmd_initialize_data.c b/recordmydesktop/src/rmd_initialize_data.c
index 4fef385..69f4fce 100644
--- a/recordmydesktop/src/rmd_initialize_data.c
+++ b/recordmydesktop/src/rmd_initialize_data.c
@@ -43,220 +43,211 @@
#ifdef HAVE_LIBASOUND
static void rmdFixBufferSize(snd_pcm_uframes_t *buffsize) {
- snd_pcm_uframes_t buffsize_t=*buffsize,
+ snd_pcm_uframes_t buffsize_t=*buffsize,
#else
static void rmdFixBufferSize(u_int32_t *buffsize) {
- u_int32_t buffsize_t=*buffsize,
+ u_int32_t buffsize_t=*buffsize,
#endif
- buffsize_ret=1;
- while(buffsize_t>1){
- buffsize_t>>=1;
- buffsize_ret<<=1;
- }
- fprintf(stderr,"Buffer size adjusted to %d from %d frames.\n",
- (int)buffsize_ret,(int)*buffsize);
+ buffsize_ret=1;
+
+ while (buffsize_t>1) {
+ buffsize_t>>=1;
+ buffsize_ret<<=1;
+ }
+ fprintf(stderr,"Buffer size adjusted to %d from %d frames.\n",
+ (int)buffsize_ret,(int)*buffsize);
}
-int rmdInitializeData(ProgData *pdata,
- EncData *enc_data,
- CacheData *cache_data){
- int i;
-
- fprintf(stderr,"Initializing...\n");
- rmdMakeMatrices();
- if(pdata->args.have_dummy_cursor){
- pdata->dummy_pointer = rmdMakeDummyPointer(pdata->dpy,
- &pdata->specs,
- 16,
- pdata->args.cursor_color,
- 0,
- &pdata->npxl);
- pdata->dummy_p_size=16;
- }
- else
- pdata->dummy_p_size=0;
-
-
- pdata->rect_root=NULL;
- pthread_mutex_init(&pdata->sound_buffer_mutex,NULL);
- pthread_mutex_init(&pdata->snd_buff_ready_mutex,NULL);
- pthread_mutex_init(&pdata->img_buff_ready_mutex,NULL);
- pthread_mutex_init(&pdata->theora_lib_mutex,NULL);
- pthread_mutex_init(&pdata->vorbis_lib_mutex,NULL);
- pthread_mutex_init(&pdata->libogg_mutex,NULL);
- pthread_mutex_init(&pdata->yuv_mutex,NULL);
- pthread_mutex_init(&pdata->pause_mutex, NULL);
- pthread_mutex_init(&pdata->time_mutex, NULL);
- pthread_cond_init(&pdata->time_cond,NULL);
- pthread_cond_init(&pdata->pause_cond,NULL);
- pthread_cond_init(&pdata->image_buffer_ready,NULL);
- pthread_cond_init(&pdata->sound_data_read,NULL);
- pthread_cond_init(&pdata->theora_lib_clean,NULL);
- pthread_cond_init(&pdata->vorbis_lib_clean,NULL);
- pdata->th_encoding_clean=pdata->v_encoding_clean=1;
- pdata->avd=0;
- pdata->sound_buffer=NULL;
- pdata->running = TRUE;
- pdata->paused = FALSE;
- pdata->aborted = FALSE;
- pdata->pause_state_changed = FALSE;
- pdata->frames_total = 0;
- pdata->frames_lost = 0;
- pdata->encoder_busy = FALSE;
- pdata->capture_busy = FALSE;
-
- if(!pdata->args.nosound){
- if(!pdata->args.use_jack){
- rmdFixBufferSize(&pdata->args.buffsize);
+int rmdInitializeData(ProgData *pdata, EncData *enc_data, CacheData *cache_data) {
+ int i;
+
+ fprintf(stderr,"Initializing...\n");
+ rmdMakeMatrices();
+ if (pdata->args.have_dummy_cursor) {
+ pdata->dummy_pointer = rmdMakeDummyPointer( pdata->dpy,
+ &pdata->specs,
+ 16,
+ pdata->args.cursor_color,
+ 0,
+ &pdata->npxl);
+ pdata->dummy_p_size=16;
+ } else
+ pdata->dummy_p_size=0;
+
+ pdata->rect_root=NULL;
+ pthread_mutex_init(&pdata->sound_buffer_mutex,NULL);
+ pthread_mutex_init(&pdata->snd_buff_ready_mutex,NULL);
+ pthread_mutex_init(&pdata->img_buff_ready_mutex,NULL);
+ pthread_mutex_init(&pdata->theora_lib_mutex,NULL);
+ pthread_mutex_init(&pdata->vorbis_lib_mutex,NULL);
+ pthread_mutex_init(&pdata->libogg_mutex,NULL);
+ pthread_mutex_init(&pdata->yuv_mutex,NULL);
+ pthread_mutex_init(&pdata->pause_mutex, NULL);
+ pthread_mutex_init(&pdata->time_mutex, NULL);
+ pthread_cond_init(&pdata->time_cond,NULL);
+ pthread_cond_init(&pdata->pause_cond,NULL);
+ pthread_cond_init(&pdata->image_buffer_ready,NULL);
+ pthread_cond_init(&pdata->sound_data_read,NULL);
+ pthread_cond_init(&pdata->theora_lib_clean,NULL);
+ pthread_cond_init(&pdata->vorbis_lib_clean,NULL);
+ pdata->th_encoding_clean=pdata->v_encoding_clean=1;
+ pdata->avd=0;
+ pdata->sound_buffer=NULL;
+ pdata->running = TRUE;
+ pdata->paused = FALSE;
+ pdata->aborted = FALSE;
+ pdata->pause_state_changed = FALSE;
+ pdata->frames_total = 0;
+ pdata->frames_lost = 0;
+ pdata->encoder_busy = FALSE;
+ pdata->capture_busy = FALSE;
+
+ if (!pdata->args.nosound) {
+ if (!pdata->args.use_jack) {
+ rmdFixBufferSize(&pdata->args.buffsize);
#ifdef HAVE_LIBASOUND
- pdata->sound_handle=rmdOpenDev(pdata->args.device,
- &pdata->args.channels,
- &pdata->args.frequency,
- &pdata->args.buffsize,
- &pdata->periodsize,
- &pdata->periodtime,
- &pdata->hard_pause);
- pdata->sound_framesize=((snd_pcm_format_width(
- SND_PCM_FORMAT_S16_LE))/8)*
- pdata->args.channels;
-
- if(pdata->sound_handle==NULL){
+ pdata->sound_handle=rmdOpenDev(pdata->args.device,
+ &pdata->args.channels,
+ &pdata->args.frequency,
+ &pdata->args.buffsize,
+ &pdata->periodsize,
+ &pdata->periodtime,
+ &pdata->hard_pause);
+ pdata->sound_framesize=((snd_pcm_format_width(
+ SND_PCM_FORMAT_S16_LE))/8)*
+ pdata->args.channels;
+
+ if (pdata->sound_handle==NULL) {
#else
- pdata->sound_handle=rmdOpenDev(pdata->args.device,
- pdata->args.channels,
- pdata->args.frequency);
- pdata->periodtime=(1000000*pdata->args.buffsize)/
- ((pdata->args.channels<<1)*pdata->args.frequency);
- //when using OSS periodsize serves as an alias of buffsize
- pdata->periodsize=pdata->args.buffsize;
- pdata->sound_framesize=pdata->args.channels<<1;
- if(pdata->sound_handle<0){
+ pdata->sound_handle=rmdOpenDev( pdata->args.device,
+ pdata->args.channels,
+ pdata->args.frequency);
+
+ pdata->periodtime=(1000000*pdata->args.buffsize)/
+ ((pdata->args.channels<<1)*pdata->args.frequency);
+ //when using OSS periodsize serves as an alias of buffsize
+ pdata->periodsize=pdata->args.buffsize;
+ pdata->sound_framesize=pdata->args.channels<<1;
+ if (pdata->sound_handle<0) {
#endif
- fprintf(stderr,"Error while opening/configuring soundcard %s\n"
- "Try running with the --no-sound or specify a "
- "correct device.\n",
- pdata->args.device);
- return 3;
- }
- }
- else{
+ fprintf(stderr,"Error while opening/configuring soundcard %s\n"
+ "Try running with the --no-sound or specify a "
+ "correct device.\n",
+ pdata->args.device);
+ return 3;
+ }
+ } else {
#ifdef HAVE_LIBJACK
- int jack_error=0;
- pdata->jdata->port_names=pdata->args.jack_port_names;
- pdata->jdata->nports=pdata->args.jack_nports;
- pdata->jdata->ringbuffer_secs=pdata->args.jack_ringbuffer_secs;
- pdata->jdata->snd_buff_ready_mutex=&pdata->snd_buff_ready_mutex;
- pdata->jdata->sound_data_read=&pdata->sound_data_read;
- pdata->jdata->capture_started=0;
-
- if((jack_error=rmdStartJackClient(pdata->jdata))!=0)
- return jack_error;
-
- pdata->args.buffsize=pdata->jdata->buffersize;
- pdata->periodsize=pdata->args.buffsize;
- pdata->args.frequency=pdata->jdata->frequency;
- pdata->args.channels=pdata->jdata->nports;
- pdata->periodtime=(1000000*pdata->args.buffsize)/
- pdata->args.frequency;
- pdata->sound_framesize=sizeof(jack_default_audio_sample_t)*
- pdata->jdata->nports;
+ int jack_error=0;
+ pdata->jdata->port_names=pdata->args.jack_port_names;
+ pdata->jdata->nports=pdata->args.jack_nports;
+ pdata->jdata->ringbuffer_secs=pdata->args.jack_ringbuffer_secs;
+ pdata->jdata->snd_buff_ready_mutex=&pdata->snd_buff_ready_mutex;
+ pdata->jdata->sound_data_read=&pdata->sound_data_read;
+ pdata->jdata->capture_started=0;
+
+ if ((jack_error=rmdStartJackClient(pdata->jdata))!=0)
+ return jack_error;
+
+ pdata->args.buffsize=pdata->jdata->buffersize;
+ pdata->periodsize=pdata->args.buffsize;
+ pdata->args.frequency=pdata->jdata->frequency;
+ pdata->args.channels=pdata->jdata->nports;
+ pdata->periodtime=(1000000*pdata->args.buffsize)/
+ pdata->args.frequency;
+ pdata->sound_framesize=sizeof(jack_default_audio_sample_t)*
+ pdata->jdata->nports;
#else
- fprintf(stderr,"Should not be here!\n");
- exit(-1);
+ fprintf(stderr,"Should not be here!\n");
+ exit(-1);
#endif
- }
- }
+ }
+ }
- if(pdata->args.encOnTheFly)
- rmdInitEncoder(pdata,enc_data,0);
- else
- rmdInitCacheData(pdata,enc_data,cache_data);
+ if(pdata->args.encOnTheFly)
+ rmdInitEncoder(pdata, enc_data, 0);
+ else
+ rmdInitCacheData(pdata, enc_data, cache_data);
- for(i=0;i<(pdata->enc_data->yuv.y_width*pdata->enc_data->yuv.y_height);i++)
- pdata->enc_data->yuv.y[i]=0;
- for(i=0;
- i<(pdata->enc_data->yuv.uv_width*pdata->enc_data->yuv.uv_height);
- i++){
- pdata->enc_data->yuv.v[i]=pdata->enc_data->yuv.u[i]=127;
- }
+ for(i=0;i<(pdata->enc_data->yuv.y_width*pdata->enc_data->yuv.y_height);i++)
+ pdata->enc_data->yuv.y[i]=0;
- yblocks=malloc(sizeof(u_int32_t)*(pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH)*
- (pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH));
- ublocks=malloc(sizeof(u_int32_t)*(pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH)*
- (pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH));
- vblocks=malloc(sizeof(u_int32_t)*(pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH)*
- (pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH));
+ for(i=0; i<(pdata->enc_data->yuv.uv_width*pdata->enc_data->yuv.uv_height); i++)
+ pdata->enc_data->yuv.v[i]=pdata->enc_data->yuv.u[i]=127;
- pdata->frametime=(1000000)/pdata->args.fps;
- return 0;
+ yblocks=malloc(sizeof(u_int32_t)*(pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH)*
+ (pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH));
+ ublocks=malloc(sizeof(u_int32_t)*(pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH)*
+ (pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH));
+ vblocks=malloc(sizeof(u_int32_t)*(pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH)*
+ (pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH));
+
+ pdata->frametime=(1000000)/pdata->args.fps;
+ return 0;
}
void rmdSetupDefaultArgs(ProgArgs *args) {
-
- args->delay = 0;
- args->windowid = 0;
- args->x = 0;
- args->y = 0;
- args->width = 0;
- args->height = 0;
- args->rescue_path = NULL;
- args->nosound = 0;
- args->full_shots = 0;
- args->follow_mouse = 0;
- args->encOnTheFly = 0;
- args->nowmcheck = 0;
- args->overwrite = 0;
- args->use_jack = 0;
- args->noshared = 0;
- args->no_encode = 0;
- args->noframe = 0;
- args->jack_nports = 0;
- args->jack_ringbuffer_secs = 3.0;
- args->zerocompression = 1;
- args->no_quick_subsample = 1;
- args->cursor_color = 1;
- args->have_dummy_cursor = 0;
- args->xfixes_cursor = 1;
- args->fps = 15;
- args->channels = 1;
- args->frequency = 22050;
- args->buffsize = 4096;
- args->v_bitrate = 0;
- args->v_quality = 63;
- args->s_quality = 10;
-
- if (getenv("DISPLAY") != NULL) {
- args->display = (char *) malloc(strlen(getenv("DISPLAY")) + 1);
- strcpy(args->display, getenv("DISPLAY"));
- }
- else {
- args->display = NULL;
- }
-
- memset(args->jack_port_names, 0, sizeof(args->jack_port_names));
-
- args->device = (char *) malloc(strlen(DEFAULT_AUDIO_DEVICE) + 1);
- strcpy(args->device, DEFAULT_AUDIO_DEVICE);
-
- args->workdir = (char *) malloc(5);
- strcpy(args->workdir, "/tmp");
-
- args->pause_shortcut = (char *) malloc(15);
- strcpy(args->pause_shortcut, "Control+Mod1+p");
-
- args->stop_shortcut = (char *) malloc(15);
- strcpy(args->stop_shortcut, "Control+Mod1+s");
-
- args->filename = (char *) malloc(8);
- strcpy(args->filename, "out.ogv");
+ args->delay = 0;
+ args->windowid = 0;
+ args->x = 0;
+ args->y = 0;
+ args->width = 0;
+ args->height = 0;
+ args->rescue_path = NULL;
+ args->nosound = 0;
+ args->full_shots = 0;
+ args->follow_mouse = 0;
+ args->encOnTheFly = 0;
+ args->nowmcheck = 0;
+ args->overwrite = 0;
+ args->use_jack = 0;
+ args->noshared = 0;
+ args->no_encode = 0;
+ args->noframe = 0;
+ args->jack_nports = 0;
+ args->jack_ringbuffer_secs = 3.0;
+ args->zerocompression = 1;
+ args->no_quick_subsample = 1;
+ args->cursor_color = 1;
+ args->have_dummy_cursor = 0;
+ args->xfixes_cursor = 1;
+ args->fps = 15;
+ args->channels = 1;
+ args->frequency = 22050;
+ args->buffsize = 4096;
+ args->v_bitrate = 0;
+ args->v_quality = 63;
+ args->s_quality = 10;
+
+ if (getenv("DISPLAY") != NULL) {
+ args->display = (char *) malloc(strlen(getenv("DISPLAY")) + 1);
+ strcpy(args->display, getenv("DISPLAY"));
+ } else {
+ args->display = NULL;
+ }
+
+ memset(args->jack_port_names, 0, sizeof(args->jack_port_names));
+
+ args->device = (char *) malloc(strlen(DEFAULT_AUDIO_DEVICE) + 1);
+ strcpy(args->device, DEFAULT_AUDIO_DEVICE);
+
+ args->workdir = (char *) malloc(5);
+ strcpy(args->workdir, "/tmp");
+
+ args->pause_shortcut = (char *) malloc(15);
+ strcpy(args->pause_shortcut, "Control+Mod1+p");
+
+ args->stop_shortcut = (char *) malloc(15);
+ strcpy(args->stop_shortcut, "Control+Mod1+s");
+
+ args->filename = (char *) malloc(8);
+ strcpy(args->filename, "out.ogv");
}
-void rmdCleanUp(void){
-
- free(yblocks);
- free(ublocks);
- free(vblocks);
-
+void rmdCleanUp(void) {
+ free(yblocks);
+ free(ublocks);
+ free(vblocks);
}
diff --git a/recordmydesktop/src/rmd_jack.c b/recordmydesktop/src/rmd_jack.c
index fb7a55e..ada967e 100644
--- a/recordmydesktop/src/rmd_jack.c
+++ b/recordmydesktop/src/rmd_jack.c
@@ -42,28 +42,28 @@
* \param nframes Number of frames captured
*
* \param jdata_t Pointer to JackData struct containing port
-* and client information
+* and client information
*
* \returns Zero always
*/
static int rmdJackCapture(jack_nframes_t nframes,void *jdata_t) {
- int i=0;
- JackData *jdata=(JackData *)jdata_t;
+ int i=0;
+ JackData *jdata=(JackData *)jdata_t;
- if (!jdata->pdata->running || jdata->pdata->paused || !jdata->capture_started) {
- return 0;
- }
+ if (!jdata->pdata->running || jdata->pdata->paused || !jdata->capture_started)
+ return 0;
+
+ for(i= 0;i<jdata->nports;i++)
+ jdata->portbuf[i]=jack_port_get_buffer(jdata->ports[i],nframes);
- for(i= 0;i<jdata->nports;i++)
- jdata->portbuf[i]=jack_port_get_buffer(jdata->ports[i],nframes);
//vorbis analysis buffer wants uninterleaved data
//so we are simply placing the buffers for every channel
//sequentially on the ringbuffer
- for(i=0;i<jdata->nports;i++)
- (*jack_ringbuffer_write)(jdata->sound_buffer,
- (void *)(jdata->portbuf[i]),
- nframes*
- sizeof(jack_default_audio_sample_t));
+ for(i=0;i<jdata->nports;i++)
+ (*jack_ringbuffer_write)( jdata->sound_buffer,
+ (void *)(jdata->portbuf[i]),
+ nframes*
+ sizeof(jack_default_audio_sample_t));
/*FIXME */
//This is not safe.
//cond_var signaling must move away from signal handlers
@@ -72,54 +72,55 @@ static int rmdJackCapture(jack_nframes_t nframes,void *jdata_t) {
//The callback should write on the pipe and the main thread
//should perform a select over the fd's, signaling afterwards the
//appropriate cond_var.
- pthread_mutex_lock(jdata->snd_buff_ready_mutex);
- pthread_cond_signal(jdata->sound_data_read);
- pthread_mutex_unlock(jdata->snd_buff_ready_mutex);
+ pthread_mutex_lock(jdata->snd_buff_ready_mutex);
+ pthread_cond_signal(jdata->sound_data_read);
+ pthread_mutex_unlock(jdata->snd_buff_ready_mutex);
- return 0;
+ return 0;
}
/**
* Register and Activate specified ports
*
* \param jdata_t Pointer to JackData struct containing port
-* and client information
+* and client information
*
* \returns 0 on Success, 1 on failure
*/
static int rmdSetupPorts(JackData *jdata) {
- int i=0;
- jdata->ports=malloc(sizeof(jack_port_t *)*
- jdata->nports);
- jdata->portbuf=malloc(sizeof(jack_default_audio_sample_t*)*
- jdata->nports);
- memset(jdata->portbuf,0,sizeof(jack_default_audio_sample_t*)*
- jdata->nports);
-
- for(i=0;i<jdata->nports;i++){
- char name[64];//recordMyDesktop:input_n<64 is enough for full name
- char num[8];
- strcpy(name,"input_");
- snprintf( num, 8, "%d", i+1 );
- strcat(name,num);
- if((jdata->ports[i]=jack_port_register(jdata->client,
- name,
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsInput,
- 0))==0){
- fprintf(stderr,"Cannot register input port \"%s\"!\n",name);
- return 1;
- }
- if(jack_connect(jdata->client,
- jdata->port_names[i],
- jack_port_name(jdata->ports[i]))){
- fprintf(stderr,"Cannot connect input port %s to %s\n",
- jack_port_name(jdata->ports[i]),
- jdata->port_names[i]);
- return 1;
- }
- }
- return 0;
+ int i=0;
+
+ jdata->ports=malloc(sizeof(jack_port_t *)* jdata->nports);
+ jdata->portbuf=malloc(sizeof(jack_default_audio_sample_t*)* jdata->nports);
+ memset(jdata->portbuf,0,sizeof(jack_default_audio_sample_t*)* jdata->nports);
+
+ for(i=0;i<jdata->nports;i++) {
+ char name[64];//recordMyDesktop:input_n<64 is enough for full name
+ char num[8];
+ strcpy(name,"input_");
+ snprintf( num, 8, "%d", i+1 );
+ strcat(name,num);
+
+ jdata->ports[i] = jack_port_register( jdata->client,
+ name,
+ JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsInput,
+ 0);
+
+ if (!jdata->ports[i]) {
+ fprintf(stderr,"Cannot register input port \"%s\"!\n",name);
+ return 1;
+ }
+
+ if (jack_connect(jdata->client, jdata->port_names[i], jack_port_name(jdata->ports[i]))) {
+
+ fprintf(stderr,"Cannot connect input port %s to %s\n",
+ jack_port_name(jdata->ports[i]),
+ jdata->port_names[i]);
+ return 1;
+ }
+ }
+ return 0;
}
//in case the jack server shuts down
@@ -127,34 +128,34 @@ static int rmdSetupPorts(JackData *jdata) {
//encode the result(if not on the fly)
//an exit cleanly.
static void rmdJackShutdown(void *jdata_t) {
- JackData *jdata = (JackData *)jdata_t;
+ JackData *jdata = (JackData *)jdata_t;
- jdata->pdata->running = FALSE;
+ jdata->pdata->running = FALSE;
- fprintf (stderr, "JACK shutdown\n");
+ fprintf (stderr, "JACK shutdown\n");
}
-int rmdStartJackClient(JackData *jdata){
- float ring_buffer_size=0.0;
- int pid;
- char pidbuf[8];
- char rmd_client_name[32];
-
- //construct the jack client name
- //which is recordMyDesktop-pid
- //in order to allow multiple
- //instances of recordMyDesktop
- //to connetc to a Jack Server
- strcpy(rmd_client_name,"recordMyDesktop-");
- pid=getpid();
- snprintf( pidbuf, 8, "%d", pid );
- strcat(rmd_client_name,pidbuf);
-
- if ((jdata->client=(*jack_client_new)(rmd_client_name))==0){
- fprintf(stderr,"Could not create new client!\n"
- "Make sure that Jack server is running!\n");
- return 15;
- }
+int rmdStartJackClient(JackData *jdata) {
+ float ring_buffer_size=0.0;
+ int pid;
+ char pidbuf[8];
+ char rmd_client_name[32];
+
+ //construct the jack client name
+ //which is recordMyDesktop-pid
+ //in order to allow multiple
+ //instances of recordMyDesktop
+ //to connetc to a Jack Server
+ strcpy(rmd_client_name,"recordMyDesktop-");
+ pid=getpid();
+ snprintf( pidbuf, 8, "%d", pid );
+ strcat(rmd_client_name,pidbuf);
+
+ if ((jdata->client=(*jack_client_new)(rmd_client_name))==0) {
+ fprintf(stderr, "Could not create new client!\n"
+ "Make sure that Jack server is running!\n");
+ return 15;
+ }
//in contrast to ALSA and OSS, Jack dictates frequency
//and buffersize to the values it was launched with.
//Supposedly jack_set_buffer_size can set the buffersize
@@ -168,51 +169,50 @@ int rmdStartJackClient(JackData *jdata){
//(it might be in some cases, but it will certainly be the cause
//of unpredicted problems). A clean exit is preferable
//and any recording up to that point will be encoded and saved.
- jdata->frequency=jack_get_sample_rate(jdata->client);
- jdata->buffersize=jack_get_buffer_size(jdata->client);
- ring_buffer_size=(jdata->ringbuffer_secs*
- jdata->frequency*
- sizeof(jack_default_audio_sample_t)*
- jdata->nports);
- jdata->sound_buffer=
- (*jack_ringbuffer_create)((int)(ring_buffer_size+0.5));//round up
- jack_set_process_callback(jdata->client,rmdJackCapture,jdata);
- jack_on_shutdown(jdata->client,rmdJackShutdown,jdata);
-
- if (jack_activate(jdata->client)) {
- fprintf(stderr,"cannot activate client!\n");
- return 16;
- }
- if(rmdSetupPorts(jdata)){
- jack_client_close(jdata->client);
- return 17;
- }
-
- return 0;
+ jdata->frequency=jack_get_sample_rate(jdata->client);
+ jdata->buffersize=jack_get_buffer_size(jdata->client);
+ ring_buffer_size=( jdata->ringbuffer_secs*
+ jdata->frequency*
+ sizeof(jack_default_audio_sample_t)*
+ jdata->nports);
+ jdata->sound_buffer= (*jack_ringbuffer_create)((int)(ring_buffer_size+0.5));//round up
+ jack_set_process_callback(jdata->client,rmdJackCapture,jdata);
+ jack_on_shutdown(jdata->client,rmdJackShutdown,jdata);
+
+ if (jack_activate(jdata->client)) {
+ fprintf(stderr,"cannot activate client!\n");
+ return 16;
+ }
+
+ if (rmdSetupPorts(jdata)) {
+ jack_client_close(jdata->client);
+ return 17;
+ }
+
+ return 0;
}
-int rmdStopJackClient(JackData *jdata){
- int ret=0;
+int rmdStopJackClient(JackData *jdata) {
+ int ret=0;
- (*jack_ringbuffer_free)(jdata->sound_buffer);
- if(jack_client_close(jdata->client)){
- fprintf(stderr,"Cannot close Jack client!\n");
- ret=1;
- }
+ (*jack_ringbuffer_free)(jdata->sound_buffer);
+ if (jack_client_close(jdata->client)) {
+ fprintf(stderr,"Cannot close Jack client!\n");
+ ret=1;
+ }
/*TODO*/
//I need to make some kind of program/thread
//flow diagram to see where it's safe to dlclose
//because here it causes a segfault.
-// if(dlclose(jdata->jack_lib_handle)){
-// fprintf(stderr,"Cannot unload Jack library!\n");
-// ret=1;
-// }
-// else fprintf(stderr,"Unloaded Jack library.\n");
+// if (dlclose(jdata->jack_lib_handle)) {
+// fprintf(stderr,"Cannot unload Jack library!\n");
+// ret=1;
+// }
+// else fprintf(stderr,"Unloaded Jack library.\n");
- return ret;
+ return ret;
}
#endif
-
diff --git a/recordmydesktop/src/rmd_load_cache.c b/recordmydesktop/src/rmd_load_cache.c
index e744ce5..089121c 100644
--- a/recordmydesktop/src/rmd_load_cache.c
+++ b/recordmydesktop/src/rmd_load_cache.c
@@ -48,7 +48,7 @@
//of the widths(specified above),
//but the definitions bellow are only
//for convenience anyway.
-#define Y_UNIT_BYTES 0x0100
+#define Y_UNIT_BYTES 0x0100
#define UV_UNIT_BYTES 0x0040
@@ -56,284 +56,279 @@
//Based on the Header information
//we can read the correct amount of bytes.
typedef struct _CachedFrame{
- FrameHeader *header;
- u_int32_t *YBlocks, //identifying number on the grid,
- *UBlocks, //starting at top left
- *VBlocks; // >> >>
- unsigned char *YData, //pointer to data for the blocks that have changed,
- *UData, //which have to be remapped
- *VData; //on the buffer when reading
+ FrameHeader *header;
+ u_int32_t *YBlocks, //identifying number on the grid,
+ *UBlocks, //starting at top left
+ *VBlocks; // >> >>
+ unsigned char *YData, //pointer to data for the blocks that have changed,
+ *UData, //which have to be remapped
+ *VData; //on the buffer when reading
}CachedFrame;
static void rmdLoadBlock(unsigned char *dest,
- unsigned char *source,
- int blockno,
- int width,
- int height,
- int blockwidth) {
- int j,
- block_i=blockno/(width/blockwidth),//place on the grid
- block_k=blockno%(width/blockwidth);
- for(j=0;j<blockwidth;j++)//we copy rows
- memcpy( &dest[(block_i*width+block_k)*blockwidth+j*width],
- &source[j*blockwidth],
- blockwidth);
+ unsigned char *source,
+ int blockno,
+ int width,
+ int height,
+ int blockwidth) {
+ int j,
+ block_i=blockno/(width/blockwidth),//place on the grid
+ block_k=blockno%(width/blockwidth);
+
+ for (j=0;j<blockwidth;j++)//we copy rows
+ memcpy( &dest[(block_i*width+block_k)*blockwidth+j*width],
+ &source[j*blockwidth],
+ blockwidth);
}
//returns number of bytes
static int rmdReadZF(void * buffer, size_t size, size_t nmemb, FILE *ucfp, gzFile *ifp) {
- if((ifp!=NULL && ucfp!=NULL)||
- (ifp==NULL && ucfp==NULL))
- return -1;
- else if(ucfp!=NULL){
- return (size*fread(buffer,size,nmemb,ucfp));
- }
- else
- return gzread(ifp,buffer,size*nmemb);
+ if ((ifp!=NULL && ucfp!=NULL)||
+ (ifp==NULL && ucfp==NULL))
+ return -1;
+ else if (ucfp!=NULL) {
+ return (size*fread(buffer,size,nmemb,ucfp));
+ } else
+ return gzread(ifp,buffer,size*nmemb);
}
static int rmdReadFrame(CachedFrame *frame, FILE *ucfp, gzFile *ifp) {
- int index_entry_size=sizeof(u_int32_t);
- if(frame->header->Ynum>0){
- if(rmdReadZF(frame->YBlocks,
- index_entry_size,
- frame->header->Ynum,
- ucfp,
- ifp)!=index_entry_size*frame->header->Ynum){
- return -1;
- }
- }
- if(frame->header->Unum>0){
- if(rmdReadZF(frame->UBlocks,
- index_entry_size,
- frame->header->Unum,
- ucfp,
- ifp)!=index_entry_size*frame->header->Unum){
- return -1;
- }
- }
- if(frame->header->Vnum>0){
- if(rmdReadZF(frame->VBlocks,
- index_entry_size,
- frame->header->Vnum,
- ucfp,
- ifp)!=index_entry_size*frame->header->Vnum){
- return -1;
- }
- }
- if(frame->header->Ynum>0){
- if(rmdReadZF(frame->YData,
- Y_UNIT_BYTES,
- frame->header->Ynum,
- ucfp,
- ifp)!=Y_UNIT_BYTES*frame->header->Ynum){
- return -2;
- }
- }
- if(frame->header->Unum>0){
- if(rmdReadZF(frame->UData,
- UV_UNIT_BYTES,
- frame->header->Unum,
- ucfp,
- ifp)!=UV_UNIT_BYTES*frame->header->Unum){
- return -2;
- }
- }
- if(frame->header->Vnum>0){
- if(rmdReadZF(frame->VData,
- UV_UNIT_BYTES,
- frame->header->Vnum,
- ucfp,
- ifp)!=UV_UNIT_BYTES*frame->header->Vnum){
- return -2;
- }
- }
- return 0;
-}
+ int index_entry_size=sizeof(u_int32_t);
+
+ if (frame->header->Ynum>0) {
+ if (rmdReadZF( frame->YBlocks,
+ index_entry_size,
+ frame->header->Ynum,
+ ucfp,
+ ifp)!=index_entry_size*frame->header->Ynum) {
+ return -1;
+ }
+ }
+
+ if (frame->header->Unum>0) {
+ if (rmdReadZF( frame->UBlocks,
+ index_entry_size,
+ frame->header->Unum,
+ ucfp,
+ ifp)!=index_entry_size*frame->header->Unum) {
+ return -1;
+ }
+ }
+
+ if (frame->header->Vnum>0) {
+ if (rmdReadZF( frame->VBlocks,
+ index_entry_size,
+ frame->header->Vnum,
+ ucfp,
+ ifp)!=index_entry_size*frame->header->Vnum) {
+ return -1;
+ }
+ }
-void *rmdLoadCache(ProgData *pdata){
-
- yuv_buffer *yuv=&pdata->enc_data->yuv;
- gzFile *ifp=NULL;
- FILE *ucfp=NULL;
- FILE *afp=pdata->cache_data->afp;
- FrameHeader fheader;
- CachedFrame frame;
- int j=0,
- nth_cache=1,
- audio_end=0,
- extra_frames=0,//total number of duplicated frames
- missing_frames=0,//if this is found >0 current run will not load
- //a frame but it will proccess the previous
- thread_exit=0,//0 success, -1 couldn't find files,1 couldn't remove
- blocknum_x=pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
- blocknum_y=pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH,
- blockszy=Y_UNIT_BYTES,//size of y plane block in bytes
- blockszuv=UV_UNIT_BYTES;//size of u,v plane blocks in bytes
- signed char *sound_data=(signed char *)malloc(pdata->periodsize*
- pdata->sound_framesize);
-
- u_int32_t YBlocks[(yuv->y_width*yuv->y_height)/Y_UNIT_BYTES],
- UBlocks[(yuv->uv_width*yuv->uv_height)/UV_UNIT_BYTES],
- VBlocks[(yuv->uv_width*yuv->uv_height)/UV_UNIT_BYTES];
-
- // We allocate the frame that we will use
- frame.header = &fheader;
- frame.YBlocks = YBlocks;
- frame.UBlocks = UBlocks;
- frame.VBlocks = VBlocks;
- frame.YData = malloc(yuv->y_width * yuv->y_height);
- frame.UData = malloc(yuv->uv_width * yuv->uv_height);
- frame.VData = malloc(yuv->uv_width * yuv->uv_height);
-
- //and the we open our files
- if(!pdata->args.zerocompression){
- ifp=gzopen(pdata->cache_data->imgdata,"rb");
- if(ifp==NULL){
- thread_exit=-1;
- pthread_exit(&thread_exit);
- }
- }
- else{
- ucfp=fopen(pdata->cache_data->imgdata,"rb");
- if(ucfp==NULL){
- thread_exit=-1;
- pthread_exit(&thread_exit);
- }
- }
-
-
- if(!pdata->args.nosound){
- afp=fopen(pdata->cache_data->audiodata,"rb");
- if(afp==NULL){
- thread_exit=-1;
- pthread_exit(&thread_exit);
- }
- }
-
- //this will be used now to define if we proccess audio or video
- //on any given loop.
- 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(pdata->running){
- //video load and encoding
- if(pdata->avd<=0 || pdata->args.nosound || audio_end){
- if(missing_frames>0){
- extra_frames++;
- missing_frames--;
- rmdSyncEncodeImageBuffer(pdata);
- }
- else if(((!pdata->args.zerocompression)&&
- (gzread(ifp,frame.header,sizeof(FrameHeader))==
- sizeof(FrameHeader) ))||
- ((pdata->args.zerocompression)&&
- (fread(frame.header,sizeof(FrameHeader),1,ucfp)==1))){
- //sync
- missing_frames+=frame.header->current_total-
- (extra_frames+frame.header->frameno);
- if (pdata->frames_total) {
- fprintf(stdout,
- "\r[%d%%] ",
- ((frame.header->frameno + extra_frames) * 100) / pdata->frames_total);
- }
- else
- fprintf(stdout,"\r[%d frames rendered] ",
- (frame.header->frameno+extra_frames));
- fflush(stdout);
- if( (frame.header->Ynum<=blocknum_x*blocknum_y) &&
- (frame.header->Unum<=blocknum_x*blocknum_y) &&
- (frame.header->Vnum<=blocknum_x*blocknum_y) &&
- (!rmdReadFrame(&frame,
- ((pdata->args.zerocompression)?ucfp:NULL),
- ((pdata->args.zerocompression)?NULL:ifp)))
- ){
- //load the blocks for each buffer
- if(frame.header->Ynum)
- for(j=0;j<frame.header->Ynum;j++)
- rmdLoadBlock(yuv->y,
- &frame.YData[j*blockszy],
- frame.YBlocks[j],
- yuv->y_width,
- yuv->y_height,
- Y_UNIT_WIDTH);
- if(frame.header->Unum)
- for(j=0;j<frame.header->Unum;j++)
- rmdLoadBlock(yuv->u,
- &frame.UData[j*blockszuv],
- frame.UBlocks[j],
- yuv->uv_width,
- yuv->uv_height,
- UV_UNIT_WIDTH);
- if(frame.header->Vnum)
- for(j=0;j<frame.header->Vnum;j++)
- rmdLoadBlock(yuv->v,
- &frame.VData[j*blockszuv],
- frame.VBlocks[j],
- yuv->uv_width,
- yuv->uv_height,
- UV_UNIT_WIDTH);
- //encode. This is not made in a thread since
- //now blocking is not a problem
- //and this way sync problems
- //can be avoided more easily.
- rmdSyncEncodeImageBuffer(pdata);
- }
- else{
- raise(SIGINT);
- continue;
- }
- }
- else{
- if(rmdSwapCacheFilesRead(pdata->cache_data->imgdata,
- nth_cache,
- &ifp,
- &ucfp)){
- raise(SIGINT);
- }
- else{
- fprintf(stderr,"\t[Cache File %d]",nth_cache);
- nth_cache++;
- }
- continue;
- }
- }
- //audio load and encoding
- else{
- if(!audio_end){
- int nbytes=fread(sound_data,1,pdata->periodsize*
- pdata->sound_framesize,afp);
- if(nbytes<=0)
- audio_end=1;
- else
- rmdSyncEncodeSoundBuffer(pdata,sound_data);
- }
- }
- }
-
- pdata->v_encoding_clean=pdata->th_encoding_clean=1;
- pthread_mutex_lock(&pdata->theora_lib_mutex);
- pthread_cond_signal(&pdata->theora_lib_clean);
- pthread_mutex_unlock(&pdata->theora_lib_mutex);
- pthread_mutex_lock(&pdata->vorbis_lib_mutex);
- pthread_cond_signal(&pdata->vorbis_lib_clean);
- pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
- fprintf(stdout,"\n");
-
- // Clear frame
- free(frame.YData);
- free(frame.UData);
- free(frame.VData);
-
- free(sound_data);
-
- if(!pdata->args.nosound){
- fclose(afp);
- }
-
- pthread_exit(&thread_exit);
+ if (frame->header->Ynum>0) {
+ if (rmdReadZF( frame->YData,
+ Y_UNIT_BYTES,
+ frame->header->Ynum,
+ ucfp,
+ ifp)!=Y_UNIT_BYTES*frame->header->Ynum) {
+ return -2;
+ }
+ }
+ if (frame->header->Unum>0) {
+ if (rmdReadZF( frame->UData,
+ UV_UNIT_BYTES,
+ frame->header->Unum,
+ ucfp,
+ ifp)!=UV_UNIT_BYTES*frame->header->Unum) {
+ return -2;
+ }
+ }
+ if (frame->header->Vnum>0) {
+ if (rmdReadZF( frame->VData,
+ UV_UNIT_BYTES,
+ frame->header->Vnum,
+ ucfp,
+ ifp)!=UV_UNIT_BYTES*frame->header->Vnum) {
+ return -2;
+ }
+ }
+
+ return 0;
}
+void *rmdLoadCache(ProgData *pdata) {
+
+ yuv_buffer *yuv=&pdata->enc_data->yuv;
+ gzFile *ifp=NULL;
+ FILE *ucfp=NULL;
+ FILE *afp=pdata->cache_data->afp;
+ FrameHeader fheader;
+ CachedFrame frame;
+ int j=0, nth_cache=1,
+ audio_end=0,
+ extra_frames=0,//total number of duplicated frames
+ missing_frames=0,//if this is found >0 current run will not load
+ //a frame but it will proccess the previous
+ thread_exit=0,//0 success, -1 couldn't find files,1 couldn't remove
+ blocknum_x=pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
+ blocknum_y=pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH,
+ blockszy=Y_UNIT_BYTES,//size of y plane block in bytes
+ blockszuv=UV_UNIT_BYTES;//size of u,v plane blocks in bytes
+ signed char *sound_data=(signed char *)malloc(pdata->periodsize* pdata->sound_framesize);
+
+ u_int32_t YBlocks[(yuv->y_width*yuv->y_height)/Y_UNIT_BYTES],
+ UBlocks[(yuv->uv_width*yuv->uv_height)/UV_UNIT_BYTES],
+ VBlocks[(yuv->uv_width*yuv->uv_height)/UV_UNIT_BYTES];
+
+ // We allocate the frame that we will use
+ frame.header = &fheader;
+ frame.YBlocks = YBlocks;
+ frame.UBlocks = UBlocks;
+ frame.VBlocks = VBlocks;
+ frame.YData = malloc(yuv->y_width * yuv->y_height);
+ frame.UData = malloc(yuv->uv_width * yuv->uv_height);
+ frame.VData = malloc(yuv->uv_width * yuv->uv_height);
+
+ //and the we open our files
+ if (!pdata->args.zerocompression) {
+ ifp=gzopen(pdata->cache_data->imgdata,"rb");
+ if (ifp==NULL) {
+ thread_exit=-1;
+ pthread_exit(&thread_exit);
+ }
+ } else {
+ ucfp=fopen(pdata->cache_data->imgdata,"rb");
+ if (ucfp==NULL) {
+ thread_exit=-1;
+ pthread_exit(&thread_exit);
+ }
+ }
+
+ if (!pdata->args.nosound) {
+ afp=fopen(pdata->cache_data->audiodata,"rb");
+ if (afp==NULL) {
+ thread_exit=-1;
+ pthread_exit(&thread_exit);
+ }
+ }
+
+ //this will be used now to define if we proccess audio or video
+ //on any given loop.
+ 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 (pdata->running) {
+ //video load and encoding
+ if (pdata->avd<=0 || pdata->args.nosound || audio_end) {
+ if (missing_frames>0) {
+ extra_frames++;
+ missing_frames--;
+ rmdSyncEncodeImageBuffer(pdata);
+ } else if (((!pdata->args.zerocompression)&&
+ (gzread(ifp,frame.header,sizeof(FrameHeader))==
+ sizeof(FrameHeader) ))||
+ ((pdata->args.zerocompression)&&
+ (fread(frame.header,sizeof(FrameHeader),1,ucfp)==1))) {
+ //sync
+ missing_frames+=frame.header->current_total-
+ (extra_frames+frame.header->frameno);
+ if (pdata->frames_total) {
+ fprintf(stdout,
+ "\r[%d%%] ",
+ ((frame.header->frameno + extra_frames) * 100) / pdata->frames_total);
+ } else
+ fprintf(stdout,"\r[%d frames rendered] ",
+ (frame.header->frameno+extra_frames));
+ fflush(stdout);
+ if ( (frame.header->Ynum<=blocknum_x*blocknum_y) &&
+ (frame.header->Unum<=blocknum_x*blocknum_y) &&
+ (frame.header->Vnum<=blocknum_x*blocknum_y) &&
+ (!rmdReadFrame( &frame,
+ ((pdata->args.zerocompression)?ucfp:NULL),
+ ((pdata->args.zerocompression)?NULL:ifp)))
+ ) {
+
+ //load the blocks for each buffer
+ if (frame.header->Ynum)
+ for (j=0;j<frame.header->Ynum;j++)
+ rmdLoadBlock( yuv->y,
+ &frame.YData[j*blockszy],
+ frame.YBlocks[j],
+ yuv->y_width,
+ yuv->y_height,
+ Y_UNIT_WIDTH);
+ if (frame.header->Unum)
+ for (j=0;j<frame.header->Unum;j++)
+ rmdLoadBlock( yuv->u,
+ &frame.UData[j*blockszuv],
+ frame.UBlocks[j],
+ yuv->uv_width,
+ yuv->uv_height,
+ UV_UNIT_WIDTH);
+ if (frame.header->Vnum)
+ for (j=0;j<frame.header->Vnum;j++)
+ rmdLoadBlock( yuv->v,
+ &frame.VData[j*blockszuv],
+ frame.VBlocks[j],
+ yuv->uv_width,
+ yuv->uv_height,
+ UV_UNIT_WIDTH);
+
+ //encode. This is not made in a thread since
+ //now blocking is not a problem
+ //and this way sync problems
+ //can be avoided more easily.
+ rmdSyncEncodeImageBuffer(pdata);
+ } else {
+ raise(SIGINT);
+ continue;
+ }
+ } else {
+ if (rmdSwapCacheFilesRead( pdata->cache_data->imgdata,
+ nth_cache,
+ &ifp,
+ &ucfp)) {
+ raise(SIGINT);
+ } else {
+ fprintf(stderr,"\t[Cache File %d]",nth_cache);
+ nth_cache++;
+ }
+ continue;
+ }
+ //audio load and encoding
+ } else {
+ if (!audio_end) {
+ int nbytes=fread(sound_data,1,pdata->periodsize*
+ pdata->sound_framesize,afp);
+ if (nbytes<=0)
+ audio_end=1;
+ else
+ rmdSyncEncodeSoundBuffer(pdata,sound_data);
+ }
+ }
+ }
+
+ pdata->v_encoding_clean=pdata->th_encoding_clean=1;
+ pthread_mutex_lock(&pdata->theora_lib_mutex);
+ pthread_cond_signal(&pdata->theora_lib_clean);
+ pthread_mutex_unlock(&pdata->theora_lib_mutex);
+ pthread_mutex_lock(&pdata->vorbis_lib_mutex);
+ pthread_cond_signal(&pdata->vorbis_lib_clean);
+ pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
+ fprintf(stdout,"\n");
+
+ // Clear frame
+ free(frame.YData);
+ free(frame.UData);
+ free(frame.VData);
+
+ free(sound_data);
+
+ if (!pdata->args.nosound)
+ fclose(afp);
+
+ pthread_exit(&thread_exit);
+}
diff --git a/recordmydesktop/src/rmd_make_dummy_pointer.c b/recordmydesktop/src/rmd_make_dummy_pointer.c
index ef8d164..ba7fb0f 100644
--- a/recordmydesktop/src/rmd_make_dummy_pointer.c
+++ b/recordmydesktop/src/rmd_make_dummy_pointer.c
@@ -33,62 +33,63 @@
#include <X11/Xlib.h>
#include <stdlib.h>
-unsigned char *rmdMakeDummyPointer(Display *display,
- DisplaySpecs *specs,
- int size,
- int color,
- int type,
- unsigned char *npxl){
- unsigned long bpixel = XBlackPixel(display, specs->screen);
- unsigned long wpixel = XWhitePixel(display, specs->screen);
- int i,k,o='.';
- unsigned long b=(color)?'w':'b',
- w=(color)?'b':'w';
- char pmask[1][16][16]={{
- {w,w,o,o,o,o,o,o,o,o,o,o,o,o,o,o},
- {w,b,w,o,o,o,o,o,o,o,o,o,o,o,o,o},
- {w,b,b,w,o,o,o,o,o,o,o,o,o,o,o,o},
- {w,b,b,b,w,o,o,o,o,o,o,o,o,o,o,o},
- {w,b,b,b,b,w,o,o,o,o,o,o,o,o,o,o},
- {w,b,b,b,b,b,w,o,o,o,o,o,o,o,o,o},
- {w,b,b,b,b,b,b,w,o,o,o,o,o,o,o,o},
- {w,b,b,b,b,b,b,b,w,o,o,o,o,o,o,o},
- {w,b,b,b,b,b,b,b,b,w,o,o,o,o,o,o},
- {w,b,b,b,b,b,w,w,w,w,o,o,o,o,o,o},
- {w,b,b,b,b,b,w,o,o,o,o,o,o,o,o,o},
- {w,b,b,w,w,b,b,w,o,o,o,o,o,o,o,o},
- {w,b,w,o,w,b,b,w,o,o,o,o,o,o,o,o},
- {w,w,o,o,o,w,b,b,w,o,o,o,o,o,o,o},
- {o,o,o,o,o,w,b,b,w,o,o,o,o,o,o,o},
- {o,o,o,o,o,o,w,w,o,o,o,o,o,o,o,o}}
- };
- unsigned char *ret=malloc(size*sizeof(char[size*4]));
- unsigned char wp[4]={ (wpixel ^ 0xff000000) >> 24,
- (wpixel ^ 0x00ff0000) >> 16,
- (wpixel ^ 0x0000ff00) >> 8,
- (wpixel ^ 0x000000ff) };
- unsigned char bp[4]={ (bpixel ^ 0xff000000) >> 24,
- (bpixel ^ 0x00ff0000) >> 16,
- (bpixel ^ 0x0000ff00) >> 8,
- (bpixel ^ 0x000000ff) };
+unsigned char *rmdMakeDummyPointer( Display *display,
+ DisplaySpecs *specs,
+ int size,
+ int color,
+ int type,
+ unsigned char *npxl) {
- *npxl=((wp[0]-1)!=bp[0])?wp[0]-100:wp[0]-102;
- for(i=0;i<size;i++){
- for(k=0;k<size;k++){
- ret[(i*size+k)*4+__ABYTE]=(pmask[type][i][k]=='w')?
- wp[0]:(pmask[type][i][k]=='b')?
- bp[0]:*npxl;
- ret[(i*size+k)*4+__RBYTE]=(pmask[type][i][k]=='w')?
- wp[1]:(pmask[type][i][k]=='b')?
- bp[1]:*npxl;
- ret[(i*size+k)*4+__GBYTE]=(pmask[type][i][k]=='w')?
- wp[2]:(pmask[type][i][k]=='b')?
- bp[2]:*npxl;
- ret[(i*size+k)*4+__BBYTE]=(pmask[type][i][k]=='w')?
- wp[3]:(pmask[type][i][k]=='b')?
- bp[3]:*npxl;
- }
- }
+ unsigned long bpixel = XBlackPixel(display, specs->screen);
+ unsigned long wpixel = XWhitePixel(display, specs->screen);
+ int i,k,o='.';
+ unsigned long b=(color)?'w':'b',
+ w=(color)?'b':'w';
+ char pmask[1][16][16]={{
+ {w,w,o,o,o,o,o,o,o,o,o,o,o,o,o,o},
+ {w,b,w,o,o,o,o,o,o,o,o,o,o,o,o,o},
+ {w,b,b,w,o,o,o,o,o,o,o,o,o,o,o,o},
+ {w,b,b,b,w,o,o,o,o,o,o,o,o,o,o,o},
+ {w,b,b,b,b,w,o,o,o,o,o,o,o,o,o,o},
+ {w,b,b,b,b,b,w,o,o,o,o,o,o,o,o,o},
+ {w,b,b,b,b,b,b,w,o,o,o,o,o,o,o,o},
+ {w,b,b,b,b,b,b,b,w,o,o,o,o,o,o,o},
+ {w,b,b,b,b,b,b,b,b,w,o,o,o,o,o,o},
+ {w,b,b,b,b,b,w,w,w,w,o,o,o,o,o,o},
+ {w,b,b,b,b,b,w,o,o,o,o,o,o,o,o,o},
+ {w,b,b,w,w,b,b,w,o,o,o,o,o,o,o,o},
+ {w,b,w,o,w,b,b,w,o,o,o,o,o,o,o,o},
+ {w,w,o,o,o,w,b,b,w,o,o,o,o,o,o,o},
+ {o,o,o,o,o,w,b,b,w,o,o,o,o,o,o,o},
+ {o,o,o,o,o,o,w,w,o,o,o,o,o,o,o,o}}
+ };
+ unsigned char *ret=malloc(size*sizeof(char[size*4]));
+ unsigned char wp[4]={ (wpixel ^ 0xff000000) >> 24,
+ (wpixel ^ 0x00ff0000) >> 16,
+ (wpixel ^ 0x0000ff00) >> 8,
+ (wpixel ^ 0x000000ff) };
+ unsigned char bp[4]={ (bpixel ^ 0xff000000) >> 24,
+ (bpixel ^ 0x00ff0000) >> 16,
+ (bpixel ^ 0x0000ff00) >> 8,
+ (bpixel ^ 0x000000ff) };
- return ret;
+ *npxl=((wp[0]-1)!=bp[0])?wp[0]-100:wp[0]-102;
+ for (i=0;i<size;i++) {
+ for (k=0;k<size;k++) {
+ ret[(i*size+k)*4+__ABYTE]=(pmask[type][i][k]=='w')?
+ wp[0]:(pmask[type][i][k]=='b')?
+ bp[0]:*npxl;
+ ret[(i*size+k)*4+__RBYTE]=(pmask[type][i][k]=='w')?
+ wp[1]:(pmask[type][i][k]=='b')?
+ bp[1]:*npxl;
+ ret[(i*size+k)*4+__GBYTE]=(pmask[type][i][k]=='w')?
+ wp[2]:(pmask[type][i][k]=='b')?
+ bp[2]:*npxl;
+ ret[(i*size+k)*4+__BBYTE]=(pmask[type][i][k]=='w')?
+ wp[3]:(pmask[type][i][k]=='b')?
+ bp[3]:*npxl;
+ }
+ }
+
+ return ret;
}
diff --git a/recordmydesktop/src/rmd_math.c b/recordmydesktop/src/rmd_math.c
index d344c78..5a184e8 100644
--- a/recordmydesktop/src/rmd_math.c
+++ b/recordmydesktop/src/rmd_math.c
@@ -28,9 +28,6 @@
#include <math.h>
-double rmdRoundf(double val){
-
- return val < 0.0 ? ceilf( val - 0.5 ) : floorf( val + 0.5 );
-
+double rmdRoundf(double val) {
+ return val < 0.0 ? ceilf( val - 0.5 ) : floorf( val + 0.5 );
}
-
diff --git a/recordmydesktop/src/rmd_opendev.c b/recordmydesktop/src/rmd_opendev.c
index 51783c7..c196c5a 100644
--- a/recordmydesktop/src/rmd_opendev.c
+++ b/recordmydesktop/src/rmd_opendev.c
@@ -42,135 +42,148 @@
#ifdef HAVE_LIBASOUND
-snd_pcm_t *rmdOpenDev(const char *pcm_dev,
- unsigned int *channels,
- unsigned int *frequency,
- snd_pcm_uframes_t *buffsize,
- snd_pcm_uframes_t *periodsize,
- unsigned int *periodtime,
- int *hard_pause){
-
- snd_pcm_t *mhandle;
- snd_pcm_hw_params_t *hwparams;
- unsigned int periods=2;
- unsigned int exactrate = *frequency;
-
- // The compiler might warn us because the expansion starts with
- // assert(&hwparams)
- snd_pcm_hw_params_alloca(&hwparams);
-
- if (snd_pcm_open(&mhandle,pcm_dev,SND_PCM_STREAM_CAPTURE,SND_PCM_ASYNC)<0){
- fprintf(stderr, "Couldn't open PCM device %s\n", pcm_dev);
- return NULL;
- }
- else
- fprintf(stderr, "Opened PCM device %s\n", pcm_dev);
- if (snd_pcm_hw_params_any(mhandle, hwparams)<0){
- fprintf(stderr, "Couldn't configure PCM device.\n");
- return NULL;
- }
- if (snd_pcm_hw_params_set_access(mhandle,
- hwparams,
- SND_PCM_ACCESS_RW_INTERLEAVED)<0){
- fprintf(stderr, "Couldn't set access.\n");
- return NULL;
- }
- if (snd_pcm_hw_params_set_format(mhandle,
- hwparams,
- SND_PCM_FORMAT_S16_LE)<0){
- fprintf(stderr, "Couldn't set format.\n");
- return NULL;
- }
- if (snd_pcm_hw_params_set_rate_near(mhandle, hwparams, &exactrate, 0)<0){
- fprintf(stderr, "Couldn't set frequency.\n");
- return NULL;
- }
- if (*frequency != exactrate){
- fprintf(stderr, "Playback frequency %dHz is not available...\n"
- "Using %dHz instead.\n",*frequency,exactrate);
- *frequency=exactrate;
- }
- if (snd_pcm_hw_params_set_channels_near(mhandle, hwparams, channels)<0){
- fprintf(stderr, "Couldn't set channels number.\n");
- return NULL;
- }
- if(*channels>2){
- fprintf(stderr,"Channels number should be 1(mono) or 2(stereo).\n");
- return NULL;
- }
- if (snd_pcm_hw_params_set_periods_near(mhandle,hwparams,&periods,0)<0){
- fprintf(stderr, "Couldn't set periods.\n");
- return NULL;
- }
-
- if (snd_pcm_hw_params_set_buffer_size_near(mhandle,hwparams,buffsize)<0){
- fprintf(stderr, "Couldn't set buffer size.\n");
- return NULL;
- }
- if (snd_pcm_hw_params(mhandle,hwparams)<0){
- fprintf(stderr, "Couldn't set hardware parameters.\n");
- return NULL;
- }
- if(hard_pause!=NULL)
- if(!snd_pcm_hw_params_can_pause(hwparams)){
- *hard_pause=1;
- }
- if(periodsize!=NULL)
- snd_pcm_hw_params_get_period_size(hwparams,periodsize,0);
-
- if(periodtime!=NULL)
- snd_pcm_hw_params_get_period_time(hwparams,periodtime,0);
- fprintf(stderr,"Recording on device %s is set to:\n%d channels at %dHz\n",
- pcm_dev,*channels,*frequency);
- snd_pcm_prepare(mhandle);
-
- return mhandle;
+snd_pcm_t *rmdOpenDev( const char *pcm_dev,
+ unsigned int *channels,
+ unsigned int *frequency,
+ snd_pcm_uframes_t *buffsize,
+ snd_pcm_uframes_t *periodsize,
+ unsigned int *periodtime,
+ int *hard_pause) {
+
+ snd_pcm_t *mhandle;
+ snd_pcm_hw_params_t *hwparams;
+ unsigned int periods=2;
+ unsigned int exactrate = *frequency;
+
+ // The compiler might warn us because the expansion starts with
+ // assert(&hwparams)
+ snd_pcm_hw_params_alloca(&hwparams);
+
+ if (snd_pcm_open(&mhandle,pcm_dev,SND_PCM_STREAM_CAPTURE,SND_PCM_ASYNC)<0) {
+ fprintf(stderr, "Couldn't open PCM device %s\n", pcm_dev);
+ return NULL;
+ } else
+ fprintf(stderr, "Opened PCM device %s\n", pcm_dev);
+
+ if (snd_pcm_hw_params_any(mhandle, hwparams)<0) {
+ fprintf(stderr, "Couldn't configure PCM device.\n");
+ return NULL;
+ }
+
+ if (snd_pcm_hw_params_set_access(mhandle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)<0) {
+ fprintf(stderr, "Couldn't set access.\n");
+ return NULL;
+ }
+
+ if (snd_pcm_hw_params_set_format(mhandle, hwparams, SND_PCM_FORMAT_S16_LE)<0) {
+ fprintf(stderr, "Couldn't set format.\n");
+ return NULL;
+ }
+
+ if (snd_pcm_hw_params_set_rate_near(mhandle, hwparams, &exactrate, 0)<0) {
+ fprintf(stderr, "Couldn't set frequency.\n");
+ return NULL;
+ }
+
+ if (*frequency != exactrate) {
+ fprintf(stderr, "Playback frequency %dHz is not available...\n"
+ "Using %dHz instead.\n",
+ *frequency, exactrate);
+
+ *frequency=exactrate;
+ }
+
+ if (snd_pcm_hw_params_set_channels_near(mhandle, hwparams, channels)<0) {
+ fprintf(stderr, "Couldn't set channels number.\n");
+ return NULL;
+ }
+
+ if (*channels>2) {
+ fprintf(stderr,"Channels number should be 1(mono) or 2(stereo).\n");
+ return NULL;
+ }
+
+ if (snd_pcm_hw_params_set_periods_near(mhandle,hwparams,&periods,0)<0) {
+ fprintf(stderr, "Couldn't set periods.\n");
+ return NULL;
+ }
+
+ if (snd_pcm_hw_params_set_buffer_size_near(mhandle,hwparams,buffsize)<0) {
+ fprintf(stderr, "Couldn't set buffer size.\n");
+ return NULL;
+ }
+
+ if (snd_pcm_hw_params(mhandle,hwparams)<0) {
+ fprintf(stderr, "Couldn't set hardware parameters.\n");
+ return NULL;
+ }
+
+ if (hard_pause!=NULL) {
+ if (!snd_pcm_hw_params_can_pause(hwparams))
+ *hard_pause=1;
+ }
+
+ if (periodsize!=NULL)
+ snd_pcm_hw_params_get_period_size(hwparams,periodsize,0);
+
+ if (periodtime!=NULL)
+ snd_pcm_hw_params_get_period_time(hwparams,periodtime,0);
+
+ fprintf(stderr,
+ "Recording on device %s is set to:\n%d channels at %dHz\n",
+ pcm_dev,*channels,*frequency);
+
+ snd_pcm_prepare(mhandle);
+
+ return mhandle;
}
#else
-int rmdOpenDev(const char *pcm_dev,
- unsigned int channels,
- unsigned int frequency){
- int fd ;
- fd=open(pcm_dev,O_RDONLY);
-
- if(fd!=-1){
- unsigned int value;
-
- if(ioctl(fd,SNDCTL_DSP_GETFMTS,&value)<0){
- fprintf(stderr,"Couldn't get audio format list\n");
- return -1;
- }
- if(value & AFMT_S16_LE){
- value=AFMT_S16_LE;
- }
- else if(value & AFMT_S16_BE){
- value=AFMT_S16_BE;
- }
- else{
- fprintf(stderr,"Soundcard doesn't support signed 16-bit-data\n");
- return -1;
- }
- if(ioctl(fd,SNDCTL_DSP_SETFMT,&value)<0){
- fprintf(stderr,"Couldn't set audio format\n" );
- return -1;
- }
- value = channels;
- if(ioctl(fd,SNDCTL_DSP_CHANNELS,&value)<0){
- fprintf(stderr,"Cannot set the number of channels\n" );
- return -1;
- }
- value = frequency;
- if(ioctl(fd,SNDCTL_DSP_SPEED,&value)<0){
- fprintf(stderr,"Couldn't set audio frequency\n" );
- return -1;
- }
- if(fcntl(fd,F_SETFL,fcntl(fd,F_GETFL) & ~O_NONBLOCK)<0){
- fprintf(stderr,"Couldn't set audio blocking mode\n" );
- return -1;
- }
- }
- return fd;
+int rmdOpenDev(const char *pcm_dev, unsigned int channels, unsigned int frequency) {
+ int fd ;
+ unsigned int value;
+
+ fd=open(pcm_dev,O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (ioctl(fd,SNDCTL_DSP_GETFMTS,&value)<0) {
+ fprintf(stderr,"Couldn't get audio format list\n");
+ return -1;
+ }
+
+ if (value & AFMT_S16_LE) {
+ value=AFMT_S16_LE;
+ } else if (value & AFMT_S16_BE) {
+ value=AFMT_S16_BE;
+ } else {
+ fprintf(stderr,"Soundcard doesn't support signed 16-bit-data\n");
+ return -1;
+ }
+
+ if (ioctl(fd,SNDCTL_DSP_SETFMT,&value)<0) {
+ fprintf(stderr,"Couldn't set audio format\n" );
+ return -1;
+ }
+
+ value = channels;
+ if (ioctl(fd,SNDCTL_DSP_CHANNELS,&value)<0) {
+ fprintf(stderr,"Cannot set the number of channels\n" );
+ return -1;
+ }
+
+ value = frequency;
+ if (ioctl(fd,SNDCTL_DSP_SPEED,&value)<0) {
+ fprintf(stderr,"Couldn't set audio frequency\n" );
+ return -1;
+ }
+
+ if (fcntl(fd,F_SETFL,fcntl(fd,F_GETFL) & ~O_NONBLOCK)<0) {
+ fprintf(stderr,"Couldn't set audio blocking mode\n" );
+ return -1;
+ }
+
+ return fd;
}
#endif
diff --git a/recordmydesktop/src/rmd_parseargs.c b/recordmydesktop/src/rmd_parseargs.c
index e8dcb4b..3ff8d21 100644
--- a/recordmydesktop/src/rmd_parseargs.c
+++ b/recordmydesktop/src/rmd_parseargs.c
@@ -66,451 +66,446 @@ static boolean rmdValidateArguments(const ProgArgs *args);
boolean rmdParseArgs(int argc, char **argv, ProgArgs *arg_return) {
- poptContext popt_context = NULL;
- boolean no_cursor = FALSE;
- boolean quick_subsampling = FALSE;
- boolean compress_cache = FALSE;
- boolean success = TRUE;
- int arg_id = 0;
-
- // Setup the option tables
- struct poptOption generic_options[] = {
- { NULL, '\0',
- POPT_ARG_CALLBACK, (void *)rmdPrintAndExit, 0,
- NULL, NULL },
-
- { "help", 'h',
- POPT_ARG_NONE, NULL, 0,
- "Print this help and exit.",
- NULL },
-
- { "version", '\0',
- POPT_ARG_NONE, NULL, 0,
- "Print program version and exit.",
- NULL },
-
- { "print-config", '\0',
- POPT_ARG_NONE, NULL, 0,
- "Print info about options selected during compilation and exit.",
- NULL },
-
- POPT_TABLEEND };
-
- struct poptOption image_options[] = {
- { "windowid", '\0',
- POPT_ARG_INT, &arg_return->windowid, 0,
- "id of window to be recorded.",
- "id_of_window" },
-
- { "display", '\0',
- POPT_ARG_STRING, &arg_return->display, 0,
- "Display to connect to.",
- "DISPLAY" },
-
- { "x", 'x',
- POPT_ARG_INT, &arg_return->x, 0,
- "Offset in x direction.",
- "N>=0" },
-
- { "x", 'y',
- POPT_ARG_INT, &arg_return->y, 0,
- "Offset in y direction.",
- "N>=0" },
-
- { "width", '\0',
- POPT_ARG_INT, &arg_return->width, 0,
- "Width of recorded window.",
- "N>0" },
-
- { "height", '\0',
- POPT_ARG_INT, &arg_return->height, 0,
- "Height of recorded window.",
- "N>0" },
-
- { "dummy-cursor", '\0',
- POPT_ARG_STRING, NULL, RMD_ARG_DUMMY_CURSOR,
- "Color of the dummy cursor [black|white]",
- "color" },
-
- { "no-cursor", '\0',
- POPT_ARG_NONE, &no_cursor, 0,
- "Disable drawing of the cursor.",
- NULL },
-
- { "no-shared", '\0',
- POPT_ARG_NONE, &arg_return->noshared, 0,
- "Disable usage of MIT-shared memory extension(Not Recommended!).",
- NULL },
-
- { "full-shots", '\0',
- POPT_ARG_NONE, &arg_return->full_shots, 0,
- "Take full screenshot at every frame(Not recomended!).",
- NULL },
-
- { "follow-mouse", '\0',
- POPT_ARG_NONE, &arg_return->follow_mouse, 0,
- "Makes the capture area follow the mouse cursor. Autoenables --full-shots.",
- NULL },
-
- { "quick-subsampling", '\0',
- POPT_ARG_NONE, &quick_subsampling, 0,
- "Do subsampling of the chroma planes by discarding, not averaging.",
- NULL },
-
- { "fps", '\0',
- POPT_ARG_FLOAT, &arg_return->fps, 0,
- "A positive number denoting desired framerate.",
- "N(number>0.0)" },
-
- POPT_TABLEEND };
-
- struct poptOption sound_options[] = {
- { "channels", '\0',
- POPT_ARG_INT, &arg_return->channels, 0,
- "A positive number denoting desired sound channels in recording.",
- "N" },
-
- { "freq", '\0',
- POPT_ARG_INT, &arg_return->frequency, 0,
- "A positive number denoting desired sound frequency.",
- "N" },
-
- { "buffer-size", '\0',
- POPT_ARG_INT, &arg_return->buffsize, 0,
- "A positive number denoting the desired sound buffer size (in frames,when using ALSA or OSS)",
- "N" },
-
- { "ring-buffer-size", '\0',
- POPT_ARG_FLOAT, &arg_return->jack_ringbuffer_secs, 0,
- "A float number denoting the desired ring buffer size (in seconds,when using JACK only).",
- "N" },
-
- { "device", '\0',
- POPT_ARG_STRING, &arg_return->device, 0,
- "Sound device(default " DEFAULT_AUDIO_DEVICE ").",
- "SOUND_DEVICE" },
-
- { "use-jack", '\0',
- POPT_ARG_STRING | RMD_USE_JACK_EXTRA_FLAG, &arg_return->x, RMD_ARG_USE_JACK,
- "Record audio from the specified list of space-separated jack ports.",
- "port1 port2... portn" },
-
- { "no-sound", '\0',
- POPT_ARG_NONE, &arg_return->nosound, 0,
- "Do not record sound.",
- NULL },
-
- POPT_TABLEEND };
-
- struct poptOption encoding_options[] = {
- { "on-the-fly-encoding", '\0',
- POPT_ARG_NONE, &arg_return->encOnTheFly, 0,
- "Encode the audio-video data, while recording.",
- NULL },
-
- { "v_quality", '\0',
- POPT_ARG_INT, &arg_return->v_quality, 0,
- "A number from 0 to 63 for desired encoded video quality(default 63).",
- "n" },
-
- { "v_bitrate", '\0',
- POPT_ARG_INT, &arg_return->v_bitrate, 0,
- "A number from 0 to 2000000 for desired encoded video bitrate(default 0).",
- "n" },
-
- { "s_quality", '\0',
- POPT_ARG_INT, &arg_return->s_quality, 0,
- "Desired audio quality(-1 to 10).",
- "n" },
-
- POPT_TABLEEND };
-
- struct poptOption misc_options[] = {
- { "rescue", '\0',
- POPT_ARG_STRING, &arg_return->rescue_path, 0,
- "Encode data from a previous, crashed, session.",
- "path_to_data" },
-
- { "no-encode", '\0',
- POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &arg_return->no_encode, 0,
- "Do not encode any data after recording is complete. This is instead done manually afterwards with --rescue.",
- NULL },
-
- { "no-wm-check", '\0',
- POPT_ARG_NONE, &arg_return->nowmcheck, 0,
- "Do not try to detect the window manager(and set options according to it)",
- NULL },
-
- { "no-frame", '\0',
- POPT_ARG_NONE, &arg_return->noframe, 0,
- "Don not show the frame that visualizes the recorded area.",
- NULL },
-
- { "pause-shortcut", '\0',
- POPT_ARG_STRING, &arg_return->pause_shortcut, 0,
- "Shortcut that will be used for (un)pausing (default Control+Mod1+p).",
- "MOD+KEY" },
-
- { "stop-shortcut", '\0',
- POPT_ARG_STRING, &arg_return->stop_shortcut, 0,
- "Shortcut that will be used to stop the recording (default Control+Mod1+s).",
- "MOD+KEY" },
-
- { "compress-cache", '\0',
- POPT_ARG_NONE, &compress_cache, 0,
- "Image data are cached with light compression.",
- NULL },
-
- { "workdir", '\0',
- POPT_ARG_STRING, &arg_return->workdir, 0,
- "Location where a temporary directory will be created to hold project files(default $HOME).",
- "DIR" },
-
- { "delay", '\0',
- POPT_ARG_STRING, &arg_return->delay, RMD_ARG_DELAY,
- "Number of secs(default),minutes or hours before capture starts(number can be float)",
- "n[H|h|M|m]" },
-
- { "overwrite", '\0',
- POPT_ARG_NONE, &arg_return->overwrite, 0,
- "If there is already a file with the same name, delete it (default is to add a number postfix to the new one).",
- NULL },
-
- { "output", 'o',
- POPT_ARG_STRING, &arg_return->filename, 0,
- "Name of recorded video(default out.ogv).",
- "filename" },
-
- POPT_TABLEEND };
-
- struct poptOption rmd_args[] = {
- RMD_OPTION_TABLE("Generic Options", generic_options),
- RMD_OPTION_TABLE("Image Options", image_options),
- RMD_OPTION_TABLE("Sound Options", sound_options),
- RMD_OPTION_TABLE("Encoding Options", encoding_options),
- RMD_OPTION_TABLE("Misc Options", misc_options),
- POPT_TABLEEND };
-
-
- // Some trivial setup
- popt_context = poptGetContext(NULL, argc, (const char **)argv, rmd_args, 0);
- poptSetOtherOptionHelp(popt_context, "[OPTIONS]^filename");
-
-
- // Parse the arguments
- while ((arg_id = poptGetNextOpt(popt_context)) > 0) {
- char *arg = poptGetOptArg(popt_context);
-
- // Most arguments are handled completely by libpopt but we
- // handle some by ourself, namely those in this switch case
- switch (arg_id) {
- case RMD_ARG_DELAY:
- {
- float num = atof(arg);
-
- if (num > 0.0) {
- int k;
- for (k = 0; k < strlen(arg); k++) {
- if ((arg[k] == 'M') || (arg[k] == 'm')) {
- num *= 60.0;
- break;
- }
- else if ((arg[k] == 'H') || (arg[k] == 'h')) {
- num *= 3600.0;
- break;
- }
- }
- arg_return->delay = (int) num;
- }
- else {
- fprintf(stderr,
- "Argument Usage: --delay n[H|h|M|m]\n"
- "where n is a float number\n");
- success = FALSE;
- }
- }
- break;
-
- case RMD_ARG_DUMMY_CURSOR:
- {
- if (!strcmp(arg, "white"))
- arg_return->cursor_color = 0;
- else if (!strcmp(arg, "black"))
- arg_return->cursor_color = 1;
- else {
- fprintf(stderr,
- "Argument Usage:\n"
- " --dummy-cursor [black|white]\n");
- success = FALSE;
- }
- arg_return->have_dummy_cursor = TRUE;
- arg_return->xfixes_cursor = FALSE;
- }
- break;
-
- case RMD_ARG_USE_JACK:
- {
- arg_return->jack_nports = 0;
-
- while (arg) {
-
- arg_return->jack_nports++;
-
- arg_return->jack_port_names[arg_return->jack_nports - 1] = malloc(strlen(arg) + 1);
- strcpy(arg_return->jack_port_names[arg_return->jack_nports - 1], arg);
-
- arg = poptGetOptArg(popt_context);
- }
-
- if (arg_return->jack_nports > 0) {
- arg_return->use_jack = 1;
- }
- else {
- fprintf(stderr,
- "Argument Usage: --use-jack port1 port2... portn\n");
- success = FALSE;
- }
-
- if (RMD_USE_JACK_EXTRA_FLAG == POPT_ARGFLAG_DOC_HIDDEN) {
- fprintf(stderr,
- "Warning, will ignore --use-jack flags, no libjack support in build.\n");
- }
- }
-
- default:
- break;
- }
- }
-
- if (arg_id == -1) {
- // Parsing is complete, perform final adjustments
- if (no_cursor)
- arg_return->xfixes_cursor = FALSE;
-
- if (quick_subsampling)
- arg_return->no_quick_subsample = FALSE;
-
- if (compress_cache)
- arg_return->zerocompression = FALSE;
-
- if (arg_return->follow_mouse)
- arg_return->full_shots = TRUE;
-
- if (!arg_return->filename)
- arg_return->filename = strdup(poptGetArg(popt_context));
- }
- else {
- // Parsing error, say what went wrong
- const char *str = poptBadOption(popt_context, 0);
-
- success = FALSE;
-
- fprintf(stderr,
- "Error when parsing `%s': ", str);
-
- switch (arg_id) {
- case POPT_ERROR_NOARG:
- fprintf(stderr, "Missing argument\n");
- break;
-
- case POPT_ERROR_BADNUMBER:
- fprintf(stderr, "Bad number\n");
- break;
-
- default:
- fprintf(stderr, "libpopt error: %d\n", arg_id);
- break;
- }
- }
-
- // Make sure argument ranges are valid
- success = success && rmdValidateArguments(arg_return);
-
- // Clean up
- poptFreeContext(popt_context);
-
- return success;
+ poptContext popt_context = NULL;
+ boolean no_cursor = FALSE;
+ boolean quick_subsampling = FALSE;
+ boolean compress_cache = FALSE;
+ boolean success = TRUE;
+ int arg_id = 0;
+
+ // Setup the option tables
+ struct poptOption generic_options[] = {
+ { NULL, '\0',
+ POPT_ARG_CALLBACK, (void *)rmdPrintAndExit, 0,
+ NULL, NULL },
+
+ { "help", 'h',
+ POPT_ARG_NONE, NULL, 0,
+ "Print this help and exit.",
+ NULL },
+
+ { "version", '\0',
+ POPT_ARG_NONE, NULL, 0,
+ "Print program version and exit.",
+ NULL },
+
+ { "print-config", '\0',
+ POPT_ARG_NONE, NULL, 0,
+ "Print info about options selected during compilation and exit.",
+ NULL },
+
+ POPT_TABLEEND };
+
+ struct poptOption image_options[] = {
+ { "windowid", '\0',
+ POPT_ARG_INT, &arg_return->windowid, 0,
+ "id of window to be recorded.",
+ "id_of_window" },
+
+ { "display", '\0',
+ POPT_ARG_STRING, &arg_return->display, 0,
+ "Display to connect to.",
+ "DISPLAY" },
+
+ { "x", 'x',
+ POPT_ARG_INT, &arg_return->x, 0,
+ "Offset in x direction.",
+ "N>=0" },
+
+ { "x", 'y',
+ POPT_ARG_INT, &arg_return->y, 0,
+ "Offset in y direction.",
+ "N>=0" },
+
+ { "width", '\0',
+ POPT_ARG_INT, &arg_return->width, 0,
+ "Width of recorded window.",
+ "N>0" },
+
+ { "height", '\0',
+ POPT_ARG_INT, &arg_return->height, 0,
+ "Height of recorded window.",
+ "N>0" },
+
+ { "dummy-cursor", '\0',
+ POPT_ARG_STRING, NULL, RMD_ARG_DUMMY_CURSOR,
+ "Color of the dummy cursor [black|white]",
+ "color" },
+
+ { "no-cursor", '\0',
+ POPT_ARG_NONE, &no_cursor, 0,
+ "Disable drawing of the cursor.",
+ NULL },
+
+ { "no-shared", '\0',
+ POPT_ARG_NONE, &arg_return->noshared, 0,
+ "Disable usage of MIT-shared memory extension(Not Recommended!).",
+ NULL },
+
+ { "full-shots", '\0',
+ POPT_ARG_NONE, &arg_return->full_shots, 0,
+ "Take full screenshot at every frame(Not recomended!).",
+ NULL },
+
+ { "follow-mouse", '\0',
+ POPT_ARG_NONE, &arg_return->follow_mouse, 0,
+ "Makes the capture area follow the mouse cursor. Autoenables --full-shots.",
+ NULL },
+
+ { "quick-subsampling", '\0',
+ POPT_ARG_NONE, &quick_subsampling, 0,
+ "Do subsampling of the chroma planes by discarding, not averaging.",
+ NULL },
+
+ { "fps", '\0',
+ POPT_ARG_FLOAT, &arg_return->fps, 0,
+ "A positive number denoting desired framerate.",
+ "N(number>0.0)" },
+
+ POPT_TABLEEND };
+
+ struct poptOption sound_options[] = {
+ { "channels", '\0',
+ POPT_ARG_INT, &arg_return->channels, 0,
+ "A positive number denoting desired sound channels in recording.",
+ "N" },
+
+ { "freq", '\0',
+ POPT_ARG_INT, &arg_return->frequency, 0,
+ "A positive number denoting desired sound frequency.",
+ "N" },
+
+ { "buffer-size", '\0',
+ POPT_ARG_INT, &arg_return->buffsize, 0,
+ "A positive number denoting the desired sound buffer size (in frames,when using ALSA or OSS)",
+ "N" },
+
+ { "ring-buffer-size", '\0',
+ POPT_ARG_FLOAT, &arg_return->jack_ringbuffer_secs, 0,
+ "A float number denoting the desired ring buffer size (in seconds,when using JACK only).",
+ "N" },
+
+ { "device", '\0',
+ POPT_ARG_STRING, &arg_return->device, 0,
+ "Sound device(default " DEFAULT_AUDIO_DEVICE ").",
+ "SOUND_DEVICE" },
+
+ { "use-jack", '\0',
+ POPT_ARG_STRING | RMD_USE_JACK_EXTRA_FLAG, &arg_return->x, RMD_ARG_USE_JACK,
+ "Record audio from the specified list of space-separated jack ports.",
+ "port1 port2... portn" },
+
+ { "no-sound", '\0',
+ POPT_ARG_NONE, &arg_return->nosound, 0,
+ "Do not record sound.",
+ NULL },
+
+ POPT_TABLEEND };
+
+ struct poptOption encoding_options[] = {
+ { "on-the-fly-encoding", '\0',
+ POPT_ARG_NONE, &arg_return->encOnTheFly, 0,
+ "Encode the audio-video data, while recording.",
+ NULL },
+
+ { "v_quality", '\0',
+ POPT_ARG_INT, &arg_return->v_quality, 0,
+ "A number from 0 to 63 for desired encoded video quality(default 63).",
+ "n" },
+
+ { "v_bitrate", '\0',
+ POPT_ARG_INT, &arg_return->v_bitrate, 0,
+ "A number from 0 to 2000000 for desired encoded video bitrate(default 0).",
+ "n" },
+
+ { "s_quality", '\0',
+ POPT_ARG_INT, &arg_return->s_quality, 0,
+ "Desired audio quality(-1 to 10).",
+ "n" },
+
+ POPT_TABLEEND };
+
+ struct poptOption misc_options[] = {
+ { "rescue", '\0',
+ POPT_ARG_STRING, &arg_return->rescue_path, 0,
+ "Encode data from a previous, crashed, session.",
+ "path_to_data" },
+
+ { "no-encode", '\0',
+ POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &arg_return->no_encode, 0,
+ "Do not encode any data after recording is complete. This is instead done manually afterwards with --rescue.",
+ NULL },
+
+ { "no-wm-check", '\0',
+ POPT_ARG_NONE, &arg_return->nowmcheck, 0,
+ "Do not try to detect the window manager(and set options according to it)",
+ NULL },
+
+ { "no-frame", '\0',
+ POPT_ARG_NONE, &arg_return->noframe, 0,
+ "Don not show the frame that visualizes the recorded area.",
+ NULL },
+
+ { "pause-shortcut", '\0',
+ POPT_ARG_STRING, &arg_return->pause_shortcut, 0,
+ "Shortcut that will be used for (un)pausing (default Control+Mod1+p).",
+ "MOD+KEY" },
+
+ { "stop-shortcut", '\0',
+ POPT_ARG_STRING, &arg_return->stop_shortcut, 0,
+ "Shortcut that will be used to stop the recording (default Control+Mod1+s).",
+ "MOD+KEY" },
+
+ { "compress-cache", '\0',
+ POPT_ARG_NONE, &compress_cache, 0,
+ "Image data are cached with light compression.",
+ NULL },
+
+ { "workdir", '\0',
+ POPT_ARG_STRING, &arg_return->workdir, 0,
+ "Location where a temporary directory will be created to hold project files(default $HOME).",
+ "DIR" },
+
+ { "delay", '\0',
+ POPT_ARG_STRING, &arg_return->delay, RMD_ARG_DELAY,
+ "Number of secs(default),minutes or hours before capture starts(number can be float)",
+ "n[H|h|M|m]" },
+
+ { "overwrite", '\0',
+ POPT_ARG_NONE, &arg_return->overwrite, 0,
+ "If there is already a file with the same name, delete it (default is to add a number postfix to the new one).",
+ NULL },
+
+ { "output", 'o',
+ POPT_ARG_STRING, &arg_return->filename, 0,
+ "Name of recorded video(default out.ogv).",
+ "filename" },
+
+ POPT_TABLEEND };
+
+ struct poptOption rmd_args[] = {
+ RMD_OPTION_TABLE("Generic Options", generic_options),
+ RMD_OPTION_TABLE("Image Options", image_options),
+ RMD_OPTION_TABLE("Sound Options", sound_options),
+ RMD_OPTION_TABLE("Encoding Options", encoding_options),
+ RMD_OPTION_TABLE("Misc Options", misc_options),
+ POPT_TABLEEND };
+
+
+ // Some trivial setup
+ popt_context = poptGetContext(NULL, argc, (const char **)argv, rmd_args, 0);
+ poptSetOtherOptionHelp(popt_context, "[OPTIONS]^filename");
+
+
+ // Parse the arguments
+ while ((arg_id = poptGetNextOpt(popt_context)) > 0) {
+ char *arg = poptGetOptArg(popt_context);
+
+ // Most arguments are handled completely by libpopt but we
+ // handle some by ourself, namely those in this switch case
+ switch (arg_id) {
+ case RMD_ARG_DELAY:
+ {
+ float num = atof(arg);
+
+ if (num > 0.0) {
+ int k;
+ for (k = 0; k < strlen(arg); k++) {
+ if ((arg[k] == 'M') || (arg[k] == 'm')) {
+ num *= 60.0;
+ break;
+ }
+ else if ((arg[k] == 'H') || (arg[k] == 'h')) {
+ num *= 3600.0;
+ break;
+ }
+ }
+ arg_return->delay = (int) num;
+ } else {
+ fprintf(stderr,
+ "Argument Usage: --delay n[H|h|M|m]\n"
+ "where n is a float number\n");
+ success = FALSE;
+ }
+ }
+ break;
+
+ case RMD_ARG_DUMMY_CURSOR:
+ {
+ if (!strcmp(arg, "white"))
+ arg_return->cursor_color = 0;
+ else if (!strcmp(arg, "black"))
+ arg_return->cursor_color = 1;
+ else {
+ fprintf(stderr,
+ "Argument Usage:\n"
+ " --dummy-cursor [black|white]\n");
+ success = FALSE;
+ }
+ arg_return->have_dummy_cursor = TRUE;
+ arg_return->xfixes_cursor = FALSE;
+ }
+ break;
+
+ case RMD_ARG_USE_JACK:
+ {
+ arg_return->jack_nports = 0;
+
+ while (arg) {
+
+ arg_return->jack_nports++;
+
+ arg_return->jack_port_names[arg_return->jack_nports - 1] = malloc(strlen(arg) + 1);
+ strcpy(arg_return->jack_port_names[arg_return->jack_nports - 1], arg);
+
+ arg = poptGetOptArg(popt_context);
+ }
+
+ if (arg_return->jack_nports > 0) {
+ arg_return->use_jack = 1;
+ } else {
+ fprintf(stderr,
+ "Argument Usage: --use-jack port1 port2... portn\n");
+ success = FALSE;
+ }
+
+ if (RMD_USE_JACK_EXTRA_FLAG == POPT_ARGFLAG_DOC_HIDDEN) {
+ fprintf(stderr,
+ "Warning, will ignore --use-jack flags, no libjack support in build.\n");
+ }
+ }
+
+ default:
+ break;
+ }
+ }
+
+ if (arg_id == -1) {
+ // Parsing is complete, perform final adjustments
+ if (no_cursor)
+ arg_return->xfixes_cursor = FALSE;
+
+ if (quick_subsampling)
+ arg_return->no_quick_subsample = FALSE;
+
+ if (compress_cache)
+ arg_return->zerocompression = FALSE;
+
+ if (arg_return->follow_mouse)
+ arg_return->full_shots = TRUE;
+
+ if (!arg_return->filename)
+ arg_return->filename = strdup(poptGetArg(popt_context));
+ } else {
+ // Parsing error, say what went wrong
+ const char *str = poptBadOption(popt_context, 0);
+
+ success = FALSE;
+
+ fprintf(stderr,
+ "Error when parsing `%s': ", str);
+
+ switch (arg_id) {
+ case POPT_ERROR_NOARG:
+ fprintf(stderr, "Missing argument\n");
+ break;
+
+ case POPT_ERROR_BADNUMBER:
+ fprintf(stderr, "Bad number\n");
+ break;
+
+ default:
+ fprintf(stderr, "libpopt error: %d\n", arg_id);
+ break;
+ }
+ }
+
+ // Make sure argument ranges are valid
+ success = success && rmdValidateArguments(arg_return);
+
+ // Clean up
+ poptFreeContext(popt_context);
+
+ return success;
}
static boolean rmdValidateArguments(const ProgArgs *args)
{
- boolean success = TRUE;
-
- if (args->x < 0) {
- fprintf(stdout, "-x must not be less than 0.\n");
- success = FALSE;
- }
- if (args->y < 0) {
- fprintf(stdout, "-y must not be less than 0.\n");
- success = FALSE;
- }
- if (args->width < 0) {
- fprintf(stdout, "--width must be larger than 0.\n");
- success = FALSE;
- }
- if (args->height < 0) {
- fprintf(stdout, "--height must be larger than 0.\n");
- success = FALSE;
- }
- if (args->fps <= 0) {
- fprintf(stdout, "--fps must be larger than 0.\n");
- success = FALSE;
- }
- if (args->v_quality < 0 || args->v_quality > 63) {
- fprintf(stdout, "--v_quality must be within the inclusive range [0-63].\n");
- success = FALSE;
- }
- if (args->v_bitrate < 0 || args->v_quality > 2000000) {
- fprintf(stdout, "--v_bitrate must be within the inclusive range [0-2000000].\n");
- success = FALSE;
- }
- if (args->frequency <= 0) {
- fprintf(stdout, "--frequency must be larger than 0.\n");
- success = FALSE;
- }
- if (args->channels <= 0) {
- fprintf(stdout, "--channels must be larger than 0.\n");
- success = FALSE;
- }
- if (args->buffsize <= 0) {
- fprintf(stdout, "--buffer-size must be larger than 0.\n");
- success = FALSE;
- }
- if (args->jack_ringbuffer_secs <= 0) {
- fprintf(stdout, "--jack-buffer-size must be larger than 0.\n");
- success = FALSE;
- }
-
- return success;
+ boolean success = TRUE;
+
+ if (args->x < 0) {
+ fprintf(stdout, "-x must not be less than 0.\n");
+ success = FALSE;
+ }
+ if (args->y < 0) {
+ fprintf(stdout, "-y must not be less than 0.\n");
+ success = FALSE;
+ }
+ if (args->width < 0) {
+ fprintf(stdout, "--width must be larger than 0.\n");
+ success = FALSE;
+ }
+ if (args->height < 0) {
+ fprintf(stdout, "--height must be larger than 0.\n");
+ success = FALSE;
+ }
+ if (args->fps <= 0) {
+ fprintf(stdout, "--fps must be larger than 0.\n");
+ success = FALSE;
+ }
+ if (args->v_quality < 0 || args->v_quality > 63) {
+ fprintf(stdout, "--v_quality must be within the inclusive range [0-63].\n");
+ success = FALSE;
+ }
+ if (args->v_bitrate < 0 || args->v_quality > 2000000) {
+ fprintf(stdout, "--v_bitrate must be within the inclusive range [0-2000000].\n");
+ success = FALSE;
+ }
+ if (args->frequency <= 0) {
+ fprintf(stdout, "--frequency must be larger than 0.\n");
+ success = FALSE;
+ }
+ if (args->channels <= 0) {
+ fprintf(stdout, "--channels must be larger than 0.\n");
+ success = FALSE;
+ }
+ if (args->buffsize <= 0) {
+ fprintf(stdout, "--buffer-size must be larger than 0.\n");
+ success = FALSE;
+ }
+ if (args->jack_ringbuffer_secs <= 0) {
+ fprintf(stdout, "--jack-buffer-size must be larger than 0.\n");
+ success = FALSE;
+ }
+
+ return success;
}
-static void rmdPrintAndExit(poptContext con,
- enum poptCallbackReason reason,
- const struct poptOption *opt,
- const char *arg,
- const void *data)
+static void rmdPrintAndExit( poptContext con,
+ enum poptCallbackReason reason,
+ const struct poptOption *opt,
+ const char *arg,
+ const void *data)
{
- if (strcmp(opt->longName, "version") == 0) {
- fprintf(stderr,"recordMyDesktop v%s\n\n",VERSION);
- }
- else if (strcmp(opt->longName, "help") == 0) {
- poptPrintHelp(con, stdout, 0);
- fprintf(stdout,
- "\n"
- "\tIf no other options are specified, filename can be given without the -o switch.\n"
- "\n"
- "\n");
- }
- else if (strcmp(opt->longName, "print-config") == 0) {
- fprintf(stdout,
- "\n"
- "recordMyDesktop was compiled with the following options:\n"
- "\n"
- "Jack:\t\t\t" RMD_LIBJACK_STATUS "\n"
- "Default Audio Backend:\t" RMD_LIBASOUND_STATUS "\n"
- "\n"
- "\n");
- }
-
- exit(0);
+ if (strcmp(opt->longName, "version") == 0) {
+ fprintf(stderr,"recordMyDesktop v%s\n\n",VERSION);
+ } else if (strcmp(opt->longName, "help") == 0) {
+ poptPrintHelp(con, stdout, 0);
+ fprintf(stdout,
+ "\n"
+ "\tIf no other options are specified, filename can be given without the -o switch.\n"
+ "\n"
+ "\n");
+ } else if (strcmp(opt->longName, "print-config") == 0) {
+ fprintf(stdout,
+ "\n"
+ "recordMyDesktop was compiled with the following options:\n"
+ "\n"
+ "Jack:\t\t\t" RMD_LIBJACK_STATUS "\n"
+ "Default Audio Backend:\t" RMD_LIBASOUND_STATUS "\n"
+ "\n"
+ "\n");
+ }
+
+ exit(0);
}
diff --git a/recordmydesktop/src/rmd_poll_events.c b/recordmydesktop/src/rmd_poll_events.c
index db56219..9745889 100644
--- a/recordmydesktop/src/rmd_poll_events.c
+++ b/recordmydesktop/src/rmd_poll_events.c
@@ -42,10 +42,10 @@
#include <pthread.h>
-#define CLIP_EVENT_AREA(e,brwin,xrect){\
- if(((e)->area.x<=(brwin)->rrect.x)&&((e)->area.y<=(brwin)->rrect.y)&&\
+#define CLIP_EVENT_AREA(e,brwin,xrect) {\
+ if (((e)->area.x<=(brwin)->rrect.x)&&((e)->area.y<=(brwin)->rrect.y)&&\
((e)->area.width>=(brwin)->rrect.width)&&\
- ((e)->area.height<(brwin)->rrect.height)){\
+ ((e)->area.height<(brwin)->rrect.height)) {\
(xrect)->x=(brwin)->rrect.x;\
(xrect)->y=(brwin)->rrect.y;\
(xrect)->width=(brwin)->rrect.width;\
@@ -74,136 +74,124 @@
(brwin)->rrect.height-(e)->area.y+\
(brwin)->rrect.y:(e)->area.height):0;\
\
- if((xrect)->width>(brwin)->rrect.width)\
+ if ((xrect)->width>(brwin)->rrect.width)\
(xrect)->width=(brwin)->rrect.width;\
- if((xrect)->height>(brwin)->rrect.height)\
+ if ((xrect)->height>(brwin)->rrect.height)\
(xrect)->height=(brwin)->rrect.height;\
}\
}
-void rmdInitEventsPolling(ProgData *pdata){
- Window root_return,
- parent_return,
- *children;
- unsigned int i,
- nchildren;
-
-
- XSelectInput (pdata->dpy,pdata->specs.root, SubstructureNotifyMask);
-
-
- if(!pdata->args.full_shots){
- XQueryTree (pdata->dpy,
- pdata->specs.root,
- &root_return,
- &parent_return,
- &children,
- &nchildren);
-
- for (i = 0; i < nchildren; i++){
- XWindowAttributes attribs;
- if (XGetWindowAttributes (pdata->dpy,children[i],&attribs)){
- if(!attribs.override_redirect &&
- attribs.depth==pdata->specs.depth)
- XDamageCreate(pdata->dpy,
- children[i],
- XDamageReportRawRectangles);
- }
- }
- XFree(children);
- XDamageCreate(pdata->dpy,
- pdata->specs.root,
- XDamageReportRawRectangles);
- }
-
-
-
+void rmdInitEventsPolling(ProgData *pdata) {
+ Window root_return,
+ parent_return,
+ *children;
+ unsigned int i,
+ nchildren;
+
+ XSelectInput (pdata->dpy,pdata->specs.root, SubstructureNotifyMask);
+
+ if (!pdata->args.full_shots) {
+ XQueryTree ( pdata->dpy,
+ pdata->specs.root,
+ &root_return,
+ &parent_return,
+ &children,
+ &nchildren);
+
+ for (i = 0; i < nchildren; i++) {
+ XWindowAttributes attribs;
+ if (XGetWindowAttributes (pdata->dpy,children[i],&attribs)) {
+ if (!attribs.override_redirect && attribs.depth==pdata->specs.depth)
+ XDamageCreate( pdata->dpy,
+ children[i],
+ XDamageReportRawRectangles);
+ }
+ }
+ XFree(children);
+ XDamageCreate( pdata->dpy,
+ pdata->specs.root,
+ XDamageReportRawRectangles);
+ }
}
-void rmdEventLoop(ProgData *pdata){
- int inserts=0;
-
- XEvent event;
-
- while(XPending(pdata->dpy)){
- XNextEvent(pdata->dpy,&event);
- if(event.type == KeyPress){
- XKeyEvent *e=(XKeyEvent *)(&event);
- if(e->keycode == pdata->pause_key.key){
- int i=0;
- int found=0;
- for(i=0;i<pdata->pause_key.modnum;i++){
- if(pdata->pause_key.mask[i]==e->state){
- found=1;
- break;
- }
- }
- if(found){
- raise(SIGUSR1);
- continue;
- }
- }
- if(e->keycode == pdata->stop_key.key){
- int i=0;
- int found=0;
- for(i=0;i<pdata->stop_key.modnum;i++){
- if(pdata->stop_key.mask[i]==e->state){
- found=1;
- break;
- }
- }
- if(found){
- raise(SIGINT);
- continue;
- }
- }
- }
- else if(event.type == Expose){
-
- if(event.xexpose.count!=0)
- continue;
- else if(!pdata->args.noframe){
- rmdDrawFrame(pdata->dpy,
- pdata->specs.screen,
- pdata->shaped_w,
- pdata->brwin.rrect.width,
- pdata->brwin.rrect.height);
-
- }
-
- }
- else if(!pdata->args.full_shots){
- if(event.type == MapNotify ){
- XWindowAttributes attribs;
- if (!((XMapEvent *)(&event))->override_redirect&&
- XGetWindowAttributes(pdata->dpy,
- event.xcreatewindow.window,
- &attribs)){
- if(!attribs.override_redirect&&
- attribs.depth==pdata->specs.depth)
- XDamageCreate(pdata->dpy,
- event.xcreatewindow.window,
- XDamageReportRawRectangles);
- }
- }
- else if(event.type == pdata->damage_event + XDamageNotify ){
- XDamageNotifyEvent *e =(XDamageNotifyEvent *)( &event );
- XRectangle xrect;
- CLIP_EVENT_AREA(e,&(pdata->brwin),&xrect);
- if((xrect.x>=0)&&(xrect.y>=0)&&
- (xrect.width>0)&&(xrect.height>0)){
-
- inserts+=rmdRectInsert(&pdata->rect_root,&xrect);
-
- }
- }
- }
-
- }
-
-
+void rmdEventLoop(ProgData *pdata) {
+ int inserts=0;
+
+ XEvent event;
+
+ while (XPending(pdata->dpy)) {
+ XNextEvent(pdata->dpy,&event);
+ if (event.type == KeyPress) {
+ XKeyEvent *e=(XKeyEvent *)(&event);
+ if (e->keycode == pdata->pause_key.key) {
+ int i=0;
+ int found=0;
+ for (i=0;i<pdata->pause_key.modnum;i++) {
+ if (pdata->pause_key.mask[i]==e->state) {
+ found=1;
+ break;
+ }
+ }
+ if (found) {
+ raise(SIGUSR1);
+ continue;
+ }
+ }
+ if (e->keycode == pdata->stop_key.key) {
+ int i=0;
+ int found=0;
+ for (i=0;i<pdata->stop_key.modnum;i++) {
+ if (pdata->stop_key.mask[i]==e->state) {
+ found=1;
+ break;
+ }
+ }
+ if (found) {
+ raise(SIGINT);
+ continue;
+ }
+ }
+ } else if (event.type == Expose) {
+
+ if (event.xexpose.count!=0)
+ continue;
+ else if (!pdata->args.noframe) {
+ rmdDrawFrame( pdata->dpy,
+ pdata->specs.screen,
+ pdata->shaped_w,
+ pdata->brwin.rrect.width,
+ pdata->brwin.rrect.height);
+
+ }
+
+ } else if (!pdata->args.full_shots) {
+ if (event.type == MapNotify ) {
+ XWindowAttributes attribs;
+
+ if (!((XMapEvent *)(&event))->override_redirect&&
+ XGetWindowAttributes( pdata->dpy,
+ event.xcreatewindow.window,
+ &attribs)) {
+
+ if (!attribs.override_redirect&& attribs.depth==pdata->specs.depth)
+ XDamageCreate( pdata->dpy,
+ event.xcreatewindow.window,
+ XDamageReportRawRectangles);
+ }
+ } else if (event.type == pdata->damage_event + XDamageNotify ) {
+ XDamageNotifyEvent *e =(XDamageNotifyEvent *)( &event );
+ XRectangle xrect;
+ CLIP_EVENT_AREA(e,&(pdata->brwin),&xrect);
+ if ((xrect.x>=0)&&(xrect.y>=0)&&
+ (xrect.width>0)&&(xrect.height>0)) {
+
+ inserts+=rmdRectInsert(&pdata->rect_root,&xrect);
+
+ }
+ }
+ }
+
+ }
}
-
-
diff --git a/recordmydesktop/src/rmd_queryextensions.c b/recordmydesktop/src/rmd_queryextensions.c
index a7ecab0..087f7d2 100644
--- a/recordmydesktop/src/rmd_queryextensions.c
+++ b/recordmydesktop/src/rmd_queryextensions.c
@@ -36,49 +36,51 @@
-void rmdQueryExtensions(Display *dpy,
- ProgArgs *args,
- int *damage_event,
- int *damage_error,
- int *shm_opcode){
- int xf_event_basep,
- xf_error_basep,
- shm_event_base,
- shm_error_base,
- shape_event_base,
- shape_error_base;
+void rmdQueryExtensions( Display *dpy,
+ ProgArgs *args,
+ int *damage_event,
+ int *damage_error,
+ int *shm_opcode) {
+ int xf_event_basep,
+ xf_error_basep,
+ shm_event_base,
+ shm_error_base,
+ shape_event_base,
+ shape_error_base;
- if((!(args->full_shots))&&(!XDamageQueryExtension( dpy, damage_event, damage_error))){
- fprintf(stderr,"XDamage extension not found!!!\n"
- "Try again using the --full-shots option, though\n"
- "enabling XDamage is highly recommended,\n"
- "for performance reasons.\n");
- exit(4);
- }
- if((!args->noshared)&&(!XQueryExtension(dpy,
- "MIT-SHM",
- shm_opcode,
- &shm_event_base,
- &shm_error_base))){
- args->noshared=1;
- fprintf(stderr,"Shared Memory extension not present!\n"
- "Try again using the --no-shared option\n");
- exit(5);
- }
- if((args->xfixes_cursor)&&
- (XFixesQueryExtension(dpy,&xf_event_basep,&xf_error_basep)==False)){
- args->xfixes_cursor=0;
- fprintf(stderr,"Xfixes extension not present!\n"
- "Please run with the -dummy-cursor or"
- " --no-cursor option.\n");
- exit(6);
- }
- if((!args->noframe)&&
- (!XShapeQueryExtension(dpy,&shape_event_base,&shape_error_base))){
- fprintf(stderr,"XShape Not Found!!!\n"
- "Frame won't be available.\n");
+ if ((!(args->full_shots))&&(!XDamageQueryExtension( dpy, damage_event, damage_error))) {
+ fprintf(stderr, "XDamage extension not found!!!\n"
+ "Try again using the --full-shots option, though\n"
+ "enabling XDamage is highly recommended,\n"
+ "for performance reasons.\n");
+ exit(4);
+ }
- args->noframe=1;
- }
+ if ((!args->noshared)&&(!XQueryExtension( dpy,
+ "MIT-SHM",
+ shm_opcode,
+ &shm_event_base,
+ &shm_error_base))) {
+ args->noshared=1;
+ fprintf(stderr,"Shared Memory extension not present!\n"
+ "Try again using the --no-shared option\n");
+ exit(5);
+ }
+ if ((args->xfixes_cursor)&&
+ (XFixesQueryExtension(dpy,&xf_event_basep,&xf_error_basep)==False)) {
+ args->xfixes_cursor=0;
+ fprintf(stderr,"Xfixes extension not present!\n"
+ "Please run with the -dummy-cursor or"
+ " --no-cursor option.\n");
+ exit(6);
+ }
+
+ if ((!args->noframe)&&
+ (!XShapeQueryExtension(dpy,&shape_event_base,&shape_error_base))) {
+ fprintf(stderr,"XShape Not Found!!!\n"
+ "Frame won't be available.\n");
+
+ args->noframe=1;
+ }
}
diff --git a/recordmydesktop/src/rmd_rectinsert.c b/recordmydesktop/src/rmd_rectinsert.c
index 33addea..acb4aae 100644
--- a/recordmydesktop/src/rmd_rectinsert.c
+++ b/recordmydesktop/src/rmd_rectinsert.c
@@ -57,34 +57,31 @@
*
*/
static int rmdCollideRects(XRectangle *xrect1,
- XRectangle *xrect2,
- XRectangle xrect_return[],
- int *nrects) {
- //1 fits in 2
- if((xrect1->x>=xrect2->x)&&
- (xrect1->x+xrect1->width<=xrect2->x+xrect2->width)&&
- (xrect1->y>=xrect2->y)&&
- (xrect1->y+xrect1->height<=xrect2->y+xrect2->height)){
- *nrects=0;
- return 1;
- }
- //2 fits in 1
- else if((xrect2->x>=xrect1->x)&&
- (xrect2->x+xrect2->width<=xrect1->x+xrect1->width)&&
- (xrect2->y>=xrect1->y)&&
- (xrect2->y+xrect2->height<=xrect1->y+xrect1->height)){
- *nrects=0;
- return 2;
- }
- //no collision
- else if((xrect1->x+xrect1->width<xrect2->x)||
- (xrect2->x+xrect2->width<xrect1->x)||
- (xrect1->y+xrect1->height<xrect2->y)||
- (xrect2->y+xrect2->height<xrect1->y)){
- *nrects=0;
- return 0;
- }
- else{
+ XRectangle *xrect2,
+ XRectangle xrect_return[],
+ int *nrects) {
+ if ((xrect1->x>=xrect2->x)&&
+ (xrect1->x+xrect1->width<=xrect2->x+xrect2->width)&&
+ (xrect1->y>=xrect2->y)&&
+ (xrect1->y+xrect1->height<=xrect2->y+xrect2->height)) {
+ //1 fits in 2
+ *nrects=0;
+ return 1;
+ } else if ((xrect2->x>=xrect1->x)&&
+ (xrect2->x+xrect2->width<=xrect1->x+xrect1->width)&&
+ (xrect2->y>=xrect1->y)&&
+ (xrect2->y+xrect2->height<=xrect1->y+xrect1->height)) {
+ //2 fits in 1
+ *nrects=0;
+ return 2;
+ } else if ((xrect1->x+xrect1->width<xrect2->x)||
+ (xrect2->x+xrect2->width<xrect1->x)||
+ (xrect1->y+xrect1->height<xrect2->y)||
+ (xrect2->y+xrect2->height<xrect1->y)) {
+ //no collision
+ *nrects=0;
+ return 0;
+ } else {
//overlapping points are considered enclosed
//this happens because libxdamage may generate many events for one change
//and some of them may be in the the exact same region
@@ -93,438 +90,409 @@ static int rmdCollideRects(XRectangle *xrect1,
//function should always start at the next element(which is logical since
//if any rect makes it to a points none of it's part collides with previous
//nodes on the list, too)
- int x1[2]={xrect1->x,xrect1->x+xrect1->width};
- int y1[2]={xrect1->y,xrect1->y+xrect1->height};
- int x2[2]={xrect2->x,xrect2->x+xrect2->width};
- int y2[2]={xrect2->y,xrect2->y+xrect2->height};
- int enclosed[2][4],tot1,tot2;
- enclosed[0][0]=(((x1[0]>=x2[0])&&(x1[0]<=x2[1])&&
- (y1[0]>=y2[0])&&(y1[0]<=y2[1]))?1:0);
- enclosed[0][1]=(((x1[1]>=x2[0])&&(x1[1]<=x2[1])&&
- (y1[0]>=y2[0])&&(y1[0]<=y2[1]))?1:0);
- enclosed[0][2]=(((x1[0]>=x2[0])&&(x1[0]<=x2[1])&&
- (y1[1]>=y2[0])&&(y1[1]<=y2[1]))?1:0);
- enclosed[0][3]=(((x1[1]>=x2[0])&&(x1[1]<=x2[1])&&
- (y1[1]>=y2[0])&&(y1[1]<=y2[1]))?1:0);
- enclosed[1][0]=(((x2[0]>=x1[0])&&(x2[0]<=x1[1])&&
- (y2[0]>=y1[0])&&(y2[0]<=y1[1]))?1:0);
- enclosed[1][1]=(((x2[1]>=x1[0])&&(x2[1]<=x1[1])&&
- (y2[0]>=y1[0])&&(y2[0]<=y1[1]))?1:0);
- enclosed[1][2]=(((x2[0]>=x1[0])&&(x2[0]<=x1[1])&&
- (y2[1]>=y1[0])&&(y2[1]<=y1[1]))?1:0);
- enclosed[1][3]=(((x2[1]>=x1[0])&&(x2[1]<=x1[1])&&
- (y2[1]>=y1[0])&&(y2[1]<=y1[1]))?1:0);
- tot1=enclosed[0][0]+enclosed[0][1]+enclosed[0][2]+enclosed[0][3];
- tot2=enclosed[1][0]+enclosed[1][1]+enclosed[1][2]+enclosed[1][3];
- if((tot1==2)&&(tot2==2)){//same width or height, which is the best case
- //group
- if((enclosed[1][0]&&enclosed[1][1])&&
- (xrect1->width==xrect2->width)){
- *nrects=1;
- xrect_return[0].x = xrect1->x;
- xrect_return[0].y = xrect1->y;
- xrect_return[0].width = xrect1->width;
- xrect_return[0].height = xrect2->height + xrect2->y - xrect1->y;
- return -10;
- }
- else if((enclosed[1][0]&&enclosed[1][2])&&
- (xrect1->height==xrect2->height)){
- *nrects=1;
- xrect_return[0].x = xrect1->x;
- xrect_return[0].y = xrect1->y;
- xrect_return[0].width = xrect2->width + xrect2->x - xrect1->x;
- xrect_return[0].height = xrect1->height;
- return -10;
- }
- else if((enclosed[1][3]&&enclosed[1][1])&&
- (xrect1->height==xrect2->height)){
- *nrects=1;
- xrect_return[0].x = xrect2->x;
- xrect_return[0].y = xrect2->y;
- xrect_return[0].width = xrect1->width + xrect1->x - xrect2->x;
- xrect_return[0].height = xrect2->height;
- return -10;
- }
- else if((enclosed[1][3]&&enclosed[1][2])&&
- (xrect1->width==xrect2->width)){
- *nrects=1;
- xrect_return[0].x = xrect2->x;
- xrect_return[0].y = xrect2->y;
- xrect_return[0].width = xrect2->width;
- xrect_return[0].height = xrect1->height + xrect1->y - xrect2->y;
- return -10;
- }
- //if control reaches here therewasn't a group and we go on
- }
- if(tot2==2){
- //break rect2
- xrect_return[0].x = xrect2->x;
- xrect_return[0].y = xrect2->y;
- xrect_return[0].width = xrect2->width;
- xrect_return[0].height = xrect2->height;
- *nrects=1;
- if(enclosed[1][0]&&enclosed[1][1]){
- xrect_return[0].y = y1[1];
- xrect_return[0].height -= y1[1] - y2[0];
- }
- else if(enclosed[1][0]&&enclosed[1][2]){
- xrect_return[0].x = x1[1];
- xrect_return[0].width -= x1[1] - x2[0];
- }
- else if(enclosed[1][3]&&enclosed[1][1])
- xrect_return[0].width -= x2[1] - x1[0];
- else if(enclosed[1][3]&&enclosed[1][2])
- xrect_return[0].height -= y2[1] - y1[0];
- return -2;
- }
- else if(tot1==2){
- //if the first one breaks(which is already inserted)
- //then we reenter the part that was left and the one
- //that was to be inserted
- xrect_return[1].x = xrect2->x;
- xrect_return[1].y = xrect2->y;
- xrect_return[1].width = xrect2->width;
- xrect_return[1].height = xrect2->height;
- xrect_return[0].x = xrect1->x;
- xrect_return[0].y = xrect1->y;
- xrect_return[0].width = xrect1->width;
- xrect_return[0].height = xrect1->height;
- *nrects=1;
- if(enclosed[0][0]&&enclosed[0][1]){
- xrect_return[0].y = y2[1];
- xrect_return[0].height -= y2[1] - y1[0];
- }
- else if(enclosed[0][0]&&enclosed[0][2]){
- xrect_return[0].x = x2[1];
- xrect_return[0].width -= x2[1] - x1[0];
- }
- else if(enclosed[0][3]&&enclosed[0][1])
- xrect_return[0].width -= x1[1] - x2[0];
- else if(enclosed[0][3]&&enclosed[0][2])
- xrect_return[0].height -= y1[1] - y2[0];
- return -1;
+ int x1[2]={xrect1->x,xrect1->x+xrect1->width};
+ int y1[2]={xrect1->y,xrect1->y+xrect1->height};
+ int x2[2]={xrect2->x,xrect2->x+xrect2->width};
+ int y2[2]={xrect2->y,xrect2->y+xrect2->height};
+ int enclosed[2][4],tot1,tot2;
+ enclosed[0][0]=(((x1[0]>=x2[0])&&(x1[0]<=x2[1])&&
+ (y1[0]>=y2[0])&&(y1[0]<=y2[1]))?1:0);
+ enclosed[0][1]=(((x1[1]>=x2[0])&&(x1[1]<=x2[1])&&
+ (y1[0]>=y2[0])&&(y1[0]<=y2[1]))?1:0);
+ enclosed[0][2]=(((x1[0]>=x2[0])&&(x1[0]<=x2[1])&&
+ (y1[1]>=y2[0])&&(y1[1]<=y2[1]))?1:0);
+ enclosed[0][3]=(((x1[1]>=x2[0])&&(x1[1]<=x2[1])&&
+ (y1[1]>=y2[0])&&(y1[1]<=y2[1]))?1:0);
+ enclosed[1][0]=(((x2[0]>=x1[0])&&(x2[0]<=x1[1])&&
+ (y2[0]>=y1[0])&&(y2[0]<=y1[1]))?1:0);
+ enclosed[1][1]=(((x2[1]>=x1[0])&&(x2[1]<=x1[1])&&
+ (y2[0]>=y1[0])&&(y2[0]<=y1[1]))?1:0);
+ enclosed[1][2]=(((x2[0]>=x1[0])&&(x2[0]<=x1[1])&&
+ (y2[1]>=y1[0])&&(y2[1]<=y1[1]))?1:0);
+ enclosed[1][3]=(((x2[1]>=x1[0])&&(x2[1]<=x1[1])&&
+ (y2[1]>=y1[0])&&(y2[1]<=y1[1]))?1:0);
+ tot1=enclosed[0][0]+enclosed[0][1]+enclosed[0][2]+enclosed[0][3];
+ tot2=enclosed[1][0]+enclosed[1][1]+enclosed[1][2]+enclosed[1][3];
+ if ((tot1==2)&&(tot2==2)) {//same width or height, which is the best case
+ //group
+ if ((enclosed[1][0]&&enclosed[1][1])&&
+ (xrect1->width==xrect2->width)) {
+ *nrects=1;
+ xrect_return[0].x = xrect1->x;
+ xrect_return[0].y = xrect1->y;
+ xrect_return[0].width = xrect1->width;
+ xrect_return[0].height = xrect2->height + xrect2->y - xrect1->y;
+ return -10;
+ } else if ((enclosed[1][0]&&enclosed[1][2])&&
+ (xrect1->height==xrect2->height)) {
+ *nrects=1;
+ xrect_return[0].x = xrect1->x;
+ xrect_return[0].y = xrect1->y;
+ xrect_return[0].width = xrect2->width + xrect2->x - xrect1->x;
+ xrect_return[0].height = xrect1->height;
+ return -10;
+ } else if ((enclosed[1][3]&&enclosed[1][1])&&
+ (xrect1->height==xrect2->height)) {
+ *nrects=1;
+ xrect_return[0].x = xrect2->x;
+ xrect_return[0].y = xrect2->y;
+ xrect_return[0].width = xrect1->width + xrect1->x - xrect2->x;
+ xrect_return[0].height = xrect2->height;
+ return -10;
+ } else if ((enclosed[1][3]&&enclosed[1][2])&&
+ (xrect1->width==xrect2->width)) {
+ *nrects=1;
+ xrect_return[0].x = xrect2->x;
+ xrect_return[0].y = xrect2->y;
+ xrect_return[0].width = xrect2->width;
+ xrect_return[0].height = xrect1->height + xrect1->y - xrect2->y;
+ return -10;
+ }
+ //if control reaches here therewasn't a group and we go on
+ }
- }
- else if(tot2==1){ //in which case there is also tot1==1
- //but we rather not break that
- //break rect2 in two
- *nrects=2;
- if(enclosed[1][0]){
+ if (tot2==2) {
+ //break rect2
+ xrect_return[0].x = xrect2->x;
+ xrect_return[0].y = xrect2->y;
+ xrect_return[0].width = xrect2->width;
+ xrect_return[0].height = xrect2->height;
+ *nrects=1;
+ if (enclosed[1][0]&&enclosed[1][1]) {
+ xrect_return[0].y = y1[1];
+ xrect_return[0].height -= y1[1] - y2[0];
+ } else if (enclosed[1][0]&&enclosed[1][2]) {
+ xrect_return[0].x = x1[1];
+ xrect_return[0].width -= x1[1] - x2[0];
+ } else if (enclosed[1][3]&&enclosed[1][1])
+ xrect_return[0].width -= x2[1] - x1[0];
+ else if (enclosed[1][3]&&enclosed[1][2])
+ xrect_return[0].height -= y2[1] - y1[0];
+ return -2;
+ } else if (tot1==2) {
+ //if the first one breaks(which is already inserted)
+ //then we reenter the part that was left and the one
+ //that was to be inserted
+ xrect_return[1].x = xrect2->x;
+ xrect_return[1].y = xrect2->y;
+ xrect_return[1].width = xrect2->width;
+ xrect_return[1].height = xrect2->height;
+ xrect_return[0].x = xrect1->x;
+ xrect_return[0].y = xrect1->y;
+ xrect_return[0].width = xrect1->width;
+ xrect_return[0].height = xrect1->height;
+ *nrects=1;
+ if (enclosed[0][0]&&enclosed[0][1]) {
+ xrect_return[0].y = y2[1];
+ xrect_return[0].height -= y2[1] - y1[0];
+ } else if (enclosed[0][0]&&enclosed[0][2]) {
+ xrect_return[0].x = x2[1];
+ xrect_return[0].width -= x2[1] - x1[0];
+ } else if (enclosed[0][3]&&enclosed[0][1])
+ xrect_return[0].width -= x1[1] - x2[0];
+ else if (enclosed[0][3]&&enclosed[0][2])
+ xrect_return[0].height -= y1[1] - y2[0];
+ return -1;
+
+ } else if (tot2==1) { //in which case there is also tot1==1
+ //but we rather not break that
+ //break rect2 in two
+ *nrects=2;
+ if (enclosed[1][0]) {
//first
- xrect_return[0].x = x1[1];
- xrect_return[0].y = y2[0];
- xrect_return[0].width = xrect2->width - x1[1] + x2[0];
- xrect_return[0].height = xrect2->height;
+ xrect_return[0].x = x1[1];
+ xrect_return[0].y = y2[0];
+ xrect_return[0].width = xrect2->width - x1[1] + x2[0];
+ xrect_return[0].height = xrect2->height;
//second
- xrect_return[1].x = x2[0];
- xrect_return[1].y = y1[1];
- xrect_return[1].width = x1[1] - x2[0];
- xrect_return[1].height = xrect2->height - y1[1] + y2[0];
- }
- else if(enclosed[1][1]){
+ xrect_return[1].x = x2[0];
+ xrect_return[1].y = y1[1];
+ xrect_return[1].width = x1[1] - x2[0];
+ xrect_return[1].height = xrect2->height - y1[1] + y2[0];
+ } else if (enclosed[1][1]) {
//first
- xrect_return[0].x = x2[0];
- xrect_return[0].y = y2[0];
- xrect_return[0].width = xrect2->width - x2[1] + x1[0];
- xrect_return[0].height = xrect2->height;
+ xrect_return[0].x = x2[0];
+ xrect_return[0].y = y2[0];
+ xrect_return[0].width = xrect2->width - x2[1] + x1[0];
+ xrect_return[0].height = xrect2->height;
//second
- xrect_return[1].x = x1[0];
- xrect_return[1].y = y1[1];
- xrect_return[1].width = x2[1] - x1[0];
- xrect_return[1].height = xrect2->height - y1[1] + y2[0];
- }
- else if(enclosed[1][2]){
+ xrect_return[1].x = x1[0];
+ xrect_return[1].y = y1[1];
+ xrect_return[1].width = x2[1] - x1[0];
+ xrect_return[1].height = xrect2->height - y1[1] + y2[0];
+ } else if (enclosed[1][2]) {
//first(same as [1][0])
- xrect_return[0].x = x1[1];
- xrect_return[0].y = y2[0];
- xrect_return[0].width = xrect2->width - x1[1] + x2[0];
- xrect_return[0].height = xrect2->height;
+ xrect_return[0].x = x1[1];
+ xrect_return[0].y = y2[0];
+ xrect_return[0].width = xrect2->width - x1[1] + x2[0];
+ xrect_return[0].height = xrect2->height;
//second
- xrect_return[1].x = x2[0];
- xrect_return[1].y = y2[0];
- xrect_return[1].width = x1[1] - x2[0];
- xrect_return[1].height = xrect2->height - y2[1] + y1[0];
- }
- else if(enclosed[1][3]){
+ xrect_return[1].x = x2[0];
+ xrect_return[1].y = y2[0];
+ xrect_return[1].width = x1[1] - x2[0];
+ xrect_return[1].height = xrect2->height - y2[1] + y1[0];
+ } else if (enclosed[1][3]) {
//first(same as [1][1])
- xrect_return[0].x = x2[0];
- xrect_return[0].y = y2[0];
- xrect_return[0].width = xrect2->width - x2[1] + x1[0];
- xrect_return[0].height = xrect2->height;
+ xrect_return[0].x = x2[0];
+ xrect_return[0].y = y2[0];
+ xrect_return[0].width = xrect2->width - x2[1] + x1[0];
+ xrect_return[0].height = xrect2->height;
//second
- xrect_return[1].x = x1[0];
- xrect_return[1].y = y2[0];
- xrect_return[1].width = x2[1] - x1[0];
- xrect_return[1].height = xrect2->height - y2[1] + y1[0];
- }
- return -2;
- }
- else{//polygons collide but no point of one is in the other
- //so we just keep the two parts of rect2 that are outside rect1
+ xrect_return[1].x = x1[0];
+ xrect_return[1].y = y2[0];
+ xrect_return[1].width = x2[1] - x1[0];
+ xrect_return[1].height = xrect2->height - y2[1] + y1[0];
+ }
+ return -2;
+ } else {//polygons collide but no point of one is in the other
+ //so we just keep the two parts of rect2 that are outside rect1
- //break rect2 in two
- //two cases:
- //rect2 crossing vertically rect1
- //and rect2 crossing horizontally rect1
- //The proper one can be found by simply checking x,y positions
- *nrects=2;
- if(xrect2->y<xrect1->y){
- //common
- xrect_return[0].x = xrect_return[1].x = x2[0];
- xrect_return[0].width = xrect_return[1].width = xrect2->width;
+ //break rect2 in two
+ //two cases:
+ //rect2 crossing vertically rect1
+ //and rect2 crossing horizontally rect1
+ //The proper one can be found by simply checking x,y positions
+ *nrects=2;
+ if (xrect2->y<xrect1->y) {
+ //common
+ xrect_return[0].x = xrect_return[1].x = x2[0];
+ xrect_return[0].width = xrect_return[1].width = xrect2->width;
- xrect_return[0].y = y2[0];
- xrect_return[0].height = xrect2->height - y2[1] + y1[0];
- xrect_return[1].y = y1[1];
- xrect_return[1].height = y2[1] - y1[1];
- }
- else{
- //common
- xrect_return[0].y = xrect_return[1].y = y2[0];
- xrect_return[0].height = xrect_return[1].height = xrect2->height;
+ xrect_return[0].y = y2[0];
+ xrect_return[0].height = xrect2->height - y2[1] + y1[0];
+ xrect_return[1].y = y1[1];
+ xrect_return[1].height = y2[1] - y1[1];
+ } else {
+ //common
+ xrect_return[0].y = xrect_return[1].y = y2[0];
+ xrect_return[0].height = xrect_return[1].height = xrect2->height;
- xrect_return[0].x = x2[0];
- xrect_return[0].width = xrect2->width - x2[1] + x1[0];
- xrect_return[1].x = x1[1];
- xrect_return[1].width = x2[1] - x1[1];
- }
- return -2;
- }
- }
+ xrect_return[0].x = x2[0];
+ xrect_return[0].width = xrect2->width - x2[1] + x1[0];
+ xrect_return[1].x = x1[1];
+ xrect_return[1].width = x2[1] - x1[1];
+ }
+ return -2;
+ }
+ }
}
-int rmdRectInsert(RectArea **root,XRectangle *xrect){
+int rmdRectInsert(RectArea **root,XRectangle *xrect) {
- int total_insertions=0;
- RectArea *temp=NULL,*newnode=(RectArea *)malloc(sizeof(RectArea));
- //align
- //we do need to know boundaries
- xrect->width+=(xrect->width%2)|(xrect->x%2);
- xrect->height+=(xrect->height%2)|(xrect->y%2);
- xrect->width+=(xrect->width%2);
- xrect->height+=(xrect->height%2);
- xrect->x-=xrect->x%2;
- xrect->y-=xrect->y%2;
-// fprintf(stderr," %d %d %d %d\n",xrect->x,
+ int total_insertions=0;
+ RectArea *temp=NULL,*newnode=(RectArea *)malloc(sizeof(RectArea));
+ //align
+ //we do need to know boundaries
+ xrect->width+=(xrect->width%2)|(xrect->x%2);
+ xrect->height+=(xrect->height%2)|(xrect->y%2);
+ xrect->width+=(xrect->width%2);
+ xrect->height+=(xrect->height%2);
+ xrect->x-=xrect->x%2;
+ xrect->y-=xrect->y%2;
+// fprintf(stderr," %d %d %d %d\n",xrect->x,
- newnode->rect.x=xrect->x;
- newnode->rect.y=xrect->y;
- newnode->rect.width=xrect->width;
- newnode->rect.height=xrect->height;
- newnode->prev=newnode->next=NULL;
- if(*root==NULL){
- *root=newnode;
- total_insertions=1;
- }
- else{
- XRectangle xrect_return[2];
+ newnode->rect.x=xrect->x;
+ newnode->rect.y=xrect->y;
+ newnode->rect.width=xrect->width;
+ newnode->rect.height=xrect->height;
+ newnode->prev=newnode->next=NULL;
+ if (*root==NULL) {
+ *root=newnode;
+ total_insertions=1;
+ } else {
+ XRectangle xrect_return[2];
- int nrects=0,insert_ok=1,i=0;
- temp=*root;
- while(insert_ok){ //if something is broken list does not procceed
- //(except on -1 collres case)
- int collres = rmdCollideRects(&temp->rect, xrect, &xrect_return[0], &nrects);
- if((!collres))
- insert_ok=1;
- else{
- for(i=0;i<nrects;i++){
- xrect_return[i].width += (xrect_return[i].width % 2) |
- (xrect_return[i].x % 2);
- xrect_return[i].height += (xrect_return[i].height % 2) |
- (xrect_return[i].y % 2);
- xrect_return[i].width += (xrect_return[i].width % 2);
- xrect_return[i].height += (xrect_return[i].height % 2);
- xrect_return[i].x -= xrect_return[i].x % 2;
- xrect_return[i].y -= xrect_return[i].y % 2;
- }
- insert_ok=0;
- switch(collres){
- case 1://remove current node,reinsert new one
- total_insertions--;
- if(temp->prev!=NULL){//no root
- if(temp->next!=NULL){//
- RectArea *temp1=temp->next;
- temp->prev->next=temp->next;
- temp->next->prev=temp->prev;
- free(temp);
- if((xrect->width>0)&&(xrect->height>0))
- total_insertions+=rmdRectInsert(&temp1,xrect);
- }
- else{
- temp->prev->next=newnode;
- newnode->prev=temp->prev;
- total_insertions++;
- free(temp);
- }
- }
- else{//root
- if((*root)->next!=NULL){
- (*root)=(*root)->next;
- (*root)->prev=NULL;
- if((xrect->width>0)&&(xrect->height>0))
- total_insertions+=rmdRectInsert(root,xrect);
- }
- else if((xrect->width>0)&&(xrect->height>0)){
- *root=newnode;
- total_insertions++;
- }
- else{
- *root=NULL;
- total_insertions++;
- }
- free(temp);
- }
- break;
- case 2://done,area is already covered
- free(newnode);
- break;
- case -1://current node is broken and reinserted
- //(in same pos)
- //newnode is also reinserted
- if (xrect_return[0].width > 0 &&
- xrect_return[0].height > 0) {
- temp->rect.x = xrect_return[0].x;
- temp->rect.y = xrect_return[0].y;
- temp->rect.width = xrect_return[0].width;
- temp->rect.height = xrect_return[0].height;
- if(temp->next==NULL){
- temp->next=newnode;
- newnode->prev=temp;
- total_insertions++;
- }
- else{
- insert_ok=1;
- }
- }
- else{//it might happen that the old and now broken node
- //is of zero width or height
- //(so it isn't reinserted)
- if((temp->prev==NULL)&&(temp->next!=NULL)){
- *root=(*root)->next;
- (*root)->prev=NULL;
- }
- else if((temp->next==NULL)&&(temp->prev!=NULL)){
- temp->prev->next=newnode;
- newnode->prev=temp->prev;
- }
- else if((temp->next==NULL)&&(temp->prev==NULL))
- (*root)=newnode;
- else{
- total_insertions--;
- temp->next->prev=temp->prev;
- temp->prev->next=temp->next;
- total_insertions+=rmdRectInsert(&temp->next,
- xrect);
- }
- free(temp);
- }
- break;
- case -2://new is broken and reinserted
- if(temp->next==NULL){
- total_insertions+=nrects;
- newnode->rect.x = xrect_return[0].x;
- newnode->rect.y = xrect_return[0].y;
- newnode->rect.width = xrect_return[0].width;
- newnode->rect.height = xrect_return[0].height;
- temp->next=newnode;
- newnode->prev=temp;
- if(nrects>1){
- RectArea *newnode1=
- (RectArea *)malloc(sizeof(RectArea));
+ int nrects=0,insert_ok=1,i=0;
+ temp=*root;
+ while (insert_ok) { //if something is broken list does not procceed
+ //(except on -1 collres case)
+ int collres = rmdCollideRects(&temp->rect, xrect, &xrect_return[0], &nrects);
+ if ((!collres))
+ insert_ok=1;
+ else {
+ for(i=0;i<nrects;i++) {
+ xrect_return[i].width += (xrect_return[i].width % 2) |
+ (xrect_return[i].x % 2);
+ xrect_return[i].height += (xrect_return[i].height % 2) |
+ (xrect_return[i].y % 2);
+ xrect_return[i].width += (xrect_return[i].width % 2);
+ xrect_return[i].height += (xrect_return[i].height % 2);
+ xrect_return[i].x -= xrect_return[i].x % 2;
+ xrect_return[i].y -= xrect_return[i].y % 2;
+ }
+ insert_ok=0;
+ switch (collres) {
+ case 1://remove current node,reinsert new one
+ total_insertions--;
+ if (temp->prev!=NULL) {//no root
+ if (temp->next!=NULL) {//
+ RectArea *temp1=temp->next;
+ temp->prev->next=temp->next;
+ temp->next->prev=temp->prev;
+ free(temp);
+ if ((xrect->width>0)&&(xrect->height>0))
+ total_insertions+=rmdRectInsert(&temp1,xrect);
+ } else {
+ temp->prev->next=newnode;
+ newnode->prev=temp->prev;
+ total_insertions++;
+ free(temp);
+ }
+ } else {//root
+ if ((*root)->next!=NULL) {
+ (*root)=(*root)->next;
+ (*root)->prev=NULL;
+ if ((xrect->width>0)&&(xrect->height>0))
+ total_insertions+=rmdRectInsert(root,xrect);
+ } else if ((xrect->width>0)&&(xrect->height>0)) {
+ *root=newnode;
+ total_insertions++;
+ } else {
+ *root=NULL;
+ total_insertions++;
+ }
+ free(temp);
+ }
+ break;
+ case 2://done,area is already covered
+ free(newnode);
+ break;
+ case -1://current node is broken and reinserted
+ //(in same pos)
+ //newnode is also reinserted
+ if (xrect_return[0].width > 0 &&
+ xrect_return[0].height > 0) {
+ temp->rect.x = xrect_return[0].x;
+ temp->rect.y = xrect_return[0].y;
+ temp->rect.width = xrect_return[0].width;
+ temp->rect.height = xrect_return[0].height;
+ if (temp->next==NULL) {
+ temp->next=newnode;
+ newnode->prev=temp;
+ total_insertions++;
+ } else {
+ insert_ok=1;
+ }
+ } else {//it might happen that the old and now broken node
+ //is of zero width or height
+ //(so it isn't reinserted)
+ if ((temp->prev==NULL)&&(temp->next!=NULL)) {
+ *root=(*root)->next;
+ (*root)->prev=NULL;
+ } else if ((temp->next==NULL)&&(temp->prev!=NULL)) {
+ temp->prev->next=newnode;
+ newnode->prev=temp->prev;
+ } else if ((temp->next==NULL)&&(temp->prev==NULL))
+ (*root)=newnode; else {
+ total_insertions--;
+ temp->next->prev=temp->prev;
+ temp->prev->next=temp->next;
+ total_insertions+=rmdRectInsert(&temp->next,
+ xrect);
+ }
+ free(temp);
+ }
+ break;
+ case -2://new is broken and reinserted
+ if (temp->next==NULL) {
+ total_insertions+=nrects;
+ newnode->rect.x = xrect_return[0].x;
+ newnode->rect.y = xrect_return[0].y;
+ newnode->rect.width = xrect_return[0].width;
+ newnode->rect.height = xrect_return[0].height;
+ temp->next=newnode;
+ newnode->prev=temp;
+ if (nrects>1) {
+ RectArea *newnode1=
+ (RectArea *)malloc(sizeof(RectArea));
- newnode1->rect.x = xrect_return[1].x;
- newnode1->rect.y = xrect_return[1].y;
- newnode1->rect.width = xrect_return[1].width;
- newnode1->rect.height = xrect_return[1].height;
- newnode->next=newnode1;
- newnode1->prev=newnode;
- newnode1->next=NULL;
- }
- }
- else{
- for(i=0;i<nrects;i++){
- if(xrect_return[i].width > 0 &&
- xrect_return[i].height > 0)
- total_insertions+=
- rmdRectInsert(&temp->next, &xrect_return[i]);
- }
- }
- break;
- case -10://grouped
- if(temp->prev==NULL){
- if(temp->next==NULL){//empty list
- newnode->rect.x = xrect_return[0].x;
- newnode->rect.y = xrect_return[0].y;
- newnode->rect.width = xrect_return[0].width;
- newnode->rect.height = xrect_return[0].height;
+ newnode1->rect.x = xrect_return[1].x;
+ newnode1->rect.y = xrect_return[1].y;
+ newnode1->rect.width = xrect_return[1].width;
+ newnode1->rect.height = xrect_return[1].height;
+ newnode->next=newnode1;
+ newnode1->prev=newnode;
+ newnode1->next=NULL;
+ }
+ } else {
+ for(i=0;i<nrects;i++) {
+ if (xrect_return[i].width > 0 &&
+ xrect_return[i].height > 0)
+ total_insertions+=
+ rmdRectInsert(&temp->next, &xrect_return[i]);
+ }
+ }
+ break;
+ case -10://grouped
+ if (temp->prev==NULL) {
+ if (temp->next==NULL) {//empty list
+ newnode->rect.x = xrect_return[0].x;
+ newnode->rect.y = xrect_return[0].y;
+ newnode->rect.width = xrect_return[0].width;
+ newnode->rect.height = xrect_return[0].height;
- *root=newnode;
- free(temp);
- }
- else{
- total_insertions--;
- *root=temp->next;
- (*root)->prev=NULL;
- free(temp);
- if(xrect_return[0].width > 0 &&
- xrect_return[0].height > 0)
- total_insertions+=
- rmdRectInsert(root, &xrect_return[0]);
- }
- }
- else if(temp->next==NULL){//last, enter anyway
- newnode->rect.x = xrect_return[0].x;
- newnode->rect.y = xrect_return[0].y;
- newnode->rect.width = xrect_return[0].width;
- newnode->rect.height = xrect_return[0].height;
- temp->prev->next=newnode;
- newnode->prev=temp->prev;
- free(temp);
- }
- else{//remove node and reinsert, starting where we were
- total_insertions--;
- RectArea *temp1=temp->next;
- temp->prev->next=temp->next;
- temp->next->prev=temp->prev;
- free(temp);
- if(xrect_return[0].width > 0 &&
- xrect_return[0].height > 0)
- total_insertions+=
- rmdRectInsert(&temp1, &xrect_return[0]);
- }
- break;
- }
- }
- if(insert_ok){
- if(temp->next==NULL){
- temp->next=newnode;
- newnode->prev=temp;
- total_insertions++;
- break;
- }
- else{
- temp=temp->next;
- }
- }
- else{
- break;
- }
- };
- }
- return total_insertions;
+ *root=newnode;
+ free(temp);
+ } else {
+ total_insertions--;
+ *root=temp->next;
+ (*root)->prev=NULL;
+ free(temp);
+ if (xrect_return[0].width > 0 &&
+ xrect_return[0].height > 0)
+ total_insertions+=
+ rmdRectInsert(root, &xrect_return[0]);
+ }
+ } else if (temp->next==NULL) {//last, enter anyway
+ newnode->rect.x = xrect_return[0].x;
+ newnode->rect.y = xrect_return[0].y;
+ newnode->rect.width = xrect_return[0].width;
+ newnode->rect.height = xrect_return[0].height;
+ temp->prev->next=newnode;
+ newnode->prev=temp->prev;
+ free(temp);
+ } else {//remove node and reinsert, starting where we were
+ total_insertions--;
+ RectArea *temp1=temp->next;
+ temp->prev->next=temp->next;
+ temp->next->prev=temp->prev;
+ free(temp);
+ if (xrect_return[0].width > 0 &&
+ xrect_return[0].height > 0)
+ total_insertions+=
+ rmdRectInsert(&temp1, &xrect_return[0]);
+ }
+ break;
+ }
+ }
+ if (insert_ok) {
+ if (temp->next==NULL) {
+ temp->next=newnode;
+ newnode->prev=temp;
+ total_insertions++;
+ break;
+ } else {
+ temp=temp->next;
+ }
+ } else {
+ break;
+ }
+ };
+ }
+ return total_insertions;
}
-void rmdClearList(RectArea **root){
+void rmdClearList(RectArea **root) {
- RectArea *temp;
- temp=*root;
- if(temp!=NULL){
- while(temp->next!=NULL){
- temp=temp->next;
- free(temp->prev);
+ RectArea *temp;
+ temp=*root;
+ if (temp!=NULL) {
+ while (temp->next!=NULL) {
+ temp=temp->next;
+ free(temp->prev);
- }
- free(temp);
- *root=NULL;
- }
+ }
+ free(temp);
+ *root=NULL;
+ }
}
diff --git a/recordmydesktop/src/rmd_register_callbacks.c b/recordmydesktop/src/rmd_register_callbacks.c
index 844fece..241f160 100644
--- a/recordmydesktop/src/rmd_register_callbacks.c
+++ b/recordmydesktop/src/rmd_register_callbacks.c
@@ -34,53 +34,53 @@
// There seem to be no way of passing user data to the signal handler,
// so hack around not being able to pass ProgData to them
-static int *pdata_running = NULL;
-static int *pdata_paused = NULL;
-static int *pdata_aborted = NULL;
+static int *pdata_running = NULL;
+static int *pdata_paused = NULL;
+static int *pdata_aborted = NULL;
static int *pdata_pause_state_changed = NULL;
static void rmdSetPaused(int signum) {
- *pdata_pause_state_changed = TRUE;
+ *pdata_pause_state_changed = TRUE;
}
static void rmdSetRunning(int signum) {
- if (!*pdata_paused) {
+ if (!*pdata_paused) {
- *pdata_running = FALSE;
+ *pdata_running = FALSE;
- if (signum == SIGABRT) {
- *pdata_aborted = TRUE;
- }
- }
+ if (signum == SIGABRT) {
+ *pdata_aborted = TRUE;
+ }
+ }
}
void rmdRegisterCallbacks(ProgData *pdata) {
- struct sigaction pause_act;
- struct sigaction end_act;
-
- // Is there some way to pass pdata to the signal handlers?
- pdata_running = &pdata->running;
- pdata_paused = &pdata->paused;
- pdata_aborted = &pdata->aborted;
- pdata_pause_state_changed = &pdata->pause_state_changed;
-
- // Setup pause_act
- sigfillset(&pause_act.sa_mask);
- pause_act.sa_flags = SA_RESTART;
- pause_act.sa_handler = rmdSetPaused;
-
- sigaction(SIGUSR1, &pause_act, NULL);
-
- // Setup end_act
- sigfillset(&end_act.sa_mask);
- end_act.sa_flags = SA_RESTART;
- end_act.sa_handler = rmdSetRunning;
-
- sigaction(SIGINT, &end_act, NULL);
- sigaction(SIGTERM, &end_act, NULL);
- sigaction(SIGABRT, &end_act, NULL);
+ struct sigaction pause_act;
+ struct sigaction end_act;
+
+ // Is there some way to pass pdata to the signal handlers?
+ pdata_running = &pdata->running;
+ pdata_paused = &pdata->paused;
+ pdata_aborted = &pdata->aborted;
+ pdata_pause_state_changed = &pdata->pause_state_changed;
+
+ // Setup pause_act
+ sigfillset(&pause_act.sa_mask);
+ pause_act.sa_flags = SA_RESTART;
+ pause_act.sa_handler = rmdSetPaused;
+
+ sigaction(SIGUSR1, &pause_act, NULL);
+
+ // Setup end_act
+ sigfillset(&end_act.sa_mask);
+ end_act.sa_flags = SA_RESTART;
+ end_act.sa_handler = rmdSetRunning;
+
+ sigaction(SIGINT, &end_act, NULL);
+ sigaction(SIGTERM, &end_act, NULL);
+ sigaction(SIGABRT, &end_act, NULL);
}
diff --git a/recordmydesktop/src/rmd_rescue.c b/recordmydesktop/src/rmd_rescue.c
index 8b823a7..ec3130e 100644
--- a/recordmydesktop/src/rmd_rescue.c
+++ b/recordmydesktop/src/rmd_rescue.c
@@ -40,114 +40,93 @@
#include <stdlib.h>
-int rmdRescue(const char *path){
-
- int i=0,
- offset_x,
- offset_y;
-
- unsigned short width,
- height;
-
- ProgData pdata;
- EncData enc_data;
- CacheData cache_data;
-
- rmdSetupDefaultArgs(&pdata.args);
-
- pdata.enc_data=&enc_data;
- pdata.cache_data=&cache_data;
-
- //projname
- cache_data.projname=malloc(strlen(path)+2);
- strcpy(cache_data.projname,path);
- strcat(cache_data.projname,"/");//having two of these doesn't hurt...
- //image data
- cache_data.imgdata=malloc(strlen(cache_data.projname)+11);
- strcpy(cache_data.imgdata,cache_data.projname);
- strcat(cache_data.imgdata,"img.out");
- //audio data
- cache_data.audiodata=malloc(strlen(cache_data.projname)+10);
- strcpy(cache_data.audiodata,cache_data.projname);
- strcat(cache_data.audiodata,"audio.pcm");
- //specsfile
- cache_data.specsfile=malloc(strlen(cache_data.projname)+10);
- strcpy(cache_data.specsfile,cache_data.projname);
- strcat(cache_data.specsfile,"specs.txt");
-
-
- if(rmdReadSpecsFile(&pdata))
- return 1;
-
-
- width=((pdata.brwin.rrect.width + 15) >>4)<<4;
- height=((pdata.brwin.rrect.height + 15) >>4)<<4;
- offset_x=((width-pdata.brwin.rrect.width)/2)&~1;
- offset_y=((height-pdata.brwin.rrect.height)/2)&~1;
-
-
- enc_data.yuv.y=(unsigned char *)malloc(height*width);
- enc_data.yuv.u=(unsigned char *)malloc(height*width/4);
- enc_data.yuv.v=(unsigned char *)malloc(height*width/4);
- enc_data.yuv.y_width=width;
- enc_data.yuv.y_height=height;
- enc_data.yuv.y_stride=width;
-
- enc_data.yuv.uv_width=width/2;
- enc_data.yuv.uv_height=height/2;
- enc_data.yuv.uv_stride=width/2;
- enc_data.x_offset=offset_x;
- enc_data.y_offset=offset_y;
-
- for(i=0;i<(enc_data.yuv.y_width*enc_data.yuv.y_height);i++)
- enc_data.yuv.y[i]=0;
- for(i=0;i<(enc_data.yuv.uv_width*enc_data.yuv.uv_height);i++){
- enc_data.yuv.v[i]=enc_data.yuv.u[i]=127;
- }
-
- yblocks=malloc(sizeof(u_int32_t)*(enc_data.yuv.y_width/Y_UNIT_WIDTH)*
- (enc_data.yuv.y_height/Y_UNIT_WIDTH));
- ublocks=malloc(sizeof(u_int32_t)*(enc_data.yuv.y_width/Y_UNIT_WIDTH)*
- (enc_data.yuv.y_height/Y_UNIT_WIDTH));
- vblocks=malloc(sizeof(u_int32_t)*(enc_data.yuv.y_width/Y_UNIT_WIDTH)*
- (enc_data.yuv.y_height/Y_UNIT_WIDTH));
-
- pdata.frametime=(1000000)/pdata.args.fps;
-
- pthread_mutex_init(&pdata.theora_lib_mutex,NULL);
- pthread_mutex_init(&pdata.vorbis_lib_mutex,NULL);
- pthread_mutex_init(&pdata.libogg_mutex,NULL);
- pthread_cond_init(&pdata.theora_lib_clean,NULL);
- pthread_cond_init(&pdata.vorbis_lib_clean,NULL);
- pdata.th_encoding_clean=pdata.v_encoding_clean=1;
- pdata.avd=0;
- pdata.sound_buffer=NULL;
- pdata.running = TRUE;
- pdata.aborted = FALSE;
-
- rmdRegisterCallbacks(&pdata);
- fprintf(stderr,"Restoring %s!!!\n",path);
-
- rmdEncodeCache(&pdata);
-
- fprintf(stderr,"Done!!!\n");
- fprintf(stderr,"Goodbye!\n");
- rmdCleanUp();
-
- return 0;
+int rmdRescue(const char *path) {
+
+ int i=0, offset_x, offset_y;
+ unsigned short width, height;
+
+ ProgData pdata;
+ EncData enc_data;
+ CacheData cache_data;
+
+ rmdSetupDefaultArgs(&pdata.args);
+
+ pdata.enc_data=&enc_data;
+ pdata.cache_data=&cache_data;
+
+ //projname
+ cache_data.projname=malloc(strlen(path)+2);
+ strcpy(cache_data.projname,path);
+ strcat(cache_data.projname,"/");//having two of these doesn't hurt...
+ //image data
+ cache_data.imgdata=malloc(strlen(cache_data.projname)+11);
+ strcpy(cache_data.imgdata,cache_data.projname);
+ strcat(cache_data.imgdata,"img.out");
+ //audio data
+ cache_data.audiodata=malloc(strlen(cache_data.projname)+10);
+ strcpy(cache_data.audiodata,cache_data.projname);
+ strcat(cache_data.audiodata,"audio.pcm");
+ //specsfile
+ cache_data.specsfile=malloc(strlen(cache_data.projname)+10);
+ strcpy(cache_data.specsfile,cache_data.projname);
+ strcat(cache_data.specsfile,"specs.txt");
+
+
+ if (rmdReadSpecsFile(&pdata))
+ return 1;
+
+ width=((pdata.brwin.rrect.width + 15) >>4)<<4;
+ height=((pdata.brwin.rrect.height + 15) >>4)<<4;
+ offset_x=((width-pdata.brwin.rrect.width)/2)&~1;
+ offset_y=((height-pdata.brwin.rrect.height)/2)&~1;
+
+ enc_data.yuv.y=(unsigned char *)malloc(height*width);
+ enc_data.yuv.u=(unsigned char *)malloc(height*width/4);
+ enc_data.yuv.v=(unsigned char *)malloc(height*width/4);
+ enc_data.yuv.y_width=width;
+ enc_data.yuv.y_height=height;
+ enc_data.yuv.y_stride=width;
+
+ enc_data.yuv.uv_width=width/2;
+ enc_data.yuv.uv_height=height/2;
+ enc_data.yuv.uv_stride=width/2;
+ enc_data.x_offset=offset_x;
+ enc_data.y_offset=offset_y;
+
+ for (i=0;i<(enc_data.yuv.y_width*enc_data.yuv.y_height);i++)
+ enc_data.yuv.y[i]=0;
+
+ for (i=0;i<(enc_data.yuv.uv_width*enc_data.yuv.uv_height);i++)
+ enc_data.yuv.v[i]=enc_data.yuv.u[i]=127;
+
+ yblocks=malloc(sizeof(u_int32_t)*(enc_data.yuv.y_width/Y_UNIT_WIDTH)*
+ (enc_data.yuv.y_height/Y_UNIT_WIDTH));
+ ublocks=malloc(sizeof(u_int32_t)*(enc_data.yuv.y_width/Y_UNIT_WIDTH)*
+ (enc_data.yuv.y_height/Y_UNIT_WIDTH));
+ vblocks=malloc(sizeof(u_int32_t)*(enc_data.yuv.y_width/Y_UNIT_WIDTH)*
+ (enc_data.yuv.y_height/Y_UNIT_WIDTH));
+
+ pdata.frametime=(1000000)/pdata.args.fps;
+
+ pthread_mutex_init(&pdata.theora_lib_mutex,NULL);
+ pthread_mutex_init(&pdata.vorbis_lib_mutex,NULL);
+ pthread_mutex_init(&pdata.libogg_mutex,NULL);
+ pthread_cond_init(&pdata.theora_lib_clean,NULL);
+ pthread_cond_init(&pdata.vorbis_lib_clean,NULL);
+ pdata.th_encoding_clean=pdata.v_encoding_clean=1;
+ pdata.avd=0;
+ pdata.sound_buffer=NULL;
+ pdata.running = TRUE;
+ pdata.aborted = FALSE;
+
+ rmdRegisterCallbacks(&pdata);
+ fprintf(stderr,"Restoring %s!!!\n",path);
+
+ rmdEncodeCache(&pdata);
+
+ fprintf(stderr,"Done!!!\n");
+ fprintf(stderr,"Goodbye!\n");
+ rmdCleanUp();
+
+ return 0;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/recordmydesktop/src/rmd_setbrwindow.c b/recordmydesktop/src/rmd_setbrwindow.c
index 8a29b1a..b92eb9b 100644
--- a/recordmydesktop/src/rmd_setbrwindow.c
+++ b/recordmydesktop/src/rmd_setbrwindow.c
@@ -43,170 +43,155 @@
* \note This is called separately for width and height.
*/
static void rmdSizePack2_8_16(short *start, unsigned short *size, unsigned short limit) {
- int octoffset,hexoffset;
-
- //align in two
- //an odd x can always go down and still be in recording area.
- //Resolutions come in even numbers
- //so if x is an odd numer, width max is an odd number, too
- //thus since x will go down one then width can go up one too and still
- //be inbounds
- (*size)+=((*size)%2)|((*start)%2);
- //but if x goes down 1 and width is already even,it becomes odd so:
- (*size)+=((*size)%2);
- (*start)-=(*start)%2;
-
-
- //32 bit pack align
- //we already have disible by two width,so
- //it's 2, 4 or 6
- octoffset=((*size)%8);
- if(octoffset==2){
- (*size)-=2;
-
- }
- else if(octoffset==6){
- if((*size)+(*start)+2<=limit)
- (*size)+=2;
- else if((*start)>=2){
- (*start)-=2;
- (*size)+=2;
- }
- else{
- (*start)+=2;
- (*size)-=4;
- }
- }
-
- else if(octoffset==4){
- if(((*size)+(*start)+2<=limit)&&((*start)>=2)){
- (*start)-=2;
- (*size)+=4;
- }
- else if((*size)+(*start)+4<=limit){
- (*size)+=4;
- }
- else if((*start)>=4){
- (*start)-=4;
- (*size)+=4;
- }
- else{
- (*start)+=2;
- (*size)-=4;
- }
- }
-
- //16 divisble width(needed for shared memory only,
- //but applied anyway since theora wants it, too)
- //we already have divisibility by 8 so module
- //by 16 is euther 8 or 0
- hexoffset=((*size)%16);
- if(hexoffset){
- if(((*size)+(*start)+4<=limit)&&((*start)>=4)){
- (*start)-=4;
- (*size)+=8;
- }
- else if((*size)+(*start)+8<=limit){
- (*size)+=8;
- }
- else if((*start)>=8){
- (*start)-=8;
- (*size)+=8;
- }
- else{
- (*start)+=4;
- (*size)-=8;
- }
- }
-
+ int octoffset,hexoffset;
+
+ //align in two
+ //an odd x can always go down and still be in recording area.
+ //Resolutions come in even numbers
+ //so if x is an odd numer, width max is an odd number, too
+ //thus since x will go down one then width can go up one too and still
+ //be inbounds
+ (*size)+=((*size)%2)|((*start)%2);
+ //but if x goes down 1 and width is already even,it becomes odd so:
+ (*size)+=((*size)%2);
+ (*start)-=(*start)%2;
+
+ //32 bit pack align
+ //we already have disible by two width,so
+ //it's 2, 4 or 6
+ octoffset=((*size)%8);
+ if (octoffset==2) {
+ (*size)-=2;
+ } else if (octoffset==6) {
+ if ((*size)+(*start)+2<=limit)
+ (*size)+=2;
+ else if ((*start)>=2) {
+ (*start)-=2;
+ (*size)+=2;
+ } else{
+ (*start)+=2;
+ (*size)-=4;
+ }
+ } else if (octoffset==4) {
+ if (((*size)+(*start)+2<=limit)&&((*start)>=2)) {
+ (*start)-=2;
+ (*size)+=4;
+ } else if ((*size)+(*start)+4<=limit) {
+ (*size)+=4;
+ } else if ((*start)>=4) {
+ (*start)-=4;
+ (*size)+=4;
+ } else {
+ (*start)+=2;
+ (*size)-=4;
+ }
+ }
+
+ //16 divisble width(needed for shared memory only,
+ //but applied anyway since theora wants it, too)
+ //we already have divisibility by 8 so module
+ //by 16 is euther 8 or 0
+ hexoffset=((*size)%16);
+ if (hexoffset) {
+ if (((*size)+(*start)+4<=limit)&&((*start)>=4)) {
+ (*start)-=4;
+ (*size)+=8;
+ } else if ((*size)+(*start)+8<=limit) {
+ (*size)+=8;
+ } else if ((*start)>=8) {
+ (*start)-=8;
+ (*size)+=8;
+ } else {
+ (*start)+=4;
+ (*size)-=8;
+ }
+ }
}
-
-
-boolean rmdSetBRWindow(Display *dpy,
- BRWindow *brwin,
- DisplaySpecs *specs,
- ProgArgs *args) {
- //before we start recording we have to make sure the ranges are valid
- if(args->windowid==0){//root window
- //first set it up
- brwin->windowid=specs->root;
- brwin->rect.x=brwin->rect.y=0;
- brwin->rect.width=specs->width;
- brwin->rect.height=specs->height;
- brwin->rrect.x=args->x;
- brwin->rrect.y=args->y;
- brwin->rrect.width=((args->width)?
- args->width:specs->width-brwin->rrect.x);
- brwin->rrect.height=((args->height)?
- args->height:specs->height-brwin->rrect.y);
- //and then check validity
- if((brwin->rrect.x+brwin->rrect.width>specs->width)||
- (brwin->rrect.y+brwin->rrect.height>specs->height)){
- fprintf(stderr,"Window size specification out of bounds!"
- "(current resolution:%dx%d)\n",
- specs->width,specs->height);
- return FALSE;
- }
- }
- else{
- Window wchid;
- int transl_x,transl_y;
-
- XWindowAttributes attribs;
- XGetWindowAttributes(dpy,args->windowid,&attribs);
- if((attribs.map_state==IsUnviewable)||(attribs.map_state==IsUnmapped)){
- fprintf(stderr,"Window must be mapped and visible!\n");
- return FALSE;
- }
- XTranslateCoordinates(dpy,
- specs->root,
- args->windowid,
- attribs.x,
- attribs.y,
- &transl_x,
- &transl_y,
- &wchid);
-
- brwin->rect.x=attribs.x-transl_x;
- brwin->rect.y=attribs.y-transl_y;
- brwin->rect.width=attribs.width;
- brwin->rect.height=attribs.height;
- if((brwin->rect.x+brwin->rect.width>specs->width)||
- (brwin->rect.y+brwin->rect.height>specs->height)){
- fprintf(stderr,"Window must be on visible screen area!\n");
- return FALSE;
- }
-
- brwin->rrect.x=brwin->rect.x+args->x;
- brwin->rrect.y=brwin->rect.y+args->y;
- brwin->rrect.width=((args->width)?
- args->width:brwin->rect.width-args->x);
- brwin->rrect.height=((args->height)?
- args->height:brwin->rect.height-args->y);
- if((args->x+brwin->rrect.width>brwin->rect.width)||
- (args->y+brwin->rrect.height>brwin->rect.height)){
- fprintf(stderr,"Specified Area is larger than window!\n");
- return FALSE;
- }
- }
- fprintf(stderr, "Initial recording window is set to:\n"
- "X:%d Y:%d Width:%d Height:%d\n",
- brwin->rrect.x,brwin->rrect.y,
- brwin->rrect.width,brwin->rrect.height);
- rmdSizePack2_8_16(&brwin->rrect.x,&brwin->rrect.width,specs->width);
- rmdSizePack2_8_16(&brwin->rrect.y,&brwin->rrect.height,specs->height);
-
- fprintf(stderr, "Adjusted recording window is set to:\n"
- "X:%d Y:%d Width:%d Height:%d\n",
- brwin->rrect.x,brwin->rrect.y,
- brwin->rrect.width,brwin->rrect.height);
-
-
-
- brwin->nbytes=(((brwin->rrect.width+15)>>4)<<4)*
- (((brwin->rrect.height+15)>>4)<<4)*
- ((specs->depth==16)?2:4);
-
- return TRUE;
+boolean rmdSetBRWindow( Display *dpy,
+ BRWindow *brwin,
+ DisplaySpecs *specs,
+ ProgArgs *args) {
+
+ //before we start recording we have to make sure the ranges are valid
+ if (args->windowid==0) {//root window
+ //first set it up
+ brwin->windowid=specs->root;
+ brwin->rect.x=brwin->rect.y=0;
+ brwin->rect.width=specs->width;
+ brwin->rect.height=specs->height;
+ brwin->rrect.x=args->x;
+ brwin->rrect.y=args->y;
+ brwin->rrect.width=((args->width)? args->width:specs->width-brwin->rrect.x);
+ brwin->rrect.height=((args->height)? args->height:specs->height-brwin->rrect.y);
+ //and then check validity
+ if ((brwin->rrect.x+brwin->rrect.width>specs->width)||
+ (brwin->rrect.y+brwin->rrect.height>specs->height)) {
+ fprintf(stderr, "Window size specification out of bounds!"
+ "(current resolution:%dx%d)\n",
+ specs->width,specs->height);
+ return FALSE;
+ }
+ } else {
+ Window wchid;
+ int transl_x,transl_y;
+
+ XWindowAttributes attribs;
+ XGetWindowAttributes(dpy,args->windowid,&attribs);
+
+ if ((attribs.map_state==IsUnviewable)||(attribs.map_state==IsUnmapped)) {
+ fprintf(stderr,"Window must be mapped and visible!\n");
+ return FALSE;
+ }
+
+ XTranslateCoordinates( dpy,
+ specs->root,
+ args->windowid,
+ attribs.x,
+ attribs.y,
+ &transl_x,
+ &transl_y,
+ &wchid);
+
+ brwin->rect.x=attribs.x-transl_x;
+ brwin->rect.y=attribs.y-transl_y;
+ brwin->rect.width=attribs.width;
+ brwin->rect.height=attribs.height;
+
+ if ((brwin->rect.x+brwin->rect.width>specs->width)||
+ (brwin->rect.y+brwin->rect.height>specs->height)) {
+ fprintf(stderr,"Window must be on visible screen area!\n");
+ return FALSE;
+ }
+
+ brwin->rrect.x=brwin->rect.x+args->x;
+ brwin->rrect.y=brwin->rect.y+args->y;
+ brwin->rrect.width=((args->width)? args->width:brwin->rect.width-args->x);
+ brwin->rrect.height=((args->height)? args->height:brwin->rect.height-args->y);
+
+ if ((args->x+brwin->rrect.width>brwin->rect.width)||
+ (args->y+brwin->rrect.height>brwin->rect.height)) {
+ fprintf(stderr,"Specified Area is larger than window!\n");
+ return FALSE;
+ }
+ }
+
+ fprintf(stderr, "Initial recording window is set to:\n"
+ "X:%d Y:%d Width:%d Height:%d\n",
+ brwin->rrect.x,brwin->rrect.y,
+ brwin->rrect.width,brwin->rrect.height);
+
+ rmdSizePack2_8_16(&brwin->rrect.x,&brwin->rrect.width,specs->width);
+ rmdSizePack2_8_16(&brwin->rrect.y,&brwin->rrect.height,specs->height);
+
+ fprintf(stderr, "Adjusted recording window is set to:\n"
+ "X:%d Y:%d Width:%d Height:%d\n",
+ brwin->rrect.x,brwin->rrect.y,
+ brwin->rrect.width,brwin->rrect.height);
+
+ brwin->nbytes= (((brwin->rrect.width+15)>>4)<<4)*
+ (((brwin->rrect.height+15)>>4)<<4)*
+ ((specs->depth==16)?2:4);
+
+ return TRUE;
}
diff --git a/recordmydesktop/src/rmd_shortcuts.c b/recordmydesktop/src/rmd_shortcuts.c
index 1712b93..bdc8daa 100644
--- a/recordmydesktop/src/rmd_shortcuts.c
+++ b/recordmydesktop/src/rmd_shortcuts.c
@@ -37,117 +37,107 @@
#include <stdlib.h>
#include <string.h>
-int rmdRegisterShortcut(Display *dpy,
- Window root,
- const char *shortcut,
- HotKey *hotkey){
-
- int keycode=0,
- i, j ;
- KeySym key=0;
- unsigned int modifier_mask=0,
- numlock_mask=0;
- char *keystr=NULL;
- XModifierKeymap *modmap;
-
- if(strstr(shortcut,"Shift"))
- modifier_mask = modifier_mask|ShiftMask;
- if(strstr(shortcut,"Control"))
- modifier_mask = modifier_mask|ControlMask;
- if(strstr(shortcut,"Mod1"))
- modifier_mask = modifier_mask|Mod1Mask;
- if(strstr(shortcut,"Mod2"))
- modifier_mask = modifier_mask|Mod2Mask;
- if(strstr(shortcut,"Mod3"))
- modifier_mask = modifier_mask|Mod3Mask;
- if(strstr(shortcut,"Mod4"))
- modifier_mask = modifier_mask|Mod4Mask;
- if(strstr(shortcut,"Mod5"))
- modifier_mask = modifier_mask|Mod5Mask;
-
- //we register the shortcut on the root
- //window, which means on every keypress event,
- //so I think it's neccessary to have at least one
- //modifier.
- if(modifier_mask == 0)
- return 1;
- if((keystr=rindex(shortcut,'+'))!=NULL){
- keystr++;
- if((key=XStringToKeysym(keystr))==NoSymbol)
- return 1;
- else
- keycode=XKeysymToKeycode(dpy,key);
- }
- else
- return 1;
-
-
- /* Key grabbing stuff taken from tilda who took it from yeahconsole
- * who took it from evilwm */
-
- modmap = XGetModifierMapping(dpy);
- for(i=0;i<8;i++){
- for(j=0;j<modmap->max_keypermod;j++){
- if(modmap->modifiermap[i*modmap->max_keypermod+j]==
- XKeysymToKeycode(dpy,XK_Num_Lock))
- numlock_mask=(1<<i);
- }
- }
- XFreeModifiermap(modmap);
-
- hotkey->modnum=0;
- hotkey->key=keycode;
-
- XGrabKey(dpy,
- keycode,
- modifier_mask,
- root,
- True,
- GrabModeAsync,
- GrabModeAsync);
- hotkey->mask[0]=modifier_mask;
- hotkey->modnum++;
-
- XGrabKey(dpy,
- keycode,
- LockMask | modifier_mask,
- root,
- True,
- GrabModeAsync,
- GrabModeAsync);
- hotkey->mask[1]=LockMask | modifier_mask;
- hotkey->modnum++;
-
- if(numlock_mask){
-
- XGrabKey(dpy,
- keycode,
- numlock_mask | modifier_mask,
- root,
- True,
- GrabModeAsync,
- GrabModeAsync);
- hotkey->mask[2]=numlock_mask | modifier_mask;
- hotkey->modnum++;
-
- XGrabKey(dpy,
- keycode,
- numlock_mask | LockMask | modifier_mask,
- root,
- True,
- GrabModeAsync,
- GrabModeAsync);
- hotkey->mask[3]=numlock_mask | LockMask | modifier_mask;
- hotkey->modnum++;
-
- }
-
- return 0;
-
+int rmdRegisterShortcut( Display *dpy,
+ Window root,
+ const char *shortcut,
+ HotKey *hotkey) {
+
+ int keycode=0, i, j ;
+ KeySym key=0;
+ unsigned int modifier_mask=0, numlock_mask=0;
+ char *keystr=NULL;
+ XModifierKeymap *modmap;
+
+ if (strstr(shortcut,"Shift"))
+ modifier_mask = modifier_mask|ShiftMask;
+ if (strstr(shortcut,"Control"))
+ modifier_mask = modifier_mask|ControlMask;
+ if (strstr(shortcut,"Mod1"))
+ modifier_mask = modifier_mask|Mod1Mask;
+ if (strstr(shortcut,"Mod2"))
+ modifier_mask = modifier_mask|Mod2Mask;
+ if (strstr(shortcut,"Mod3"))
+ modifier_mask = modifier_mask|Mod3Mask;
+ if (strstr(shortcut,"Mod4"))
+ modifier_mask = modifier_mask|Mod4Mask;
+ if (strstr(shortcut,"Mod5"))
+ modifier_mask = modifier_mask|Mod5Mask;
+
+ //we register the shortcut on the root
+ //window, which means on every keypress event,
+ //so I think it's neccessary to have at least one
+ //modifier.
+ if (modifier_mask == 0)
+ return 1;
+ if ((keystr=rindex(shortcut,'+'))!=NULL) {
+ keystr++;
+ if ((key=XStringToKeysym(keystr))==NoSymbol)
+ return 1;
+ else
+ keycode=XKeysymToKeycode(dpy,key);
+ } else
+ return 1;
+
+
+ /* Key grabbing stuff taken from tilda who took it from yeahconsole
+ * who took it from evilwm */
+
+ modmap = XGetModifierMapping(dpy);
+ for (i=0;i<8;i++) {
+ for (j=0;j<modmap->max_keypermod;j++) {
+ if (modmap->modifiermap[i*modmap->max_keypermod+j]==
+ XKeysymToKeycode(dpy,XK_Num_Lock))
+ numlock_mask=(1<<i);
+ }
+ }
+ XFreeModifiermap(modmap);
+
+ hotkey->modnum=0;
+ hotkey->key=keycode;
+
+ XGrabKey( dpy,
+ keycode,
+ modifier_mask,
+ root,
+ True,
+ GrabModeAsync,
+ GrabModeAsync);
+ hotkey->mask[0]=modifier_mask;
+ hotkey->modnum++;
+
+ XGrabKey( dpy,
+ keycode,
+ LockMask | modifier_mask,
+ root,
+ True,
+ GrabModeAsync,
+ GrabModeAsync);
+ hotkey->mask[1]=LockMask | modifier_mask;
+ hotkey->modnum++;
+
+ if (numlock_mask) {
+
+ XGrabKey( dpy,
+ keycode,
+ numlock_mask | modifier_mask,
+ root,
+ True,
+ GrabModeAsync,
+ GrabModeAsync);
+ hotkey->mask[2]=numlock_mask | modifier_mask;
+ hotkey->modnum++;
+
+ XGrabKey( dpy,
+ keycode,
+ numlock_mask | LockMask | modifier_mask,
+ root,
+ True,
+ GrabModeAsync,
+ GrabModeAsync);
+ hotkey->mask[3]=numlock_mask | LockMask | modifier_mask;
+ hotkey->modnum++;
+
+ }
+
+ return 0;
}
-
-
-
-
-
-
diff --git a/recordmydesktop/src/rmd_specsfile.c b/recordmydesktop/src/rmd_specsfile.c
index 11b55dc..50542a8 100644
--- a/recordmydesktop/src/rmd_specsfile.c
+++ b/recordmydesktop/src/rmd_specsfile.c
@@ -33,137 +33,119 @@
#include <stdio.h>
-int rmdWriteSpecsFile(ProgData *pdata){
-
- FILE *fp;
-
-
- fp=fopen(pdata->cache_data->specsfile,"wb");
- if(fp==NULL)
- return 1;
- else{
-
- fprintf(fp,"recordMyDesktop = %s\n",VERSION);
- fprintf(fp,"Width = %hu\n",pdata->brwin.rrect.width);
- fprintf(fp,"Height = %hu\n",pdata->brwin.rrect.height);
- fprintf(fp,"Filename = %s\n",pdata->args.filename);
- fprintf(fp,"FPS = %f\n",pdata->args.fps);
- fprintf(fp,"NoSound = %d\n",pdata->args.nosound);
- fprintf(fp,"Frequency = %d\n",pdata->args.frequency);
- fprintf(fp,"Channels = %d\n",pdata->args.channels);
- fprintf(fp,"BufferSize = %lu\n",(unsigned long)pdata->args.buffsize);
- fprintf(fp,"SoundFrameSize = %d\n",pdata->sound_framesize);
- fprintf(fp,"PeriodSize = %lu\n",(unsigned long)pdata->periodsize);
- fprintf(fp,"UsedJack = %d\n",pdata->args.use_jack);
- fprintf(fp,"v_bitrate = %d\n",pdata->args.v_bitrate);
- fprintf(fp,"v_quality = %d\n",pdata->args.v_quality);
- fprintf(fp,"s_quality = %d\n",pdata->args.s_quality);
- fprintf(fp,"ZeroCompression = %d\n",pdata->args.zerocompression);
-
-
- }
-
- fclose(fp);
- return 0;
-
+int rmdWriteSpecsFile(ProgData *pdata) {
+
+ FILE *fp;
+
+ fp=fopen(pdata->cache_data->specsfile,"wb");
+ if (!fp)
+ return 1;
+
+ fprintf(fp,"recordMyDesktop = %s\n",VERSION);
+ fprintf(fp,"Width = %hu\n",pdata->brwin.rrect.width);
+ fprintf(fp,"Height = %hu\n",pdata->brwin.rrect.height);
+ fprintf(fp,"Filename = %s\n",pdata->args.filename);
+ fprintf(fp,"FPS = %f\n",pdata->args.fps);
+ fprintf(fp,"NoSound = %d\n",pdata->args.nosound);
+ fprintf(fp,"Frequency = %d\n",pdata->args.frequency);
+ fprintf(fp,"Channels = %d\n",pdata->args.channels);
+ fprintf(fp,"BufferSize = %lu\n",(unsigned long)pdata->args.buffsize);
+ fprintf(fp,"SoundFrameSize = %d\n",pdata->sound_framesize);
+ fprintf(fp,"PeriodSize = %lu\n",(unsigned long)pdata->periodsize);
+ fprintf(fp,"UsedJack = %d\n",pdata->args.use_jack);
+ fprintf(fp,"v_bitrate = %d\n",pdata->args.v_bitrate);
+ fprintf(fp,"v_quality = %d\n",pdata->args.v_quality);
+ fprintf(fp,"s_quality = %d\n",pdata->args.s_quality);
+ fprintf(fp,"ZeroCompression = %d\n",pdata->args.zerocompression);
+
+ fclose(fp);
+
+ return 0;
}
-int rmdReadSpecsFile(ProgData *pdata){
-
-
- FILE *fp;
-
-
- fp=fopen(pdata->cache_data->specsfile,"rb");
- if(fp==NULL)
- return 1;
- else{
-
- char Cached_Version[256];
- free(pdata->args.filename);
- pdata->args.filename=malloc(512);
-
- //Take that single-point-of-exit advocates !!!
- //15 points of exit, just for your pleasure.
- //Also, Vi(m) rules, emacs sucks.
-
- if(fscanf(fp,"recordMyDesktop = %s\n",Cached_Version)!=1){
- fprintf(stderr,"Error reading VERSION attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"Width = %hu\n",&pdata->brwin.rrect.width)!=1){
- fprintf(stderr,"Error reading Width attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"Height = %hu\n",&pdata->brwin.rrect.height)!=1){
- fprintf(stderr,"Error reading Height attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"Filename = %s\n",pdata->args.filename)!=1){
- fprintf(stderr,"Error reading Filename attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"FPS = %f\n",&pdata->args.fps)!=1){
- fprintf(stderr,"Error reading FPS attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"NoSound = %d\n",&pdata->args.nosound)!=1){
- fprintf(stderr,"Error reading NoSound attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"Frequency = %d\n",&pdata->args.frequency)!=1){
- fprintf(stderr,"Error reading Frequency attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"Channels = %d\n",&pdata->args.channels)!=1){
- fprintf(stderr,"Error reading Channels attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"BufferSize = %lu\n",
- (unsigned long *)&pdata->args.buffsize)!=1){
- fprintf(stderr,"Error reading BufferSize attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"SoundFrameSize = %d\n",&pdata->sound_framesize)!=1){
- fprintf(stderr,"Error reading SoundFrameSize attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"PeriodSize = %lu\n",
- (unsigned long *)&pdata->periodsize)!=1){
- fprintf(stderr,"Error reading PeriodSize attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"UsedJack = %u\n",&pdata->args.use_jack)!=1){
- fprintf(stderr,"Error reading UsedJack attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"v_bitrate = %d\n",&pdata->args.v_bitrate)!=1){
- fprintf(stderr,"Error reading v_bitrate attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"v_quality = %d\n",&pdata->args.v_quality)!=1){
- fprintf(stderr,"Error reading v_quality attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"s_quality = %d\n",&pdata->args.s_quality)!=1){
- fprintf(stderr,"Error reading s_quality attribute!!!\n");
- return 1;
- }
- if(fscanf(fp,"ZeroCompression = %d\n",&pdata->args.zerocompression)!=1){
- fprintf(stderr,"Error reading ZeroCompression attribute!!!\n");
- return 1;
- }
-
-
- }
-
- fclose(fp);
- return 0;
-
+int rmdReadSpecsFile(ProgData *pdata) {
+ char Cached_Version[256];
+ FILE *fp;
+
+ fp=fopen(pdata->cache_data->specsfile,"rb");
+ if (!fp)
+ return 1;
+
+ free(pdata->args.filename);
+ pdata->args.filename=malloc(512);
+
+ //Take that single-point-of-exit advocates !!!
+ //15 points of exit, just for your pleasure.
+ //Also, Vi(m) rules, emacs sucks.
+
+ if (fscanf(fp,"recordMyDesktop = %s\n",Cached_Version)!=1) {
+ fprintf(stderr,"Error reading VERSION attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"Width = %hu\n",&pdata->brwin.rrect.width)!=1) {
+ fprintf(stderr,"Error reading Width attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"Height = %hu\n",&pdata->brwin.rrect.height)!=1) {
+ fprintf(stderr,"Error reading Height attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"Filename = %s\n",pdata->args.filename)!=1) {
+ fprintf(stderr,"Error reading Filename attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"FPS = %f\n",&pdata->args.fps)!=1) {
+ fprintf(stderr,"Error reading FPS attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"NoSound = %d\n",&pdata->args.nosound)!=1) {
+ fprintf(stderr,"Error reading NoSound attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"Frequency = %d\n",&pdata->args.frequency)!=1) {
+ fprintf(stderr,"Error reading Frequency attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"Channels = %d\n",&pdata->args.channels)!=1) {
+ fprintf(stderr,"Error reading Channels attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"BufferSize = %lu\n",
+ (unsigned long *)&pdata->args.buffsize)!=1) {
+ fprintf(stderr,"Error reading BufferSize attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"SoundFrameSize = %d\n",&pdata->sound_framesize)!=1) {
+ fprintf(stderr,"Error reading SoundFrameSize attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"PeriodSize = %lu\n",
+ (unsigned long *)&pdata->periodsize)!=1) {
+ fprintf(stderr,"Error reading PeriodSize attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"UsedJack = %u\n",&pdata->args.use_jack)!=1) {
+ fprintf(stderr,"Error reading UsedJack attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"v_bitrate = %d\n",&pdata->args.v_bitrate)!=1) {
+ fprintf(stderr,"Error reading v_bitrate attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"v_quality = %d\n",&pdata->args.v_quality)!=1) {
+ fprintf(stderr,"Error reading v_quality attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"s_quality = %d\n",&pdata->args.s_quality)!=1) {
+ fprintf(stderr,"Error reading s_quality attribute!!!\n");
+ return 1;
+ }
+ if (fscanf(fp,"ZeroCompression = %d\n",&pdata->args.zerocompression)!=1) {
+ fprintf(stderr,"Error reading ZeroCompression attribute!!!\n");
+ return 1;
+ }
+
+ fclose(fp);
+
+ return 0;
}
-
-
-
-
-
-
diff --git a/recordmydesktop/src/rmd_threads.c b/recordmydesktop/src/rmd_threads.c
index 320e8f4..7afe792 100644
--- a/recordmydesktop/src/rmd_threads.c
+++ b/recordmydesktop/src/rmd_threads.c
@@ -45,122 +45,119 @@
#include <stdlib.h>
#include <unistd.h>
-void rmdThreads(ProgData *pdata){
- pthread_t image_capture_t,
- image_encode_t,
- image_cache_t,
- sound_capture_t,
- sound_encode_t,
- sound_cache_t,
- flush_to_ogg_t,
- timer_t;
-
- if(pdata->args.delay>0){
- fprintf(stderr,"Will sleep for %d seconds now.\n",pdata->args.delay);
- sleep(pdata->args.delay);
- }
-
- /*start threads*/
- pthread_create(&image_capture_t,
- NULL,
- (void *)rmdGetFrame,
- (void *)pdata);
- if(pdata->args.encOnTheFly)
- pthread_create(&image_encode_t,
- NULL,
- (void *)rmdEncodeImageBuffer,
- (void *)pdata);
- else
- pthread_create(&image_cache_t,
- NULL,
- (void *)rmdCacheImageBuffer,
- (void *)pdata);
-
- if(!pdata->args.nosound){
- if(!pdata->args.use_jack)
- pthread_create(&sound_capture_t,
- NULL,
- (void *)rmdCaptureSound,
- (void *)pdata);
- if(pdata->args.encOnTheFly)
- pthread_create(&sound_encode_t,
- NULL,
- (void *)rmdEncodeSoundBuffer,
- (void *)pdata);
- else
- pthread_create(&sound_cache_t,
- NULL,
- (void *)rmdCacheSoundBuffer,
- (void *)pdata);
- }
- if(pdata->args.encOnTheFly)
- pthread_create(&flush_to_ogg_t,
- NULL,
- (void *)rmdFlushToOgg,
- (void *)pdata);
-
- rmdRegisterCallbacks(pdata);
- pdata->timer_alive=1;
- pthread_create(&timer_t,
- NULL,
- (void *)rmdTimer,
- (void *)pdata);
- fprintf(stderr,"Capturing!\n");
+void rmdThreads(ProgData *pdata) {
+ pthread_t image_capture_t,
+ image_encode_t,
+ image_cache_t,
+ sound_capture_t,
+ sound_encode_t,
+ sound_cache_t,
+ flush_to_ogg_t,
+ timer_t;
+
+ if (pdata->args.delay>0) {
+ fprintf(stderr, "Will sleep for %d seconds now.\n", pdata->args.delay);
+ sleep(pdata->args.delay);
+ }
+
+ /*start threads*/
+ pthread_create( &image_capture_t,
+ NULL,
+ (void *)rmdGetFrame,
+ (void *)pdata);
+
+ if (pdata->args.encOnTheFly)
+ pthread_create( &image_encode_t,
+ NULL,
+ (void *)rmdEncodeImageBuffer,
+ (void *)pdata);
+ else
+ pthread_create( &image_cache_t,
+ NULL,
+ (void *)rmdCacheImageBuffer,
+ (void *)pdata);
+
+ if (!pdata->args.nosound) {
+ if (!pdata->args.use_jack)
+ pthread_create( &sound_capture_t,
+ NULL,
+ (void *)rmdCaptureSound,
+ (void *)pdata);
+
+ if (pdata->args.encOnTheFly)
+ pthread_create( &sound_encode_t,
+ NULL,
+ (void *)rmdEncodeSoundBuffer,
+ (void *)pdata);
+ else
+ pthread_create( &sound_cache_t,
+ NULL,
+ (void *)rmdCacheSoundBuffer,
+ (void *)pdata);
+ }
+
+ if(pdata->args.encOnTheFly)
+ pthread_create( &flush_to_ogg_t,
+ NULL,
+ (void *)rmdFlushToOgg,
+ (void *)pdata);
+
+ rmdRegisterCallbacks(pdata);
+ pdata->timer_alive=1;
+ pthread_create( &timer_t,
+ NULL,
+ (void *)rmdTimer,
+ (void *)pdata);
+ fprintf(stderr,"Capturing!\n");
+
#ifdef HAVE_LIBJACK
- if(pdata->args.use_jack){
- pdata->jdata->capture_started=1;
- }
+ if (pdata->args.use_jack)
+ pdata->jdata->capture_started=1;
#endif
- //wait all threads to finish
-
- pthread_join(image_capture_t,NULL);
- fprintf(stderr,"Shutting down.");
- //if no damage events have been received the thread will get stuck
- while(!pdata->th_enc_thread_waiting && !pdata->th_encoding_clean){
- usleep(10000);
- pthread_mutex_lock(&pdata->img_buff_ready_mutex);
- pthread_cond_signal(&pdata->image_buffer_ready);
- pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
- }
-
- if(pdata->args.encOnTheFly){
- pthread_join(image_encode_t,NULL);
- }
- else
- pthread_join(image_cache_t,NULL);
- fprintf(stderr,".");
-
- if(!pdata->args.nosound){
+ //wait all threads to finish
+
+ pthread_join(image_capture_t,NULL);
+ fprintf(stderr,"Shutting down.");
+ //if no damage events have been received the thread will get stuck
+ while (!pdata->th_enc_thread_waiting && !pdata->th_encoding_clean) {
+ usleep(10000);
+ pthread_mutex_lock(&pdata->img_buff_ready_mutex);
+ pthread_cond_signal(&pdata->image_buffer_ready);
+ pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
+ }
+
+ if (pdata->args.encOnTheFly)
+ pthread_join(image_encode_t,NULL);
+ else
+ pthread_join(image_cache_t,NULL);
+ fprintf(stderr,".");
+
+ if (!pdata->args.nosound) {
#ifdef HAVE_LIBJACK
- if(pdata->args.use_jack)
- rmdStopJackClient(pdata->jdata);
+ if (pdata->args.use_jack)
+ rmdStopJackClient(pdata->jdata);
#endif
- if(!pdata->args.use_jack)
- pthread_join(sound_capture_t,NULL);
- fprintf(stderr,".");
- while(pdata->v_enc_thread_waiting || !pdata->v_encoding_clean){
- usleep(10000);
- pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
- pthread_cond_signal(&pdata->sound_data_read);
- pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
- }
- if(pdata->args.encOnTheFly){
- pthread_join(sound_encode_t,NULL);
- }
- else{
- pthread_join(sound_cache_t,NULL);
- }
- }
- else
- fprintf(stderr,"..");
-
- if(pdata->args.encOnTheFly)
- pthread_join(flush_to_ogg_t,NULL);
- fprintf(stderr,".");
-
- //Now that we are done with recording we cancel the timer
- pdata->timer_alive=0;
- pthread_join(timer_t,NULL);
-
-
+ if (!pdata->args.use_jack)
+ pthread_join(sound_capture_t,NULL);
+
+ fprintf(stderr,".");
+ while (pdata->v_enc_thread_waiting || !pdata->v_encoding_clean) {
+ usleep(10000);
+ pthread_mutex_lock(&pdata->snd_buff_ready_mutex);
+ pthread_cond_signal(&pdata->sound_data_read);
+ pthread_mutex_unlock(&pdata->snd_buff_ready_mutex);
+ }
+
+ if (pdata->args.encOnTheFly)
+ pthread_join(sound_encode_t, NULL);
+ else
+ pthread_join(sound_cache_t, NULL);
+ } else
+ fprintf(stderr,"..");
+
+ fprintf(stderr,".");
+
+ //Now that we are done with recording we cancel the timer
+ pdata->timer_alive=0;
+ pthread_join(timer_t,NULL);
}
diff --git a/recordmydesktop/src/rmd_timer.c b/recordmydesktop/src/rmd_timer.c
index af6fa75..2548fbe 100644
--- a/recordmydesktop/src/rmd_timer.c
+++ b/recordmydesktop/src/rmd_timer.c
@@ -38,51 +38,40 @@
void *rmdTimer(ProgData *pdata){
-
- long unsigned int secs_tw=1/pdata->args.fps;
- long unsigned int usecs_tw=(1000000)/pdata->args.fps-
- secs_tw*1000000;
-
- while(pdata->timer_alive){
-
- if (pdata->pause_state_changed) {
- pdata->pause_state_changed = FALSE;
-
- if (!pdata->paused) {
- pdata->paused = TRUE;
- fprintf(stderr,"STATE:PAUSED\n");fflush(stderr);
- }
- else{
- pdata->paused = FALSE;
- fprintf(stderr,"STATE:RECORDING\n");fflush(stderr);
- pthread_mutex_lock(&pdata->pause_mutex);
- pthread_cond_broadcast(&pdata->pause_cond);
- pthread_mutex_unlock(&pdata->pause_mutex);
- }
-
- }
-
- if (!pdata->paused) {
- pdata->frames_total++;
- if (pdata->capture_busy) {
- pdata->frames_lost++;
- }
- }
-
- pthread_mutex_lock(&pdata->time_mutex);
- pthread_cond_broadcast(&pdata->time_cond);
- pthread_mutex_unlock(&pdata->time_mutex);
-
-
- if(secs_tw)
- sleep(secs_tw);
- usleep(usecs_tw);
-
- }
-
-
- pthread_exit(&errno);
+ long unsigned int secs_tw=1/pdata->args.fps;
+ long unsigned int usecs_tw=(1000000)/pdata->args.fps- secs_tw*1000000;
+
+ while (pdata->timer_alive){
+ if (pdata->pause_state_changed) {
+ pdata->pause_state_changed = FALSE;
+
+ if (!pdata->paused) {
+ pdata->paused = TRUE;
+ fprintf(stderr,"STATE:PAUSED\n");fflush(stderr);
+ } else{
+ pdata->paused = FALSE;
+ fprintf(stderr,"STATE:RECORDING\n");fflush(stderr);
+ pthread_mutex_lock(&pdata->pause_mutex);
+ pthread_cond_broadcast(&pdata->pause_cond);
+ pthread_mutex_unlock(&pdata->pause_mutex);
+ }
+ }
+
+ if (!pdata->paused) {
+ pdata->frames_total++;
+ if (pdata->capture_busy)
+ pdata->frames_lost++;
+ }
+
+ pthread_mutex_lock(&pdata->time_mutex);
+ pthread_cond_broadcast(&pdata->time_cond);
+ pthread_mutex_unlock(&pdata->time_mutex);
+
+ if (secs_tw)
+ sleep(secs_tw);
+
+ usleep(usecs_tw);
+ }
+
+ pthread_exit(&errno);
}
-
-
-
diff --git a/recordmydesktop/src/rmd_types.h b/recordmydesktop/src/rmd_types.h
index e0fe1a1..9e5aa93 100644
--- a/recordmydesktop/src/rmd_types.h
+++ b/recordmydesktop/src/rmd_types.h
@@ -70,8 +70,8 @@ typedef u_int32_t cmp_int_t;
//type of pixel proccessing for the Cb,Cr planes
//when converting from full rgb to 4:2:2 Ycbcr
enum{
- __PXL_DISCARD, //only select 1 pixel in every block of four
- __PXL_AVERAGE //calculate the average of all four pixels
+ __PXL_DISCARD, //only select 1 pixel in every block of four
+ __PXL_AVERAGE //calculate the average of all four pixels
};
// Boolean type
@@ -89,123 +89,123 @@ typedef int boolean;
typedef struct _ProgData ProgData;
typedef struct _DisplaySpecs{ //this struct holds some basic information
- int screen; //about the display,needed mostly for
- unsigned int width, height; //validity checks at startup
- Window root;
- Visual *visual;
- GC gc;
- int depth;
+ int screen; //about the display,needed mostly for
+ unsigned int width, height; //validity checks at startup
+ Window root;
+ Visual *visual;
+ GC gc;
+ int depth;
}DisplaySpecs;
typedef struct _RectArea{ //an area that has been damaged gets stored
- XRectangle rect; //in a list comprised of structs of this type
- struct _RectArea *prev,*next;
+ XRectangle rect; //in a list comprised of structs of this type
+ struct _RectArea *prev,*next;
}RectArea;
typedef struct _BRWindow{ //'basic recorded window' specs
- XRectangle rect; //window attributes
- XRectangle rrect; //part of window that is recorded
- int nbytes; //size of zpixmap when screenshoting
- Window windowid; //id
+ XRectangle rect; //window attributes
+ XRectangle rrect; //part of window that is recorded (rounded to alignment)
+ int nbytes; //size of zpixmap when screenshoting
+ Window windowid; //id
}BRWindow;
//defaults in the following comment lines may be out of sync with reality
//check the SetupDefaultArgs() function further bellow
typedef struct _ProgArgs{
- int delay; //start up delay
- Window windowid; //window to record(default root)
- char *display; //display to connect(default :0)
- int x,y; //x,y offset(default 0,0)
- int width,height; //defaults to window width and height
- char *filename; //output file(default out.[ogg|*])
- 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
- //through the xfixes extension
- float fps; //desired framerate(default 15)
- unsigned int frequency; //desired frequency (default 22050)
- unsigned int channels; //no of channels(default 2)
- char *device; //default sound device
+ int delay; //start up delay
+ Window windowid; //window to record(default root)
+ char *display; //display to connect(default :0)
+ int x,y; //x,y offset(default 0,0)
+ int width,height; //defaults to window width and height
+ char *filename; //output file(default out.[ogg|*])
+ 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
+ //through the xfixes extension
+ float fps; //desired framerate(default 15)
+ unsigned int frequency; //desired frequency (default 22050)
+ unsigned int channels; //no of channels(default 2)
+ char *device; //default sound device
#ifdef HAVE_LIBASOUND
- snd_pcm_uframes_t buffsize; //buffer size(in frames) for sound capturing
+ snd_pcm_uframes_t buffsize; //buffer size(in frames) for sound capturing
#else
- u_int32_t buffsize;
+ u_int32_t buffsize;
#endif
- const char* rescue_path;
- int nosound; //do not record sound(default 0)
- int noshared; //do not use shared memory extension(default 0)
- int nowmcheck; //do not check if there's a 3d comp window manager
- //(which changes full-shots and with-shared to 1)
- int full_shots; //do not poll damage, take full screenshots
- int follow_mouse; //capture area follows the mouse(fullshots auto enabled)
- int no_encode; //do not encode or delete the temporary files(debug opt)
- int no_quick_subsample; //average pixels in chroma planes
- int v_bitrate,v_quality,s_quality; //video bitrate,video-sound quality
- int encOnTheFly; //encode while recording, no caching(default 0)
- char *workdir; //directory to be used for cache files(default $HOME)
- char *pause_shortcut; //pause/unpause shortcut sequence(Control+Alt+p)
- char *stop_shortcut; //stop shortcut sequence(Control+Alt+s)
- int noframe; //don't draw a frame around the recording area
- int zerocompression; //image data are always flushed uncompressed
- int overwrite; //overwite a previously existing file
- //(do not add a .number postfix)
- int use_jack; //record audio with jack
- unsigned int jack_nports;
- char *jack_port_names[RMD_MAX_JACK_PORTS];
- float jack_ringbuffer_secs;
+ const char* rescue_path;
+ int nosound; //do not record sound(default 0)
+ int noshared; //do not use shared memory extension(default 0)
+ int nowmcheck; //do not check if there's a 3d comp window manager
+ //(which changes full-shots and with-shared to 1)
+ int full_shots; //do not poll damage, take full screenshots
+ int follow_mouse; //capture area follows the mouse(fullshots auto enabled)
+ int no_encode; //do not encode or delete the temporary files(debug opt)
+ int no_quick_subsample; //average pixels in chroma planes
+ int v_bitrate,v_quality,s_quality; //video bitrate,video-sound quality
+ int encOnTheFly; //encode while recording, no caching(default 0)
+ char *workdir; //directory to be used for cache files(default $HOME)
+ char *pause_shortcut; //pause/unpause shortcut sequence(Control+Alt+p)
+ char *stop_shortcut; //stop shortcut sequence(Control+Alt+s)
+ int noframe; //don't draw a frame around the recording area
+ int zerocompression; //image data are always flushed uncompressed
+ int overwrite; //overwite a previously existing file
+ //(do not add a .number postfix)
+ int use_jack; //record audio with jack
+ unsigned int jack_nports;
+ char *jack_port_names[RMD_MAX_JACK_PORTS];
+ float jack_ringbuffer_secs;
}ProgArgs;
//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
- // it is used only while initializing
- ogg_packet m_ogg_pckt1; //theora stream
- ogg_packet m_ogg_pckt2; //vorbis stream
+ ogg_stream_state m_ogg_ts; //theora
+ ogg_stream_state m_ogg_vs; //vorbis
+ 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
//theora data
- theora_state m_th_st;
- theora_info m_th_inf;
- theora_comment m_th_cmmnt;
- yuv_buffer yuv;
+ theora_state m_th_st;
+ theora_info m_th_inf;
+ theora_comment m_th_cmmnt;
+ yuv_buffer yuv;
//vorbis data
- vorbis_info m_vo_inf;
- vorbis_comment m_vo_cmmnt;
- vorbis_dsp_state m_vo_dsp;
- vorbis_block m_vo_block;
+ vorbis_info m_vo_inf;
+ vorbis_comment m_vo_cmmnt;
+ vorbis_dsp_state m_vo_dsp;
+ vorbis_block m_vo_block;
//these should be 0, since area is quantized
//before input
- int x_offset,
- y_offset;
+ int x_offset,
+ y_offset;
//our file
- FILE *fp;
+ FILE *fp;
}EncData;
//this struct will hold a few basic
//information, needed for caching the frames.
typedef struct _CacheData{
- char *workdir, //The directory were the project
- //will be stored, while recording.
- //Since this will take a lot of space, the user must be
- //able to change the location.
- *projname, //This is the name of the folder that
- //will hold the project.
- //It is rMD-session-%d where %d is the pid
- //of the current proccess.
- //This way, running two instances
- //will not create problems
- //and also, a frontend can identify
- //leftovers from a possible crash
- //and delete them
- *specsfile, //workdir+projname+specs.txt
- *imgdata, //workdir+projname+img.out.gz
- *audiodata; //workdir+projname+audio.pcm
-
- gzFile *ifp; //image data file pointer
- FILE *uncifp; //uncompressed image data file pointer
-
- FILE *afp; //audio data file pointer
+ char *workdir, //The directory were the project
+ //will be stored, while recording.
+ //Since this will take a lot of space, the user must be
+ //able to change the location.
+ *projname, //This is the name of the folder that
+ //will hold the project.
+ //It is rMD-session-%d where %d is the pid
+ //of the current proccess.
+ //This way, running two instances
+ //will not create problems
+ //and also, a frontend can identify
+ //leftovers from a possible crash
+ //and delete them
+ *specsfile, //workdir+projname+specs.txt
+ *imgdata, //workdir+projname+img.out.gz
+ *audiodata; //workdir+projname+audio.pcm
+
+ gzFile *ifp; //image data file pointer
+ FILE *uncifp; //uncompressed image data file pointer
+
+ FILE *afp; //audio data file pointer
}CacheData;
@@ -213,33 +213,33 @@ typedef struct _CacheData{
//sound keeps coming so we que it in this list
//which we then traverse
typedef struct _SndBuffer{
- signed char *data;
- struct _SndBuffer *next;
+ signed char *data;
+ struct _SndBuffer *next;
}SndBuffer;
#ifdef HAVE_LIBJACK
typedef struct _JackData{
- ProgData *pdata; //pointer to prog data
- jack_client_t *client;
- unsigned int buffersize, //buffer size for every port in frames.
- frequency, //samplerate with which jack server was started.
- nports; //number of ports.
- float ringbuffer_secs;
- char **port_names; //names of ports(as specified in args).
- jack_port_t **ports; //connections to thes ports.
- jack_default_audio_sample_t **portbuf; //retrieval of audio buffers.
- pthread_mutex_t *snd_buff_ready_mutex; //mutex and cond_var
- pthread_cond_t *sound_data_read; //in the pdata struct
- jack_ringbuffer_t *sound_buffer; //data exchange happens through this
- int capture_started; //used to hold recording in the beginning
+ ProgData *pdata; //pointer to prog data
+ jack_client_t *client;
+ unsigned int buffersize, //buffer size for every port in frames.
+ frequency, //samplerate with which jack server was started.
+ nports; //number of ports.
+ float ringbuffer_secs;
+ char **port_names; //names of ports(as specified in args).
+ jack_port_t **ports; //connections to thes ports.
+ jack_default_audio_sample_t **portbuf; //retrieval of audio buffers.
+ pthread_mutex_t *snd_buff_ready_mutex; //mutex and cond_var
+ pthread_cond_t *sound_data_read; //in the pdata struct
+ jack_ringbuffer_t *sound_buffer; //data exchange happens through this
+ int capture_started; //used to hold recording in the beginning
}JackData;
#endif
-typedef struct _HotKey{ //Hold info about the shortcuts
- int modnum; //modnum is the number of modifier masks
- unsigned int mask[4]; //that should be checked (the initial
- int key; //user requested modifier plus it's
-}HotKey; //combinations with LockMask and NumLockMask).
+typedef struct _HotKey{ //Hold info about the shortcuts
+ int modnum; //modnum is the number of modifier masks
+ unsigned int mask[4]; //that should be checked (the initial
+ int key; //user requested modifier plus it's
+}HotKey; //combinations with LockMask and NumLockMask).
//this structure holds any data related to the program
//It's usage is mostly to be given as an argument to the
@@ -247,96 +247,96 @@ typedef struct _HotKey{ //Hold info about the shortcuts
//at the same time usage of any globals.
struct _ProgData {
/**recordMyDesktop specific structs*/
- ProgArgs args; //the program arguments
- DisplaySpecs specs; //Display specific information
- BRWindow brwin; //recording window
- RectArea *rect_root; //the interchanging list roots for storing
- //the changed regions
- SndBuffer *sound_buffer;
- EncData *enc_data;
- CacheData *cache_data;
- HotKey pause_key, //Shortcuts
- stop_key;
+ ProgArgs args; //the program arguments
+ DisplaySpecs specs; //Display specific information
+ BRWindow brwin; //recording window
+ RectArea *rect_root; //the interchanging list roots for storing
+ //the changed regions
+ SndBuffer *sound_buffer;
+ EncData *enc_data;
+ CacheData *cache_data;
+ HotKey pause_key, //Shortcuts
+ stop_key;
#ifdef HAVE_LIBJACK
- JackData *jdata;
+ JackData *jdata;
#endif
/**X related info*/
- Display *dpy; //curtrent display
+ Display *dpy; //curtrent display
/** Mutexes*/
- pthread_mutex_t sound_buffer_mutex,
- snd_buff_ready_mutex,
- img_buff_ready_mutex,
- theora_lib_mutex,
- vorbis_lib_mutex,
- libogg_mutex, //libogg is not thread safe,
- 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
- //Currently this mutex only prevents
- //the cursor from flickering
+ pthread_mutex_t sound_buffer_mutex,
+ snd_buff_ready_mutex,
+ img_buff_ready_mutex,
+ theora_lib_mutex,
+ vorbis_lib_mutex,
+ libogg_mutex, //libogg is not thread safe,
+ 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
+ //Currently this mutex only prevents
+ //the cursor from flickering
/**Condition Variables*/
- pthread_cond_t time_cond, //this gets a broadcast by the handler
- //whenever it's time to get a screenshot
- pause_cond, //this is blocks execution,
- //when program is paused
- sound_data_read, //a buffer is ready for proccessing
- image_buffer_ready, //image encoding finished
- theora_lib_clean, //the flush_ogg thread cannot
- //procceed to creating last
- vorbis_lib_clean; //packages until these two libs
- //are no longer used, by other threads
+ pthread_cond_t time_cond, //this gets a broadcast by the handler
+ //whenever it's time to get a screenshot
+ pause_cond, //this is blocks execution,
+ //when program is paused
+ sound_data_read, //a buffer is ready for proccessing
+ image_buffer_ready, //image encoding finished
+ theora_lib_clean, //the flush_ogg thread cannot
+ //procceed to creating last
+ vorbis_lib_clean; //packages until these two libs
+ //are no longer used, by other threads
/**Buffers,Flags and other vars*/
- unsigned char *dummy_pointer, //a dummy pointer to be drawn
- //in every frame
- //data is casted to unsigned for
- //later use in YUV buffer
- npxl; //this is the no pixel convention
- //when drawing the dummy pointer
- unsigned int periodtime,//time that a sound buffer lasts (microsecs)
- frametime; //time that a frame lasts (microsecs)
- Window shaped_w; //frame
- int damage_event, //damage event base code
- damage_error, //damage error base code
- shm_opcode, //MIT-Shm opcode
- dummy_p_size, //dummy pointer size,initially 16x16,always square
- th_encoding_clean, //thread exit inidcator
- v_encoding_clean, // >> >>
- v_enc_thread_waiting, //these indicate a wait
- th_enc_thread_waiting, //condition on the cond vars.
- timer_alive, //determines loop of timer thread
- hard_pause, //if sound device doesn't support pause
- //we have to close and reopen
- avd, //syncronization among audio and video
- sound_framesize; //size of each sound frame
-
- /** Progam state vars */
- boolean running; //1 while the program is capturing/paused/encoding
- boolean paused; //1 while the program is paused
- boolean aborted; //1 if we should abort
- boolean pause_state_changed; //1 if pause state changed
-
- //the following values are of no effect
- //but they might be usefull later for profiling
- unsigned int frames_total, //frames calculated by total time expirations
- frames_lost; //the value of shame
-
- //used to determine frame drop which can
- //happen on failure to receive a signal over a condition variable
- boolean capture_busy,
- encoder_busy;
-
- pthread_mutex_t pause_mutex;
- pthread_mutex_t time_mutex;
+ unsigned char *dummy_pointer, //a dummy pointer to be drawn
+ //in every frame
+ //data is casted to unsigned for
+ //later use in YUV buffer
+ npxl; //this is the no pixel convention
+ //when drawing the dummy pointer
+ unsigned int periodtime,//time that a sound buffer lasts (microsecs)
+ frametime; //time that a frame lasts (microsecs)
+ Window shaped_w; //frame
+ int damage_event, //damage event base code
+ damage_error, //damage error base code
+ shm_opcode, //MIT-Shm opcode
+ dummy_p_size, //dummy pointer size,initially 16x16,always square
+ th_encoding_clean, //thread exit inidcator
+ v_encoding_clean, // >> >>
+ v_enc_thread_waiting, //these indicate a wait
+ th_enc_thread_waiting, //condition on the cond vars.
+ timer_alive, //determines loop of timer thread
+ hard_pause, //if sound device doesn't support pause
+ //we have to close and reopen
+ avd, //syncronization among audio and video
+ sound_framesize; //size of each sound frame
+
+ /** Progam state vars */
+ boolean running; //1 while the program is capturing/paused/encoding
+ boolean paused; //1 while the program is paused
+ boolean aborted; //1 if we should abort
+ boolean pause_state_changed; //1 if pause state changed
+
+ //the following values are of no effect
+ //but they might be usefull later for profiling
+ unsigned int frames_total, //frames calculated by total time expirations
+ frames_lost; //the value of shame
+
+ //used to determine frame drop which can
+ //happen on failure to receive a signal over a condition variable
+ boolean capture_busy,
+ encoder_busy;
+
+ pthread_mutex_t pause_mutex;
+ pthread_mutex_t time_mutex;
#ifdef HAVE_LIBASOUND
- snd_pcm_t *sound_handle;
- snd_pcm_uframes_t periodsize;
+ snd_pcm_t *sound_handle;
+ snd_pcm_uframes_t periodsize;
#else
- int sound_handle;
- u_int32_t periodsize;
+ int sound_handle;
+ u_int32_t periodsize;
#endif
};
@@ -354,13 +354,13 @@ struct _ProgData {
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
- u_int32_t Ynum, //number of changed blocks in the Y plane
- Unum, //number of changed blocks in the U plane
- Vnum; //number of changed blocks in the V plane
+ 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
+ u_int32_t Ynum, //number of changed blocks in the Y plane
+ Unum, //number of changed blocks in the U plane
+ Vnum; //number of changed blocks in the V plane
}FrameHeader;
#endif
diff --git a/recordmydesktop/src/rmd_update_image.c b/recordmydesktop/src/rmd_update_image.c
index f7ee8d2..657868d 100644
--- a/recordmydesktop/src/rmd_update_image.c
+++ b/recordmydesktop/src/rmd_update_image.c
@@ -36,50 +36,55 @@
#include <X11/extensions/XShm.h>
-void rmdUpdateImage(Display * dpy,
- yuv_buffer *yuv,
- DisplaySpecs *specs,
- RectArea **root,
- BRWindow *brwin,
- EncData *enc,
- char *datatemp,
- int noshmem,
- XShmSegmentInfo *shminfo,
- int shm_opcode,
- int no_quick_subsample){
- RectArea *temp;
- unsigned char *dtap=(unsigned char*)datatemp;
- temp=*root;
+void rmdUpdateImage( Display * dpy,
+ yuv_buffer *yuv,
+ DisplaySpecs *specs,
+ RectArea **root,
+ BRWindow *brwin,
+ EncData *enc,
+ char *datatemp,
+ int noshmem,
+ XShmSegmentInfo *shminfo,
+ int shm_opcode,
+ int no_quick_subsample){
- if(temp!=NULL){
- do{
- if(noshmem){
- rmdGetZPixmap(dpy,
- specs->root,
- datatemp,
- temp->rect.x,
- temp->rect.y,
- temp->rect.width,
- temp->rect.height);
- }
- else{
- rmdGetZPixmapSHM(dpy,
- specs->root,
- shminfo,
- shm_opcode,
- datatemp,temp->rect.x,
- temp->rect.y,
- temp->rect.width,
- temp->rect.height);
- }
- UPDATE_YUV_BUFFER(yuv,dtap,NULL,
- (temp->rect.x-brwin->rrect.x+enc->x_offset),
- (temp->rect.y-brwin->rrect.y+enc->y_offset),
- (temp->rect.width),(temp->rect.height),
- no_quick_subsample,
- specs->depth);
- temp=temp->next;
- }while(temp!=NULL);
- }
+ RectArea *temp;
+ unsigned char *dtap=(unsigned char*)datatemp;
+ temp=*root;
+
+ if (temp!=NULL) {
+ do {
+ if (noshmem) {
+ rmdGetZPixmap( dpy,
+ specs->root,
+ datatemp,
+ temp->rect.x,
+ temp->rect.y,
+ temp->rect.width,
+ temp->rect.height);
+ } else {
+ rmdGetZPixmapSHM( dpy,
+ specs->root,
+ shminfo,
+ shm_opcode,
+ datatemp,temp->rect.x,
+ temp->rect.y,
+ temp->rect.width,
+ temp->rect.height);
+ }
+
+ UPDATE_YUV_BUFFER(
+ yuv,dtap,NULL,
+ temp->rect.x-brwin->rrect.x+enc->x_offset,
+ temp->rect.y-brwin->rrect.y+enc->y_offset,
+ temp->rect.width,
+ temp->rect.height,
+ no_quick_subsample,
+ specs->depth
+ );
+
+ temp=temp->next;
+ } while (temp!=NULL);
+ }
}
diff --git a/recordmydesktop/src/rmd_wm_check.c b/recordmydesktop/src/rmd_wm_check.c
index 39d86da..4934425 100644
--- a/recordmydesktop/src/rmd_wm_check.c
+++ b/recordmydesktop/src/rmd_wm_check.c
@@ -32,48 +32,45 @@
#include <X11/Xatom.h>
+char *rmdWMCheck(Display *dpy,Window root) {
+ Window *wm_child=NULL;
+ Atom nwm_atom,
+ utf8_string,
+ wm_name_atom,
+ rt;
+ unsigned long nbytes, nitems;
-char *rmdWMCheck(Display *dpy,Window root){
+ char *wm_name_str=NULL;
+ int fmt;
- Window *wm_child=NULL;
- Atom nwm_atom,
- utf8_string,
- wm_name_atom,
- rt;
- unsigned long nbytes,
- nitems;
+ utf8_string = XInternAtom(dpy, "UTF8_STRING", False);
- char *wm_name_str=NULL;
- int fmt;
+ nwm_atom =XInternAtom(dpy,"_NET_SUPPORTING_WM_CHECK",True);
+ wm_name_atom =XInternAtom(dpy,"_NET_WM_NAME",True);
- utf8_string = XInternAtom(dpy, "UTF8_STRING", False);
+ if (nwm_atom!=None && wm_name_atom!=None) {
- nwm_atom =XInternAtom(dpy,"_NET_SUPPORTING_WM_CHECK",True);
- wm_name_atom =XInternAtom(dpy,"_NET_WM_NAME",True);
+ if (XGetWindowProperty( dpy,root,nwm_atom,0,100,
+ False,XA_WINDOW,
+ &rt,&fmt,&nitems, &nbytes,
+ (unsigned char **)((void*)&wm_child))
+ != Success ) {
+ fprintf(stderr,"Error while trying to get a"
+ " window to identify the window manager.\n");
+ }
- if(nwm_atom!=None && wm_name_atom!=None){
- if(XGetWindowProperty( dpy,root,nwm_atom,0,100,
- False,XA_WINDOW,
- &rt,&fmt,&nitems, &nbytes,
- (unsigned char **)((void*)&wm_child))
- != Success ){
- fprintf(stderr,"Error while trying to get a"
- " window to identify the window manager.\n");
- }
- if((wm_child == NULL)||
- (XGetWindowProperty(dpy,*wm_child,wm_name_atom,0,100,
- False,utf8_string,&rt,
- &fmt,&nitems, &nbytes,
- (unsigned char **)((void*)&wm_name_str))
- !=Success)){
- fprintf(stderr,"Warning!!!\nYour window manager appears"
- " to be non-compliant!\n");
- }
- }
- fprintf(stderr,"Your window manager appears to be %s\n\n",
- ((wm_name_str!=NULL)?wm_name_str:"Unknown"));
+ if ((wm_child == NULL)||
+ (XGetWindowProperty(dpy,*wm_child,wm_name_atom,0,100,
+ False,utf8_string,&rt,
+ &fmt,&nitems, &nbytes,
+ (unsigned char **)((void*)&wm_name_str))
+ !=Success)) {
+ fprintf(stderr,"Warning!!!\nYour window manager appears"
+ " to be non-compliant!\n");
+ }
+ }
+ fprintf(stderr, "Your window manager appears to be %s\n\n",
+ ((wm_name_str!=NULL)?wm_name_str:"Unknown"));
-
- return wm_name_str;
+ return wm_name_str;
}
-
diff --git a/recordmydesktop/src/rmd_wm_is_compositing.c b/recordmydesktop/src/rmd_wm_is_compositing.c
index f893910..bc43282 100644
--- a/recordmydesktop/src/rmd_wm_is_compositing.c
+++ b/recordmydesktop/src/rmd_wm_is_compositing.c
@@ -36,32 +36,26 @@
boolean rmdWMIsCompositing( Display *dpy, int screen ) {
-
- Window win;
- Atom atom;
- char buf[32];
- char *window_manager=rmdWMCheck( dpy,
- RootWindow( dpy, screen ) );
-
- //If the wm name is queried successfully the wm is compliant (source
- //http://standards.freedesktop.org/wm-spec/1.4/ar01s03.html#id2568282 )
- //in which case we will also free() the allcoated string.
-
- if( window_manager == NULL )
- return FALSE;
- else
- free( window_manager );
+ Window win;
+ Atom atom;
+ char buf[32];
+ char *window_manager=rmdWMCheck( dpy, RootWindow( dpy, screen ) );
+ //If the wm name is queried successfully the wm is compliant (source
+ //http://standards.freedesktop.org/wm-spec/1.4/ar01s03.html#id2568282 )
+ //in which case we will also free() the allcoated string.
- snprintf( buf, sizeof(buf), "_NET_WM_CM_S%d", screen);
- atom = XInternAtom(dpy, buf, True);
- if (atom == None) return FALSE;
-
- win = XGetSelectionOwner(dpy, atom);
-
- return win != None;
+ if (window_manager == NULL)
+ return FALSE;
+ else
+ free(window_manager);
+ snprintf( buf, sizeof(buf), "_NET_WM_CM_S%d", screen);
+ atom = XInternAtom(dpy, buf, True);
+ if (atom == None)
+ return FALSE;
+ win = XGetSelectionOwner(dpy, atom);
+ return win != None;
}
-
diff --git a/recordmydesktop/src/rmd_yuv_utils.c b/recordmydesktop/src/rmd_yuv_utils.c
index ff5316e..491d9f1 100644
--- a/recordmydesktop/src/rmd_yuv_utils.c
+++ b/recordmydesktop/src/rmd_yuv_utils.c
@@ -31,30 +31,29 @@
// Keep these global (for performance reasons I assume).
-unsigned char Yr[256], Yg[256], Yb[256],
- Ur[256], Ug[256], UbVr[256],
- Vg[256], Vb[256];
+unsigned char Yr[256], Yg[256], Yb[256],
+ Ur[256], Ug[256], UbVr[256],
+ Vg[256], Vb[256];
// FIXME: These globals are modified in other source files! We keep
// thsee here for now. These are the cache blocks. They need to be
// accesible in the dbuf macros
-u_int32_t *yblocks,
- *ublocks,
- *vblocks;
+u_int32_t *yblocks,
+ *ublocks,
+ *vblocks;
void rmdMakeMatrices (void) {
-
- int i;
+ int i;
/* assuming 8-bit precision */
float Yscale = 219.0, Yoffset = 16.0;
float Cscale = 224.0, Coffset = 128.0;
float RGBscale = 255.0;
- float r, g, b;
- float yr, yg, yb;
- float ur, ug, ub;
- float vg, vb; /* vr intentionally missing */
+ float r, g, b;
+ float yr, yg, yb;
+ float ur, ug, ub;
+ float vg, vb; /* vr intentionally missing */
/* as for ITU-R BT-601-6 specifications: */
r = 0.299;
@@ -75,20 +74,16 @@ void rmdMakeMatrices (void) {
vg = ( -0.5 * g / ( 1 - r ) ) * Cscale / RGBscale;
vb = ( -0.5 * b / ( 1 - r ) ) * Cscale / RGBscale;
- for( i = 0 ; i < 256 ; i++ ) {
+ for (i = 0; i < 256; i++) {
+ Yr[i] = (unsigned char) rmdRoundf( Yoffset + yr * i );
+ Yg[i] = (unsigned char) rmdRoundf( yg * i );
+ Yb[i] = (unsigned char) rmdRoundf( yb * i );
- Yr[i] = (unsigned char) rmdRoundf( Yoffset + yr * i );
- Yg[i] = (unsigned char) rmdRoundf( yg * i );
- Yb[i] = (unsigned char) rmdRoundf( yb * i );
-
- Ur[i] = (unsigned char) rmdRoundf( Coffset + ur * i );
- Ug[i] = (unsigned char) rmdRoundf( ug * i );
- UbVr[i] = (unsigned char) rmdRoundf( ub * i );
-
- Vg[i] = (unsigned char) rmdRoundf( vg * i );
- Vb[i] = (unsigned char) rmdRoundf( Coffset + vb * i );
-
- }
+ Ur[i] = (unsigned char) rmdRoundf( Coffset + ur * i );
+ Ug[i] = (unsigned char) rmdRoundf( ug * i );
+ UbVr[i] = (unsigned char) rmdRoundf( ub * i );
+ Vg[i] = (unsigned char) rmdRoundf( vg * i );
+ Vb[i] = (unsigned char) rmdRoundf( Coffset + vb * i );
+ }
}
-
diff --git a/recordmydesktop/src/rmd_yuv_utils.h b/recordmydesktop/src/rmd_yuv_utils.h
index d38b1b7..f0c9130 100644
--- a/recordmydesktop/src/rmd_yuv_utils.h
+++ b/recordmydesktop/src/rmd_yuv_utils.h
@@ -93,7 +93,7 @@ extern u_int32_t *yblocks,
__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,\
+ 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;\
for(k=0;k<height_tm;k++){\
@@ -105,7 +105,7 @@ extern u_int32_t *yblocks,
datapi++;\
yuv_y++;\
}\
- yuv_y+=yuv->y_width-width_tm;\
+ yuv_y+=(yuv)->y_width-width_tm;\
}\
}
@@ -142,8 +142,8 @@ extern u_int32_t *yblocks,
__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,\
+ 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,\
@@ -167,8 +167,8 @@ extern u_int32_t *yblocks,
yuv_u++;\
yuv_v++;\
}\
- yuv_u+=(yuv->y_width-width_tm)/2;\
- yuv_v+=(yuv->y_width-width_tm)/2;\
+ yuv_u+=((yuv)->y_width-width_tm)/2;\
+ yuv_v+=((yuv)->y_width-width_tm)/2;\
datapi+=width_tm;\
if(__sampling_type==__PXL_AVERAGE)\
datapi_next+=width_tm;\
@@ -232,11 +232,11 @@ extern u_int32_t *yblocks,
Yg[data_tm[(j*4)+__GBYTE]] +\
Yb[data_tm[(j*4)+__BBYTE]];\
if((k%2)&&(i%2)){\
- yuv->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*y_width_2]=\
+ (yuv)->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*y_width_2]=\
Ur[data_tm[(k*width_tm+i)*4+__RBYTE]] +\
Ug[data_tm[(k*width_tm+i)*4+__GBYTE]] +\
UbVr[data_tm[(k*width_tm+i)*4+__BBYTE]];\
- yuv->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*y_width_2]=\
+ (yuv)->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*y_width_2]=\
UbVr[data_tm[(k*width_tm+i)*4+__RBYTE]] +\
Vg[data_tm[(k*width_tm+i)*4+__GBYTE]] +\
Vb[data_tm[(k*width_tm+i)*4+__BBYTE]] ;\
@@ -256,7 +256,7 @@ extern u_int32_t *yblocks,
__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,\
+ 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;\
@@ -273,7 +273,7 @@ extern u_int32_t *yblocks,
datapi_back++;\
yuv_y++;\
}\
- yuv_y+=yuv->y_width-width_tm;\
+ yuv_y+=(yuv)->y_width-width_tm;\
}\
}
@@ -288,8 +288,8 @@ extern u_int32_t *yblocks,
__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,\
+ 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,\
@@ -325,8 +325,8 @@ extern u_int32_t *yblocks,
yuv_u++;\
yuv_v++;\
}\
- yuv_u+=(yuv->y_width-width_tm)/2;\
- yuv_v+=(yuv->y_width-width_tm)/2;\
+ 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){\
@@ -359,8 +359,8 @@ extern u_int32_t *yblocks,
yuv_u++;\
yuv_v++;\
}\
- yuv_u+=(yuv->y_width-width_tm)/2;\
- yuv_v+=(yuv->y_width-width_tm)/2;\
+ 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){\
© All Rights Reserved