diff options
Diffstat (limited to 'recordmydesktop/src')
-rw-r--r-- | recordmydesktop/src/cache_frame.c | 6 | ||||
-rw-r--r-- | recordmydesktop/src/get_frame.c | 117 | ||||
-rw-r--r-- | recordmydesktop/src/load_cache.c | 37 | ||||
-rw-r--r-- | recordmydesktop/src/poll_events.c | 40 | ||||
-rw-r--r-- | recordmydesktop/src/recordmydesktop.c | 13 | ||||
-rw-r--r-- | recordmydesktop/src/rectinsert.c | 38 | ||||
-rw-r--r-- | recordmydesktop/src/rmd_cache.c | 12 | ||||
-rw-r--r-- | recordmydesktop/src/rmd_jack.c | 80 | ||||
-rw-r--r-- | recordmydesktop/src/setbrwindow.c | 15 |
9 files changed, 344 insertions, 14 deletions
diff --git a/recordmydesktop/src/cache_frame.c b/recordmydesktop/src/cache_frame.c index 327318b..5e75700 100644 --- a/recordmydesktop/src/cache_frame.c +++ b/recordmydesktop/src/cache_frame.c @@ -27,6 +27,12 @@ #include <recordmydesktop.h> +//minimize hard disk access +#define CACHE_OUT_BUFFER_SIZE 4096 +//500 mb file size +#define CACHE_FILE_SIZE_LIMIT (500*1<<20) + + int FlushBlock(unsigned char *buf, int blockno, int width, diff --git a/recordmydesktop/src/get_frame.c b/recordmydesktop/src/get_frame.c index f20c995..fd4eda8 100644 --- a/recordmydesktop/src/get_frame.c +++ b/recordmydesktop/src/get_frame.c @@ -28,6 +28,123 @@ #include <recordmydesktop.h> +#define CLIP_DUMMY_POINTER_AREA(dummy_p_area,brwin,wgeom){\ + (wgeom)->x=((((dummy_p_area).x+\ + (dummy_p_area).width>=(brwin)->rgeom.x)&&\ + ((dummy_p_area).x<=(brwin)->rgeom.x+\ + (brwin)->rgeom.width))?\ + (((dummy_p_area).x<=(brwin)->rgeom.x)?\ + (brwin)->rgeom.x:(dummy_p_area).x):-1);\ + (wgeom)->y=((((dummy_p_area).y+\ + (dummy_p_area).height>=(brwin)->rgeom.y)&&\ + ((dummy_p_area).y<=(brwin)->rgeom.y+\ + (brwin)->rgeom.height))?\ + (((dummy_p_area).y<=(brwin)->rgeom.y)?\ + (brwin)->rgeom.y:(dummy_p_area).y):-1);\ + (wgeom)->width=((dummy_p_area).x<=(brwin)->rgeom.x)?\ + (dummy_p_area).width-\ + ((brwin)->rgeom.x-(dummy_p_area).x):\ + ((dummy_p_area).x<=(brwin)->rgeom.x+\ + (brwin)->rgeom.width)?\ + ((brwin)->rgeom.width-(dummy_p_area).x+\ + (brwin)->rgeom.x<(dummy_p_area).width)?\ + (brwin)->rgeom.width-(dummy_p_area).x+\ + (brwin)->rgeom.x:(dummy_p_area).width:-1;\ + (wgeom)->height=((dummy_p_area).y<=(brwin)->rgeom.y)?\ + (dummy_p_area).height-\ + ((brwin)->rgeom.y-(dummy_p_area).y):\ + ((dummy_p_area).y<=(brwin)->rgeom.y+\ + (brwin)->rgeom.height)?\ + ((brwin)->rgeom.height-(dummy_p_area).y+\ + (brwin)->rgeom.y<(dummy_p_area).height)?\ + (brwin)->rgeom.height-(dummy_p_area).y+\ + (brwin)->rgeom.y:(dummy_p_area).height:-1;\ + if((wgeom)->width>(brwin)->rgeom.width)\ + (wgeom)->width=(brwin)->rgeom.width;\ + if((wgeom)->height>(brwin)->rgeom.height)\ + (wgeom)->height=(brwin)->rgeom.height;\ +} + +#define XFIXES_POINTER_TO_YUV(yuv,\ + data,\ + x_tm,\ + y_tm,\ + width_tm,\ + height_tm,\ + x_offset,\ + y_offset,\ + 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++){\ + 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]*\ + (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]])*\ + data[(j*RMD_ULONG_SIZE_T)+__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-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])*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]*\ + (UCHAR_MAX-avg3)+\ + (UbVr[avg2] + Vg[avg1] +Vb[avg0])*avg3)/UCHAR_MAX;\ + }\ + }\ + }\ +} + +#define MARK_BACK_BUFFER( data,\ + x_tm,\ + y_tm,\ + width_tm,\ + height_tm,\ + buffer_width,\ + __bit_depth__){\ + if((__bit_depth__==24)||(__bit_depth__==32)){\ + MARK_BACK_BUFFER_C( data,\ + x_tm,\ + y_tm,\ + width_tm,\ + height_tm,\ + buffer_width,\ + 32)\ + }\ + else{\ + MARK_BACK_BUFFER_C( data,\ + x_tm,\ + y_tm,\ + width_tm,\ + height_tm,\ + buffer_width,\ + 16)\ + }\ +}\ + + //besides taking the first screenshot, this functions primary purpose is to //initialize the structures and memory. int FirstFrame(ProgData *pdata,XImage **image,XShmSegmentInfo *shminfo, diff --git a/recordmydesktop/src/load_cache.c b/recordmydesktop/src/load_cache.c index 6973770..020e90f 100644 --- a/recordmydesktop/src/load_cache.c +++ b/recordmydesktop/src/load_cache.c @@ -27,6 +27,43 @@ #include <recordmydesktop.h> + +//The number of bytes for every +//sub-block of the y,u and v planes. +//Since the blocks are square +//these are obviously the squares +//of the widths(specified above), +//but the definitions bellow are only +//for convenience anyway. +#define Y_UNIT_BYTES 0x0100 +#define UV_UNIT_BYTES 0x0040 + +#define INIT_FRAME(frame_t,fheader_t,yuv_t,\ + YBlocks_t,UBlocks_t,VBlocks_t){\ + (frame_t)->header=(fheader_t);\ + (frame_t)->YBlocks=YBlocks_t;\ + (frame_t)->UBlocks=UBlocks_t;\ + (frame_t)->VBlocks=VBlocks_t;\ + (frame_t)->YData=malloc((yuv_t)->y_width*(yuv_t)->y_height);\ + (frame_t)->UData=malloc((yuv_t)->uv_width*(yuv_t)->uv_height);\ + (frame_t)->VData=malloc((yuv_t)->uv_width*(yuv_t)->uv_height);\ +}; + + +//The frame after retrieval. +//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 +}CachedFrame; + + void LoadBlock(unsigned char *dest, unsigned char *source, int blockno, diff --git a/recordmydesktop/src/poll_events.c b/recordmydesktop/src/poll_events.c index fbe862c..7168a5a 100644 --- a/recordmydesktop/src/poll_events.c +++ b/recordmydesktop/src/poll_events.c @@ -40,6 +40,46 @@ #include <rmdmacro.h> +#define CLIP_EVENT_AREA(e,brwin,wgeom){\ + if(((e)->area.x<=(brwin)->rgeom.x)&&((e)->area.y<=(brwin)->rgeom.y)&&\ + ((e)->area.width>=(brwin)->rgeom.width)&&\ + ((e)->area.height<(brwin)->rgeom.height)){\ + (wgeom)->x=(brwin)->rgeom.x;\ + (wgeom)->y=(brwin)->rgeom.y;\ + (wgeom)->width=(brwin)->rgeom.width;\ + (wgeom)->height=(brwin)->rgeom.height;\ + }\ + else{\ + (wgeom)->x=((((e)->area.x+(e)->area.width>=(brwin)->rgeom.x)&&\ + ((e)->area.x<=(brwin)->rgeom.x+(brwin)->rgeom.width))?\ + (((e)->area.x<=(brwin)->rgeom.x)?(brwin)->rgeom.x:(e)->area.x):-1);\ + \ + (wgeom)->y=((((e)->area.y+(e)->area.height>=(brwin)->rgeom.y)&&\ + ((e)->area.y<=(brwin)->rgeom.y+(brwin)->rgeom.height))?\ + (((e)->area.y<=(brwin)->rgeom.y)?(brwin)->rgeom.y:(e)->area.y):-1);\ + \ + (wgeom)->width=((e)->area.x<=(brwin)->rgeom.x)?\ + (e)->area.width-((brwin)->rgeom.x-(e)->area.x):\ + ((e)->area.x<=(brwin)->rgeom.x+(brwin)->rgeom.width)?\ + (((brwin)->rgeom.width-(e)->area.x+(brwin)->rgeom.x<(e)->area.width)?\ + (brwin)->rgeom.width-(e)->area.x+(brwin)->rgeom.x:e->area.width):-1;\ + \ + (wgeom)->height=((e)->area.y<=(brwin)->rgeom.y)?\ + (e)->area.height-((brwin)->rgeom.y-(e)->area.y):\ + ((e)->area.y<=(brwin)->rgeom.y+(brwin)->rgeom.height)?\ + (((brwin)->rgeom.height-(e)->area.y+\ + (brwin)->rgeom.y<(e)->area.height)?\ + (brwin)->rgeom.height-(e)->area.y+\ + (brwin)->rgeom.y:(e)->area.height):-1;\ + \ + if((wgeom)->width>(brwin)->rgeom.width)\ + (wgeom)->width=(brwin)->rgeom.width;\ + if((wgeom)->height>(brwin)->rgeom.height)\ + (wgeom)->height=(brwin)->rgeom.height;\ + }\ +} + + void InitEventsPolling(ProgData *pdata){ Window root_return, parent_return, diff --git a/recordmydesktop/src/recordmydesktop.c b/recordmydesktop/src/recordmydesktop.c index 49ce0ca..c919690 100644 --- a/recordmydesktop/src/recordmydesktop.c +++ b/recordmydesktop/src/recordmydesktop.c @@ -28,6 +28,19 @@ #include <recordmydesktop.h> +#define QUERY_DISPLAY_SPECS(display,specstruct){\ + (specstruct)->screen=DefaultScreen(display);\ + (specstruct)->width=DisplayWidth(display,(specstruct)->screen);\ + (specstruct)->height=DisplayHeight(display,(specstruct)->screen);\ + (specstruct)->root=RootWindow(display,(specstruct)->screen);\ + (specstruct)->visual=DefaultVisual(display,(specstruct)->screen);\ + (specstruct)->gc=DefaultGC(display,(specstruct)->screen);\ + (specstruct)->depth=DefaultDepth(display,(specstruct)->screen);\ + (specstruct)->bpixel=XBlackPixel(display,(specstruct)->screen);\ + (specstruct)->wpixel=XWhitePixel(display,(specstruct)->screen);\ +} + + int main(int argc,char **argv){ ProgData pdata; diff --git a/recordmydesktop/src/rectinsert.c b/recordmydesktop/src/rectinsert.c index 1eaa9ef..8685fbb 100644 --- a/recordmydesktop/src/rectinsert.c +++ b/recordmydesktop/src/rectinsert.c @@ -26,15 +26,35 @@ #include <recordmydesktop.h> -//return 1 and null if geom1 in geom2 ,2 and null if geom2 in geom1, -//0 if they don't collide -//-1 and two geoms if they collide and geom1 is broken. -//-2 and one or two geoms if they collide and geom2 is broken. -//-10 if group and replace is possible -int CollideRects(WGeometry *wgeom1, - WGeometry *wgeom2, - WGeometry **wgeom_return, - int *ngeoms){ + +/** +* Collide two rectangles and dictate most sane action for insertion, +* as well as provide the updated rectangle(s) +* \param wgeom1 resident rectangle +* +* \param wgeom2 New rectangle +* +* \param wgeom_return Pointer to rectangles to be inserted +* +* \param ngeoms number of entries in wgeom_return +* +* \retval 0 No collision +* +* \retval 1 wgeom1 is covered by wgeom2 +* +* \retval 2 wgeom2 is covered by wgeom1 +* +* \retval -1 wgeom1 was broken (new is picked up in wgeom_return) +* +* \retval -2 wgeom2 was broken (new is picked up in wgeom_return) +* +* \retval -10 Grouping the two geoms is possible +* +*/ +static int CollideRects(WGeometry *wgeom1, + WGeometry *wgeom2, + WGeometry **wgeom_return, + int *ngeoms) { //1 fits in 2 if((wgeom1->x>=wgeom2->x)&& (wgeom1->x+wgeom1->width<=wgeom2->x+wgeom2->width)&& diff --git a/recordmydesktop/src/rmd_cache.c b/recordmydesktop/src/rmd_cache.c index 1c22349..ad4388f 100644 --- a/recordmydesktop/src/rmd_cache.c +++ b/recordmydesktop/src/rmd_cache.c @@ -27,7 +27,17 @@ #include <recordmydesktop.h> -void CacheFileN(char *name,char **newname,int n){//nth cache file +/** +*Construct an number postfixed name +* +* \param name base name +* +* \param newname modified name +* +* \n number to be used as a postfix +* +*/ +static void CacheFileN(char *name, char **newname, int n) { // Nth cache file char numbuf[8]; strcpy(*newname,name); strcat(*newname,"."); diff --git a/recordmydesktop/src/rmd_jack.c b/recordmydesktop/src/rmd_jack.c index 05bcf1a..aacb883 100644 --- a/recordmydesktop/src/rmd_jack.c +++ b/recordmydesktop/src/rmd_jack.c @@ -28,7 +28,65 @@ #include <recordmydesktop.h> #ifdef HAVE_JACK_H -int JackCapture(jack_nframes_t nframes,void *jdata_t){ + + +#define CHECK_DLERRORS_FATAL(__error_p)\ + if((__error_p=dlerror())!=NULL){\ + fprintf(stderr,"%s\n",__error_p);\ + return 1;\ + } + +#define DLSYM_AND_CHECK(lib_handle,__call_name__,__error_p)\ + __call_name__##_p=dlsym(lib_handle,#__call_name__);\ + CHECK_DLERRORS_FATAL(__error_p) + + +/** +* +* Fuction Pointers To Jack API Calls (shouldn't a jack header provide these?) +* +*/ +jack_client_t *(*jack_client_new_p)(const char *client_name); +jack_nframes_t (*jack_get_sample_rate_p)(jack_client_t * client); +int (*jack_set_buffer_size_p)(jack_client_t *client, jack_nframes_t nframes); +jack_nframes_t (*jack_get_buffer_size_p)(jack_client_t *client); +int (*jack_set_process_callback_p)(jack_client_t *client, + JackProcessCallback process_callback, + void *arg); +void (*jack_on_shutdown_p)(jack_client_t *client, + void(*function)(void *arg), + void *arg); +int (*jack_activate_p)(jack_client_t *client); +int (*jack_client_close_p)(jack_client_t *client); +void *(*jack_port_get_buffer_p)(jack_port_t *port,jack_nframes_t); +jack_port_t *(*jack_port_register_p)(jack_client_t *client, + const char *port_name, + const char *port_type, + unsigned long flags, + unsigned long buffer_size); +int (*jack_connect_p)(jack_client_t *client, + const char *source_port, + const char *destination_port); +const char *(*jack_port_name_p)(const jack_port_t *port); +int (*jack_port_name_size_p)(void); +jack_ringbuffer_t *(*jack_ringbuffer_create_p)(size_t sz); +void (*jack_ringbuffer_free_p)(jack_ringbuffer_t *rb); +size_t (*jack_ringbuffer_write_p)(jack_ringbuffer_t *rb, + const char *src, + size_t cnt); + + +/** +* Callback for capture through jack +* +* \param nframes Number of frames captured +* +* \param jdata_t Pointer to JackData struct containing port +* and client information +* +* \returns Zero always +*/ +static int JackCapture(jack_nframes_t nframes,void *jdata_t) { int i=0; JackData *jdata=(JackData *)jdata_t; @@ -59,7 +117,15 @@ int JackCapture(jack_nframes_t nframes,void *jdata_t){ return 0; } -int SetupPorts(JackData *jdata){ +/** +* Register and Activate specified ports +* +* \param jdata_t Pointer to JackData struct containing port +* and client information +* +* \returns 0 on Success, 1 on failure +*/ +static int SetupPorts(JackData *jdata) { int i=0; jdata->ports=malloc(sizeof(jack_port_t *)* jdata->nports); @@ -94,7 +160,14 @@ int SetupPorts(JackData *jdata){ return 0; } -int LoadJackLib(void *jack_lib_handle){ +/** +* dlopen libjack and dlsym all needed functions +* +* \param jack_lib_handle Pointer to handle for jack library +* +* \returns 0 on Success, 1 on failure +*/ +static int LoadJackLib(void *jack_lib_handle) { char *error; jack_lib_handle=dlopen("libjack.so",RTLD_LAZY); if(!jack_lib_handle){ @@ -126,6 +199,7 @@ int LoadJackLib(void *jack_lib_handle){ return 0; } + //in case the jack server shuts down //the program should stop recording, //encode the result(if not on the fly) diff --git a/recordmydesktop/src/setbrwindow.c b/recordmydesktop/src/setbrwindow.c index 8c8b973..94c1fa0 100644 --- a/recordmydesktop/src/setbrwindow.c +++ b/recordmydesktop/src/setbrwindow.c @@ -26,7 +26,20 @@ #include <recordmydesktop.h> -void SizePack2_8_16(int *start,int *size,int limit){ + +/** +*Align the recording window to a divisible by 2 pixel start and +*and a size divisible by 16. +* +* \param start x or y of the recording window +* +* \param size width or height of the recording window +* +* \param limit width or height of the Display +* +* \note This is called separately for width and height. +*/ +static void SizePack2_8_16(int *start, int *size, int limit) { int octoffset,hexoffset; //align in two |