diff options
-rw-r--r-- | recordmydesktop/INSTALL | 1 | ||||
-rw-r--r-- | recordmydesktop/configure.ac | 7 | ||||
-rw-r--r-- | recordmydesktop/include/recordmydesktop.h | 38 | ||||
-rw-r--r-- | recordmydesktop/src/Makefile.am | 2 | ||||
-rw-r--r-- | recordmydesktop/src/get_frame.c | 30 | ||||
-rw-r--r-- | recordmydesktop/src/parseargs.c | 8 | ||||
-rw-r--r-- | recordmydesktop/src/queryextensions.c | 19 |
7 files changed, 94 insertions, 11 deletions
diff --git a/recordmydesktop/INSTALL b/recordmydesktop/INSTALL index fe3d120..607c33e 100644 --- a/recordmydesktop/INSTALL +++ b/recordmydesktop/INSTALL @@ -13,6 +13,7 @@ alsa (libasound) X libXext libXdamage +libXfixes libogg libvorbis libtheora diff --git a/recordmydesktop/configure.ac b/recordmydesktop/configure.ac index 081eae6..21e8b83 100644 --- a/recordmydesktop/configure.ac +++ b/recordmydesktop/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.59) AC_INIT(src/recordmydesktop.c) -AM_INIT_AUTOMAKE(recordmydesktop,0.2.4,) +AM_INIT_AUTOMAKE(recordmydesktop,0.2.5,) AC_CONFIG_SRCDIR([src/recordmydesktop.c]) AM_CONFIG_HEADER(config.h) @@ -28,7 +28,9 @@ AC_CHECK_HEADERS([sys/time.h unistd.h vorbis/vorbisfile.h ]) LDFLAGS="$LD_FLAGS -L$x_libraries $X_LIBS $X_EXTRA_LIBS $X_PRE_LIBS" -CFLAGS="${CFLAGS} -O3 -Wall -D_THREAD_SAFE -pthread" +#no-O3s-thx.patch ;) +CFLAGS="${CFLAGS} -Wall -D_THREAD_SAFE -pthread" + @@ -39,6 +41,7 @@ AC_CHECK_LIB([z],[deflate],,) AC_CHECK_LIB([X11],[XOpenDisplay],,AC_MSG_ERROR([Can't find libX11]), -L$x_libraries $X_PRE_LIBS) AC_CHECK_LIB([Xext],[XShmQueryVersion],,AC_MSG_ERROR([Can't find libXext])) +AC_CHECK_LIB([Xfixes], [XFixesQueryExtension],,AC_MSG_ERROR([Can't find libXfixes])) AC_CHECK_LIB([Xdamage], [XDamageQueryExtension],,AC_MSG_ERROR([Can't find libXdamage])) AC_CHECK_LIB([vorbis],[vorbis_info_clear],,AC_MSG_ERROR([Can't find libvorbis])) AC_CHECK_LIB([vorbisfile],[ov_open],,AC_MSG_ERROR([Can't find libvorbisfile]),-lvorbis) diff --git a/recordmydesktop/include/recordmydesktop.h b/recordmydesktop/include/recordmydesktop.h index 7980f02..cc1f025 100644 --- a/recordmydesktop/include/recordmydesktop.h +++ b/recordmydesktop/include/recordmydesktop.h @@ -44,12 +44,14 @@ #include <sys/time.h> #include <sys/types.h> #include <endian.h> +#include <limits.h> #include <sys/stat.h> #include <sys/ipc.h> #include <sys/shm.h> #include <pthread.h> #include <X11/Xlib.h> #include <X11/Xlibint.h> +#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xdamage.h> #include <X11/extensions/XShm.h> #include <theora/theora.h> @@ -122,7 +124,9 @@ typedef struct _ProgArgs{ char *filename; //output file(default out.[ogg|*]) int encoding; //encoding(default OGG_THEORA_VORBIS) int cursor_color; //black or white=>1 or 0 - int have_dummy_cursor;//disable/enable drawing the dummy cursor + 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) @@ -294,13 +298,14 @@ unsigned char Yr[256],Yg[256],Yb[256], =(args)->nosound=(args)->scshot=(args)->full_shots=0;\ (args)->noshared=(args)->scale_shot=1;\ (args)->dropframes=(args)->nocondshared=0;\ - (args)->no_quick_subsample=0;\ + (args)->no_quick_subsample=1;\ (args)->filename=(char *)malloc(8);\ strcpy((args)->filename,"out.ogg");\ (args)->encoding=OGG_THEORA_VORBIS;\ (args)->cursor_color=1;\ (args)->shared_thres=75;\ - (args)->have_dummy_cursor=1;\ + (args)->have_dummy_cursor=0;\ + (args)->xfixes_cursor=1;\ (args)->device=(char *)malloc(8);\ strcpy((args)->device,"hw:0,0");\ (args)->fps=15;\ @@ -405,7 +410,32 @@ unsigned char Yr[256],Yg[256],Yb[256], }\ } - +#define XFIXES_POINTER_TO_YUV(yuv,data,x_tm,y_tm,width_tm,height_tm,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=0;k<height_tm;k++){\ + for(i=0;i<width_tm;i++){\ + yuv->y[x_tm+i+(k+y_tm)*yuv->y_width]=\ + (yuv->y[x_tm+i+(k+y_tm)*yuv->y_width]*(UCHAR_MAX-data[(j*4)+__ABYTE])+\ + (Yr[data[(j*4)+__RBYTE]] + Yg[data[(j*4)+__GBYTE]] + Yb[data[(j*4)+__BBYTE]])*data[(j*4)+__ABYTE])/UCHAR_MAX ;\ + if((k%2)&&(i%2)){\ + avg3=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__ABYTE);\ + avg2=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__RBYTE);\ + avg1=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__GBYTE);\ + avg0=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__BBYTE);\ + yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + (yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]*(UCHAR_MAX-avg3)+\ + (Ur[avg2] + Ug[avg1] +Ub[avg0])*avg3)/UCHAR_MAX;\ + yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + (yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]*(UCHAR_MAX-avg3)+\ + (Vr[avg2] + Vg[avg1] +Vb[avg0])*avg3)/UCHAR_MAX;\ + }\ + j++;\ + }\ + j+=column_discard_stride;\ + }\ +} #define DUMMY_POINTER_TO_YUV(yuv,data_tm,x_tm,y_tm,width_tm,height_tm,no_pixel){\ int i,k,j=0;\ diff --git a/recordmydesktop/src/Makefile.am b/recordmydesktop/src/Makefile.am index bec4006..e56b856 100644 --- a/recordmydesktop/src/Makefile.am +++ b/recordmydesktop/src/Makefile.am @@ -24,5 +24,5 @@ recordmydesktop_SOURCES= recordmydesktop.c\ INCLUDES= $(all_includes) -I../include -I$x_includes -recordmydesktop_LDFLAGS = -D_THREAD_SAFE -pthread -Wall -O3 +recordmydesktop_LDFLAGS = -D_THREAD_SAFE -pthread -Wall diff --git a/recordmydesktop/src/get_frame.c b/recordmydesktop/src/get_frame.c index 81ca392..ff935c0 100644 --- a/recordmydesktop/src/get_frame.c +++ b/recordmydesktop/src/get_frame.c @@ -34,6 +34,7 @@ void *GetFrame(void *pdata){ WGeometry mouse_pos_abs,mouse_pos_rel,mouse_pos_temp; Window root_ret,child_ret; int pixel_total=((ProgData *)pdata)->brwin.rgeom.width*((ProgData *)pdata)->brwin.rgeom.height; + XFixesCursorImage *xcim=NULL; mouse_pos_abs.x=0; mouse_pos_abs.y=0; @@ -72,6 +73,21 @@ void *GetFrame(void *pdata){ // } } } + if(((ProgData *)pdata)->args.xfixes_cursor){ + //xfixes pointer sequence + //update previous_position + //(if full_shots is enabled this is skipped since it's pointless) + if(!((ProgData *)pdata)->args.full_shots){ + CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&((ProgData *)pdata)->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)) + RectInsert(&((ProgData *)pdata)->rect_root[tlist_sel],&mouse_pos_temp); + } + xcim=XFixesGetCursorImage(((ProgData *)pdata)->dpy); + mouse_pos_abs.x=xcim->x; + mouse_pos_abs.y=xcim->y; + mouse_pos_abs.width=xcim->width; + mouse_pos_abs.height=xcim->height; + } if(((ProgData *)pdata)->args.have_dummy_cursor){ //dummy pointer sequence //update previous_position @@ -139,6 +155,20 @@ void *GetFrame(void *pdata){ pthread_mutex_unlock(&((ProgData *)pdata)->yuv_mutex); } } + if(((ProgData *)pdata)->args.xfixes_cursor){ + //avoid segfaults + CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&((ProgData *)pdata)->brwin,&mouse_pos_temp); + //draw the cursor + if((mouse_pos_temp.x>=0)&&(mouse_pos_temp.y>=0)&&(mouse_pos_temp.width>0)&&(mouse_pos_temp.height>0)){ + XFIXES_POINTER_TO_YUV((&((ProgData *)pdata)->enc_data->yuv),((unsigned char*)xcim->pixels), + (mouse_pos_temp.x-((ProgData *)pdata)->brwin.rgeom.x+((ProgData *)pdata)->enc_data->x_offset), + (mouse_pos_temp.y-((ProgData *)pdata)->brwin.rgeom.y+((ProgData *)pdata)->enc_data->y_offset), + mouse_pos_temp.width, + mouse_pos_temp.height, + (xcim->width-mouse_pos_temp.width)); + } + } + if(((ProgData *)pdata)->args.have_dummy_cursor){ //avoid segfaults CLIP_DUMMY_POINTER_AREA(mouse_pos_abs,&((ProgData *)pdata)->brwin,&mouse_pos_temp); diff --git a/recordmydesktop/src/parseargs.c b/recordmydesktop/src/parseargs.c index c858db0..6b40cc9 100644 --- a/recordmydesktop/src/parseargs.c +++ b/recordmydesktop/src/parseargs.c @@ -36,7 +36,7 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ "\t -v_quality n| -s_quality n| -v_bitrate n| --no-framedrop| -dummy-cursor color|\n" "\t --no-dummy-cursor| -freq N(number>0)| -channels N(number>0)| -device SOUND_DEVICE|\n" "\t --nosound| --with-shared| --no-cond-shared| -shared-threshold n| --full-shots|\n" - "\t --no-quick-subsampling| --scshot| -scale-shot N| -o filename]^filename\n\n\n" + "\t --quick-subsampling| --scshot| -scale-shot N| -o filename]^filename\n\n\n" "General Options:\n" "\t-h or --help\t\tPrint this help and exit.\n" @@ -56,7 +56,7 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ "\t--no-cond-shared\tDo not use the MIT-shared memory extension when aquiring large areas.\n" "\t-shared-threshold n\tThreshold over which shared memory is used(default 75).\n" "\t--full-shots\t\tTake full screenshot at every frame(Not recomended!).\n" - "\t--no-quick-subsampling\tDo subsampling of the chroma planes by averaging,not discarding.\n" + "\t--quick-subsampling\tDo subsampling of the chroma planes by discarding,not averaging.\n" "\t-fps N(number>0.0)\tA positive number denoting desired framerate.\n\n" "Sound Options:\n" @@ -399,8 +399,8 @@ int ParseArgs(int argc,char **argv,ProgArgs *arg_return){ arg_return->scshot=1; arg_return->nocondshared=1; } - else if(!strcmp(argv[i],"--no-quick-subsampling")){ - arg_return->no_quick_subsample=1; + else if(!strcmp(argv[i],"--quick-subsampling")){ + arg_return->no_quick_subsample=0; } else if(!strcmp(argv[i],"--help")||!strcmp(argv[i],"-h")){ fprintf(stderr,"%s",usage); diff --git a/recordmydesktop/src/queryextensions.c b/recordmydesktop/src/queryextensions.c index 056e534..0ccac84 100644 --- a/recordmydesktop/src/queryextensions.c +++ b/recordmydesktop/src/queryextensions.c @@ -28,6 +28,9 @@ #include <recordmydesktop.h> int QueryExtensions(Display *dpy,ProgArgs *args,int *damage_event,int *damage_error){ + int xf_event_basep, + xf_error_basep; + if(!XDamageQueryExtension( dpy, damage_event, damage_error)){ fprintf(stderr,"XDamage extension not found!!!\n"); return 1; @@ -36,5 +39,21 @@ int QueryExtensions(Display *dpy,ProgArgs *args,int *damage_event,int *damage_er args->noshared=1; fprintf(stderr,"Shared Memory extension not present!\nContinuing without it.\n"); } + if((args->xfixes_cursor)&&(XFixesQueryExtension(dpy,&xf_event_basep,&xf_error_basep)==False)){ + args->xfixes_cursor=0; + fprintf(stderr,"Xfixes extension not present!\nContinuing without it.\n"); + } +// XFixesCursorImage *xcim; +// xcim=XFixesGetCursorImage (dpy); +// fprintf(stderr,"XFIXES:\n\n%d %d\n\n\n%d %d\n\n",xcim->width,xcim->height,xcim->xhot,xcim->yhot); +// int i=0,k=0; +// unsigned char *cp=((unsigned char *)xcim->pixels); +// for(i=0;i<xcim->height;i++){ +// for(k=0;k<xcim->width*4;k+=4){ +// fprintf(stderr,"%d",cp[i*xcim->width*4+k]); +// } +// fprintf(stderr,"\n"); +// } + return 0; } |