From 7fa9f0dcf8f45b735f76c49dff5a4868abbc9bac Mon Sep 17 00:00:00 2001 From: iovar Date: Thu, 4 Jan 2007 09:45:09 +0000 Subject: header has been broken to types,func and macros parts for easier maintainance git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@253 f606c939-3180-4ac9-a4b8-4b8779d57d0a --- recordmydesktop/include/recordmydesktop.h | 1078 +---------------------------- 1 file changed, 3 insertions(+), 1075 deletions(-) (limited to 'recordmydesktop/include/recordmydesktop.h') diff --git a/recordmydesktop/include/recordmydesktop.h b/recordmydesktop/include/recordmydesktop.h index d684e8f..ed522db 100644 --- a/recordmydesktop/include/recordmydesktop.h +++ b/recordmydesktop/include/recordmydesktop.h @@ -32,288 +32,11 @@ #include #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "rmdtypes.h" +#include "rmdmacro.h" +#include "rmdfunc.h" -//define whcih way we are reading a pixmap -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define __ABYTE 3 -#define __RBYTE 2 -#define __GBYTE 1 -#define __BBYTE 0 - -#elif __BYTE_ORDER == __BIG_ENDIAN - -#define __ABYTE 0 -#define __RBYTE 1 -#define __GBYTE 2 -#define __BBYTE 3 - -#else -#error Only little-endian and big-endian systems are supported -#endif - -#define __RVALUE(tmp_val) (((tmp_val)&0x00ff0000)>>16) -#define __GVALUE(tmp_val) (((tmp_val)&0x0000ff00)>>8) -#define __BVALUE(tmp_val) (((tmp_val)&0x000000ff)) - -//500 mb file size -#define CACHE_FILE_SIZE_LIMIT (500*1<<20) - - - -/**Structs*/ - -typedef struct _DisplaySpecs{ //this struct holds some basic information - int screen; //about the display,needed mostly for - uint width; //validity checks at startup - uint height; - Window root; - Visual *visual; - GC gc; - int depth; - unsigned long bpixel; - unsigned long wpixel; -}DisplaySpecs; - -typedef struct _WGeometry{ //basic geometry of a window or area - int x; - int y; - int width; - int height; -}WGeometry; - -typedef struct _RectArea{ //an area that has been damaged gets stored - WGeometry geom; //in a list comprised of structs of this type - struct _RectArea *prev,*next; -}RectArea; - -typedef struct _BRWindow{ //'basic recorded window' specs - WGeometry geom; //window attributes - WGeometry rgeom; //part of window that is recorded - 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 DEFAULT_ARGS macro 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 - int quietmode; //no messages to stderr,stdout - 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(default according to alsa or oss) - snd_pcm_uframes_t buffsize;//buffer size(in frames) for sound capturing - int nosound; //do not record sound(default 0) - int noshared; //do not use shared memory extension(default 1) - int nocondshared; //do not use shared memory on large image aquititions - int nowmcheck; //do not check if there's a 3d comp window manager - //(which changes full-shots and with-shared to 1) - int shared_thres; //threshold to use shared memory - int full_shots; //do not poll damage, take full screenshots - int no_quick_subsample;//average pixels in chroma planes - int v_bitrate,v_quality,s_quality;//video bitrate,video-sound quality - int dropframes; //option for theora encoder - int encOnTheFly; //encode while recording, no caching(default 0) - char *workdir; //directory to be used for cache files(default $HOME) - int zerocompression;//image data are always flushed uncompressed - int overwrite;//overwite a previously existing file(do not add a .number postfix) -}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 -//theora data - 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; -//these should be 0, since area is quantized -//before input - int x_offset, - y_offset; -//our file - 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 - *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; - -//sound buffer -//sound keeps coming so we que it in this list -//which we then traverse -typedef struct _SndBuffer{ - signed char *data; - struct _SndBuffer *next; -}SndBuffer; - -//this structure holds any data related to the program -//It's usage is mostly to be given as an argument to the -//threads,so they will have access to the program data, avoiding -//at the same time usage of any globals. -typedef struct _ProgData{ - ProgArgs args;//the program arguments - DisplaySpecs specs;//Display specific information - BRWindow brwin;//recording window - Display *dpy;//curtrent display - char *window_manager;//name of the window manager at program launch - XImage *image;//the image that holds the current full screenshot - XImage *shimage;//the image that holds the current full screenshot(shared memory) - unsigned char *dummy_pointer;//a dummy pointer to be drawn in every frame - //data is casted to unsigned for later use in YUV buffer - int dummy_p_size;//initially 16x16,always square - unsigned char npxl;//this is the no pixel convention when drawing the dummy pointer - char *datamain,//the data of image - *datash,//the data of shimage - *datatemp;//buffer for the temporary image,which will be - //preallocated in case shared memory is not used. - RectArea *rect_root[2];//the interchanging list roots for storing the changed regions - int list_selector,//selector for the above - damage_event,//damage event base code - damage_error,//damage error base code - running; - SndBuffer *sound_buffer; - EncData *enc_data; - CacheData *cache_data; - int hard_pause;//if sound device doesn't support pause - //we have to close and reopen - int avd;//syncronization among audio and video - unsigned int periodtime, - frametime; - pthread_mutex_t list_mutex[2],//mutexes for concurrency protection of the lists - sound_buffer_mutex, - libogg_mutex,//libogg is not thread safe, -// libtheora_mutex,//same for libtheora -// libvorbis_mutex,//and libvorbis. - 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_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_buffer_ready,//sound encoding finished - 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 - int th_encoding_clean,//these indicate a wait condition on the above cond vars - v_encoding_clean; - int v_enc_thread_waiting, - th_enc_thread_waiting; - snd_pcm_t *sound_handle; - snd_pcm_uframes_t periodsize; -}ProgData; - - -//This is the header of every frame. -//Reconstruction will be correct only if made on -//the same platform. - -//We need the total number of blocks -//for each plane. - -//The number of the frame compared to the -//number of time expirations at the time of -//caching, will enable us to make up for lost frames. - -//default 4+4+2+2+2=14!bad! -//me add pad, make god of 2 happy! -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_int16_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 - u_int16_t pad;//always zero - -}FrameHeader; - -//The frame after retrieval. -//Based on the Header information -//we can read the correct amount of bytes. - - -typedef struct _CachedFrame{ - FrameHeader *header; - unsigned char *YBlocks;//identifying number on the grid, starting at top left - unsigned char *UBlocks;// >> >> - unsigned char *VBlocks;// >> >> - unsigned char *YData;//pointer to data for the blocks that have changed, - unsigned char *UData;//which have to be remapped on the buffer when reading - unsigned char *VData; -}CachedFrame; - /**Globals*/ //I've read somewhere that I'll go to hell for using globals... @@ -333,801 +56,6 @@ int capture_busy, encoder_busy; -/**Macros*/ - -#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;\ - }\ -} - -#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 DEFAULT_ARGS(args){\ - (args)->delay=0;\ - if(getenv("DISPLAY")!=NULL){\ - (args)->display=(char *)malloc(strlen(getenv("DISPLAY"))+1);\ - strcpy((args)->display,getenv("DISPLAY"));\ - }\ - else\ - (args)->display=NULL;\ - (args)->windowid=\ - (args)->x=\ - (args)->y=\ - (args)->width=\ - (args)->height=\ - (args)->quietmode=\ - (args)->nosound=\ - (args)->full_shots=\ - (args)->encOnTheFly=\ - (args)->zerocompression=\ - (args)->nowmcheck=\ - (args)->dropframes=\ - (args)->overwrite=\ - (args)->nocondshared=0;\ - (args)->no_quick_subsample=\ - (args)->noshared=1;\ - (args)->filename=(char *)malloc(8);\ - strcpy((args)->filename,"out.ogg");\ - (args)->cursor_color=1;\ - (args)->shared_thres=75;\ - (args)->have_dummy_cursor=0;\ - (args)->xfixes_cursor=1;\ - (args)->device=(char *)malloc(8);\ - strcpy((args)->device,"hw:0,0");\ - (args)->fps=15;\ - (args)->channels=1;\ - (args)->frequency=22050;\ - (args)->buffsize=4096;\ - (args)->v_bitrate=45000;\ - (args)->v_quality=63;\ - (args)->s_quality=10;\ - (args)->workdir=(char *)malloc(5);\ - strcpy((args)->workdir,"/tmp");\ -} - -#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);\ -} - -#define AVG_4_PIXELS(data_array,width_img,k_tm,i_tm,offset)\ - ((data_array[(k_tm*width_img+i_tm)*4+offset]+data_array[((k_tm-1)*width_img+i_tm)*4+offset]\ - +data_array[(k_tm*width_img+i_tm-1)*4+offset]+data_array[((k_tm-1)*width_img+i_tm-1)*4+offset])/4) - -#define UPDATE_YUV_BUFFER_SH(yuv,data,x_tm,y_tm,width_tm,height_tm){\ - int k,i;\ - register unsigned int t_val;\ - register unsigned int *datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width;\ - register unsigned char *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\ - *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,\ - *_yr=Yr,*_yg=Yg,*_yb=Yb,\ - *_ur=Ur,*_ug=Ug,*_ub=Ub,\ - *_vr=Vr,*_vg=Vg,*_vb=Vb;\ -\ - for(k=0;ky_width-width_tm;\ - datapi+=yuv->y_width-width_tm;\ - }\ - datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width;\ - for(k=0;ky_width-width_tm)/2;\ - yuv_v+=(yuv->y_width-width_tm)/2;\ - datapi+=(2*yuv->y_width-width_tm);\ - }\ -} - -#define UPDATE_YUV_BUFFER_SH_AVG(yuv,data,x_tm,y_tm,width_tm,height_tm){\ - int k,i;\ - register unsigned int t_val,t1,t2,t3,t4;\ - register unsigned int *datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width,\ - *datapi_next=(unsigned int*)data+x_tm+(y_tm+1)*yuv->y_width;\ - register unsigned char *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\ - *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,\ - *_yr=Yr,*_yg=Yg,*_yb=Yb,\ - *_ur=Ur,*_ug=Ug,*_ub=Ub,\ - *_vr=Vr,*_vg=Vg,*_vb=Vb;\ -\ - for(k=0;ky_width-width_tm;\ - datapi+=yuv->y_width-width_tm;\ - }\ - datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width;\ - for(k=0;ky_width-width_tm)/2;\ - yuv_v+=(yuv->y_width-width_tm)/2;\ - datapi+=(2*yuv->y_width-width_tm);\ - datapi_next+=(2*yuv->y_width-width_tm);\ - }\ -} - - - -#define UPDATE_YUV_BUFFER_IM(yuv,data,x_tm,y_tm,width_tm,height_tm){\ - int k,i;\ - register unsigned int t_val;\ - register unsigned int *datapi=(unsigned int*)data;\ - register unsigned char *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\ - *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,\ - *_yr=Yr,*_yg=Yg,*_yb=Yb,\ - *_ur=Ur,*_ug=Ug,*_ub=Ub,\ - *_vr=Vr,*_vg=Vg,*_vb=Vb;\ -\ - for(k=0;ky_width-width_tm;\ - }\ - datapi=(unsigned int*)data;\ - for(k=0;ky_width-width_tm)/2;\ - yuv_v+=(yuv->y_width-width_tm)/2;\ - datapi+=width_tm;\ - }\ -} - -#define UPDATE_YUV_BUFFER_IM_AVG(yuv,data,x_tm,y_tm,width_tm,height_tm){\ - int k,i;\ - register unsigned int t_val,t1,t2,t3,t4;\ - register unsigned int *datapi=(unsigned int*)data,\ - *datapi_next=(unsigned int*)data+width_tm;\ - register unsigned char *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\ - *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,\ - *_yr=Yr,*_yg=Yg,*_yb=Yb,\ - *_ur=Ur,*_ug=Ug,*_ub=Ub,\ - *_vr=Vr,*_vg=Vg,*_vb=Vb;\ -\ - for(k=0;ky_width-width_tm;\ - }\ - datapi=(unsigned int*)data;\ - for(k=0;ky_width-width_tm)/2;\ - yuv_v+=(yuv->y_width-width_tm)/2;\ - datapi+=width_tm;\ - datapi_next+=width_tm;\ - }\ -} - - - -#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;ky[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;\ - int x_2=x_tm/2,y_2=y_tm/2,y_width_2=(yuv)->y_width/2;\ - for(k=0;ky[x_tm+i+(k+y_tm)*(yuv)->y_width]=Yr[data_tm[(j*4)+__RBYTE]] + Yg[data_tm[(j*4)+__GBYTE]] + Yb[data_tm[(j*4)+__BBYTE]];\ - if((k%2)&&(i%2)){\ - yuv->u[x_2+i/2+(k/2+y_2)*y_width_2]=Ur[data_tm[(k*width_tm+i)*4+__RBYTE]] + Ug[data_tm[(k*width_tm+i)*4+__GBYTE]] + Ub[data_tm[(k*width_tm+i)*4+__BBYTE]];\ - yuv->v[x_2+i/2+(k/2+y_2)*y_width_2]=Vr[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]] ;\ - }\ - }\ - j++;\ - }\ - j+=16-width_tm;\ - }\ -} - - -#define I16TOA(number,buffer){\ - int t_num=(number),__k=0,__i=0;\ - char *t_buf=malloc(8);\ - t_num=t_num&((2<<15)-1);\ - while(t_num>0){\ - int digit=t_num%10;\ - t_buf[__k]=digit+48;\ - t_num-=digit;\ - t_num/=10;\ - __k++;\ - }\ - while(__k>0)\ - (buffer)[__i++]=t_buf[--__k];\ - (buffer)[__i]='\0';\ - free(t_buf);\ -};\ - -#define INIT_FRAME(frame_t,fheader_t,yuv_t){\ - (frame_t)->header=(fheader_t);\ - (frame_t)->YBlocks=malloc(256);\ - (frame_t)->UBlocks=malloc(64);\ - (frame_t)->VBlocks=malloc(64);\ - (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);\ -}; - -#define CLEAR_FRAME(frame_t){\ - free((frame_t)->YBlocks);\ - free((frame_t)->UBlocks);\ - free((frame_t)->VBlocks);\ - free((frame_t)->YData);\ - free((frame_t)->UData);\ - free((frame_t)->VData);\ -}; - -/**Function prototypes*/ - -/** -* Loop calling XNextEvent.Retrieve and place on -* list damage events that arive, create damage for new windows. -* \param pdata ProgData struct containing all program data -*/ -void *PollDamage(ProgData *pdata); - -/** -* Retrieve frame form xserver, and transform to a yuv buffer, -* either directly(full shots) or by calling UpdateImage. -* \param pdata ProgData struct containing all program data -*/ -void *GetFrame(ProgData *pdata); - -/** -* feed a yuv buffer to the theora encoder and submit outcome to -* the ogg stream. -* \param pdata ProgData struct containing all program data -*/ -void *EncodeImageBuffer(ProgData *pdata); - -/** -* Query theora and vorbis streams for ready packages and -* flush them on the disk -* \param pdata ProgData struct containing all program data -*/ -void *FlushToOgg(ProgData *pdata); - -/** -* Clean up a list of areas marked for update. -* \param root Root entry of the list -*/ -void ClearList(RectArea **root); - -/** -* Insert a new rectangle on the list, making sure it doesn't overlap -* with the existing ones -* \param root Root entry of the list -* -* \param wgeom New area to be inserted -* -* \returns Number of insertions during operation -* -* \note This function is reentrant and recursive. The number -* of insertions takes this into account. -*/ -int RectInsert(RectArea **root,WGeometry *wgeom); - -/** -* 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 -* -*/ -int CollideRects(WGeometry *wgeom1,WGeometry *wgeom2,WGeometry **wgeom_return,int *ngeoms); - -/** -* Broadcast time condition variable, increment frame count. -* -* \param signum Number of signal received(unused, always SIGALRM) -* -*/ -void SetExpired(int signum); - -/** -* Set up all callbacks and signal handlers -* \param pdata ProgData struct containing all program data -*/ -void RegisterCallbacks(ProgArgs *args); - -/** -* Retrieve and apply all changes, if xdamage is used. -* -* \param dpy Connection to the server -* -* \param yuv yuv_buffer that is to be modified -* -* \param yuv_mutex lock on the buffer -* -* \param specs DisplaySpecs struct with information about the display to be recorded -* -* \param root Root entry of the list with damaged areas -* -* \param brwin BRWindow struct contaning the recording window specs -* -* \param enc Encoding options -* -* \param datatemp Buffer for pixel data to be retrieved before placed on the yuv buffer -* -* \param noshmem don't use MIT_Shm extension -* -* \param no_quick_subsample Don't do quick subsampling -* -*/ -void UpdateImage(Display * dpy, - yuv_buffer *yuv, - pthread_mutex_t *yuv_mutex, - DisplaySpecs *specs, - RectArea **root, - BRWindow *brwin, - EncData *enc, - char *datatemp, - int noshmem, - int no_quick_subsample); - -/** -* Rerieve pixmap data from xserver -* -* \param dpy Connection to the server -* -* \param root root window of the display -* -* \param data (preallocated)buffer to place the data -* -* \param x x position of the screenshot -* -* \param y y position of the screenshot -* -* \param x x position of the screenshot -* -* \param width width of the screenshot -* -* \param height height position of the screenshot -* -* \param x x position of the screenshot -* -* \returns 0 on Success 1 on Failure -*/ -int GetZPixmap(Display *dpy,Window root,char *data,int x,int y,int width,int height); - -/** -* Fill ProgArgs struct with arguments entered at execution -* -* \param argc argc as entered from main -* -* \param argv argv as entered from main -* -* \param arg_return ProgArgs struct to be filled with the options -* -* \returns 0 on Success 1 on Failure -*/ -int ParseArgs(int argc,char **argv,ProgArgs *arg_return); - -/** -* Check if needed extensions are present -* -* \param dpy Connection to the server -* -* \param args ProgArgs struct containing the user-set options -* -* \param damage_event gets filled with damage event number -* -* \param damage_error gets filled with damage error number -* -* \note Can be an exit point if extensions are not found -*/ -void QueryExtensions(Display *dpy,ProgArgs *args,int *damage_event,int *damage_error); - -/** -* Check and align window size -* -* \param dpy Connection to the server -* -* \param brwin BRWindow struct contaning the initial and final window -* -* \param specs DisplaySpecs struct with information about the display to be recorded -* -* \param args ProgArgs struct containing the user-set options -* -* \returns 0 on Success 1 on Failure -*/ -int SetBRWindow(Display *dpy,BRWindow *brwin,DisplaySpecs *specs,ProgArgs *args); - -/** -* Create an array containing the data for the dummy pointer -* -* \param specs DisplaySpecs struct with information about the display to be recorded -* -* \param size Pointer size, always square, always 16.(exists only for the possibility to create -* more dummy cursors) -* \param color 0 white, 1 black -* -* \param type Always 0.(exists only for the possibility to create -* more dummy cursors) -* -* \param npxl Return of pixel value that denotes non-drawing, while applying the cursor -* on the target image -* -* \returns Pointer to pixel data of the cursor -*/ -unsigned char *MakeDummyPointer(DisplaySpecs *specs,int size,int color,int type,unsigned char *npxl); - -/** -* Sound capturing thread. Data are placed on a list to be picked up by other threads. -* -* \param pdata ProgData struct containing all program data -*/ -void *CaptureSound(ProgData *pdata); - -/** -* Sound encoding thread. Picks up data from the buffer queue , encodes and places them -* on the vorbis stream. -* -* \param pdata ProgData struct containing all program data -*/ -void *EncodeSoundBuffer(ProgData *pdata); - -/** -* Try to open sound device, with the desired parameters, -* and place the obtained ones on their place -* -* \param pcm_dev name of the device -* -* \param channels desired number of channels(gets modified with the acieved value) -* -* \param frequency desired frequency(gets modified with the acieved value) -* -* \param buffsize Size of buffer -* -* \param periodsize Size of a period(can be NULL) -* -* \param periodtime Duration of a period(can be NULL) -* -* \param hardpause Set to 1 when the device has to be stopped during pause -* and to 0 when it supports pausing -* (can be NULL) -* -* \returns snd_pcm_t handle on success, NULL on failure -*/ -snd_pcm_t *OpenDev( const char *pcm_dev, - unsigned int *channels, - unsigned int *frequency, - snd_pcm_uframes_t *buffsize, - snd_pcm_uframes_t *periodsize, - unsigned int *periodtime, - int *hardpause); -/** -* Initialize theora,vorbis encoders, and their respective ogg streams. -* -* \param pdata ProgData struct containing all program data -* -* \param enc_data_t Encoding options -* -* \param buffer_ready when 1, the yuv buffer must be preallocated -* when 0 InitEncoder will alocate a new one -* -*/ -void InitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready); - -/** -* Fill Yr,Yg,Yb,Ur,Ug.Ub,Vr,Vg,Vb arrays(globals) with values. -*/ -void MakeMatrices(); -/** -*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. -*/ -void SizePack2_8_16(int *start,int *size,int limit); - -/** -* Image caching thread. Copies the yuv buffer, compares with the last one and -* caches the result. -* -* \param pdata ProgData struct containing all program data -* -*/ -void *CacheImageBuffer(ProgData *pdata); - -/** -* Initializes paths and everything else needed to start caching -* -* \param pdata ProgData struct containing all program data -* -* \param enc_data_t Encoding options -* -* \param cache_data_t Caching options -* -*/ -void InitCacheData(ProgData *pdata,EncData *enc_data_t,CacheData *cache_data_t); - -/** -* Sound caching thread. Simply writes the pcm buffers on disk -* -* \param pdata ProgData struct containing all program data -* -*/ -void *CacheSoundBuffer(ProgData *pdata); - -/** -* Cache loading and processing thread -* -* \param pdata ProgData struct containing all program data -* -*/ -void *LoadCache(ProgData *pdata); - -/** -* As EncodeImageBuffer, only with the assumption that this is not a thread on it's own -* -* \param pdata ProgData struct containing all program data -* -*/ -void SyncEncodeImageBuffer(ProgData *pdata); - -/** -* Stop the timer -*/ -void CancelTimer(void); - -/** -* As EncodeSoundBuffer, only with the assumption that this is not a thread on it's own -* -* \param pdata ProgData struct containing all program data -* -*/ -void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff); - -/** -*Check current running window manager. -* -* \param dpy Connection to the server -* -* \param root root window of the display -* -* \returns Window manager name -*/ -char *rmdWMCheck(Display *dpy,Window root); - -/** -*Construct an number postfixed name -* -* \param name base name -* -* \param newname modified name -* -* \n number to be used as a postfix -* -*/ -void CacheFileN(char *name,char **newname,int n); - -/** -* Change file pointer to a new file while writting -* (file name is incremented with CacheFileN) -* -* \param name base file name -* -* \param n number to be used as a postfix -* -* \param fp File pointer if compression is used(must be NULL otherwise) -* -* \param ucfp File pointer if compression is NOT used(must be NULL otherwise) -* -* \returns 0 on Success 1 on Failure -*/ -int SwapCacheFilesWrite(char *name,int n,gzFile **fp,FILE **ucfp); - -/** -* Change file pointer to a new file while reading -* (file name is incremented with CacheFileN) -* -* \param name base file name -* -* \param n number to be used as a postfix -* -* \param fp File pointer if compression is used(must be NULL otherwise) -* -* \param ucfp File pointer if compression is NOT used(must be NULL otherwise) -* -* \returns 0 on Success 1 on Failure -*/ -int SwapCacheFilesRead(char *name,int n,gzFile **fp,FILE **ucfp); -/** -* Delete all cache files -* -* \param cache_data_t Caching options(file names etc.) -* -* \returns 0 if all files and folders where deleted, 1 otherwise -*/ -int PurgeCache(CacheData *cache_data_t,int sound); #endif -- cgit v1.2.1