From 2cf3c4864635a5761c5a9f45857abeb9ac363dcd Mon Sep 17 00:00:00 2001 From: enselic Date: Sat, 13 Sep 2008 21:35:43 +0000 Subject: include/rmdmacro.h include/rmdtypes.h include/skeleton.h include/recordmydesktop.h: Moved from here src/rmdmacro.h src/rmdtypes.h src/skeleton.h src/recordmydesktop.h: to here. include include/Makefile.am: Removed, no need for a separate include dir. Makefile.am configure.ac src/Makefile.am: Adjusted accordingly. git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@539 f606c939-3180-4ac9-a4b8-4b8779d57d0a --- recordmydesktop/Makefile.am | 5 +- recordmydesktop/configure.ac | 1 - recordmydesktop/include/Makefile.am | 1 - recordmydesktop/include/recordmydesktop.h | 65 ----- recordmydesktop/include/rmdmacro.h | 111 --------- recordmydesktop/include/rmdtypes.h | 387 ------------------------------ recordmydesktop/include/skeleton.h | 77 ------ recordmydesktop/src/Makefile.am | 18 +- recordmydesktop/src/recordmydesktop.h | 65 +++++ recordmydesktop/src/rmdmacro.h | 111 +++++++++ recordmydesktop/src/rmdtypes.h | 387 ++++++++++++++++++++++++++++++ recordmydesktop/src/skeleton.h | 77 ++++++ 12 files changed, 649 insertions(+), 656 deletions(-) delete mode 100644 recordmydesktop/include/Makefile.am delete mode 100644 recordmydesktop/include/recordmydesktop.h delete mode 100644 recordmydesktop/include/rmdmacro.h delete mode 100644 recordmydesktop/include/rmdtypes.h delete mode 100644 recordmydesktop/include/skeleton.h create mode 100644 recordmydesktop/src/recordmydesktop.h create mode 100644 recordmydesktop/src/rmdmacro.h create mode 100644 recordmydesktop/src/rmdtypes.h create mode 100644 recordmydesktop/src/skeleton.h diff --git a/recordmydesktop/Makefile.am b/recordmydesktop/Makefile.am index caee5a1..3920780 100644 --- a/recordmydesktop/Makefile.am +++ b/recordmydesktop/Makefile.am @@ -1,4 +1 @@ -SUBDIRS = src doc include - - - +SUBDIRS = src doc diff --git a/recordmydesktop/configure.ac b/recordmydesktop/configure.ac index 69daf37..903f4a7 100644 --- a/recordmydesktop/configure.ac +++ b/recordmydesktop/configure.ac @@ -131,7 +131,6 @@ AC_FUNC_MALLOC AC_CONFIG_FILES([Makefile src/Makefile - include/Makefile doc/Makefile ]) AC_OUTPUT diff --git a/recordmydesktop/include/Makefile.am b/recordmydesktop/include/Makefile.am deleted file mode 100644 index f675c80..0000000 --- a/recordmydesktop/include/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -noinst_HEADERS = recordmydesktop.h rmdtypes.h rmdmacro.h skeleton.h diff --git a/recordmydesktop/include/recordmydesktop.h b/recordmydesktop/include/recordmydesktop.h deleted file mode 100644 index 3ee6e83..0000000 --- a/recordmydesktop/include/recordmydesktop.h +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 John Varouhakis * -* * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program; if not, write to the Free Software * -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * -* * -* * -* * -* For further information contact me at johnvarouhakis@gmail.com * -******************************************************************************/ - - -#ifndef RECORDMYDESKTOP_H -#define RECORDMYDESKTOP_H 1 - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -//header inclusion is completely fucked up -//I'll fix it, I promise -#include "rmdtypes.h" - -//These are the cache blocks. They need to be accesible in the -//dbuf macros -u_int32_t *yblocks, - *ublocks, - *vblocks; - -#include "rmdmacro.h" - - - -/**Globals*/ -//I've read somewhere that I'll go to hell for using globals... - -//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 -int capture_busy, - encoder_busy; - -#endif - diff --git a/recordmydesktop/include/rmdmacro.h b/recordmydesktop/include/rmdmacro.h deleted file mode 100644 index 453fbea..0000000 --- a/recordmydesktop/include/rmdmacro.h +++ /dev/null @@ -1,111 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 John Varouhakis * -* * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program; if not, write to the Free Software * -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * -* * -* * -* * -* For further information contact me at johnvarouhakis@gmail.com * -******************************************************************************/ - -#ifndef RMDMACRO_H -#define RMDMACRO_H 1 - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#include "rmdtypes.h" - - -//define which 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_32(tmp_val) (((tmp_val)&0x00ff0000)>>16) -#define __GVALUE_32(tmp_val) (((tmp_val)&0x0000ff00)>>8) -#define __BVALUE_32(tmp_val) (((tmp_val)&0x000000ff)) - -#define __R16_MASK 0xf800 -#define __G16_MASK 0x7e0 -#define __B16_MASK 0x1f - -#define __RVALUE_16(tmp_val) ((((tmp_val)&__R16_MASK)>>11)*8) -#define __GVALUE_16(tmp_val) ((((tmp_val)&__G16_MASK)>>5)*4) -#define __BVALUE_16(tmp_val) ((((tmp_val)&__B16_MASK))*8) - -//xfixes pointer data are written as unsigned long -//(even though the server returns CARD32) -//so we need to set the step accordingly to -//avoid problems (amd64 has 8byte ulong) -#define RMD_ULONG_SIZE_T (sizeof(unsigned long)) - -//size of stride when comparing planes(depending on type) -//this is just to avoid thousands of sizeof's -#ifdef HAVE_U_INT64_T - #define COMPARE_STRIDE 8 -#else - #define COMPARE_STRIDE 4 -#endif - -//The width, in bytes, of the blocks -//on which the y,u and v planes are broken. -//These blocks are square. -#define Y_UNIT_WIDTH 0x0010 -#define UV_UNIT_WIDTH 0x0008 - -#ifdef HAVE_LIBASOUND - #define DEFAULT_AUDIO_DEVICE "hw:0,0" -#else - #define DEFAULT_AUDIO_DEVICE "/dev/dsp" -#endif - -#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);\ -};\ - - -#endif diff --git a/recordmydesktop/include/rmdtypes.h b/recordmydesktop/include/rmdtypes.h deleted file mode 100644 index f4099ce..0000000 --- a/recordmydesktop/include/rmdtypes.h +++ /dev/null @@ -1,387 +0,0 @@ -/****************************************************************************** -* recordMyDesktop * -******************************************************************************* -* * -* Copyright (C) 2006,2007,2008 John Varouhakis * -* * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program; if not, write to the Free Software * -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * -* * -* For further information contact me at johnvarouhakis@gmail.com * -******************************************************************************/ - -#ifndef RMDTYPES_H -#define RMDTYPES_H 1 - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_MACHINE_ENDIAN_H - #include -#else - #include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_LIBASOUND - #include -#else - #include - #include -#endif - -#ifdef HAVE_JACK_H - #include - #include - #include -#endif - - -//this type exists only -//for comparing the planes at caching. -//u_int64_t mught not be available everywhere. -//The performance gain comes from casting the unsigned char -//buffers to this type before comparing the two blocks. -//This is made possible by the fact that blocks -//for the Y plane are 16 bytes in width and blocks -//for the U,V planes are 8 bytes in width -#ifdef HAVE_U_INT64_T -typedef u_int64_t cmp_int_t; -#else -typedef u_int32_t cmp_int_t; -#endif - -//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 -}; - -// Boolean type -typedef int boolean; -#define FALSE (0) -#define TRUE (!FALSE) - -// Forward declarations -typedef struct _ProgData ProgData; - -typedef struct _DisplaySpecs{ //this struct holds some basic information - int screen; //about the display,needed mostly for - unsigned int width; //validity checks at startup - unsigned int 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 - 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 -#else - u_int32_t buffsize; -#endif - 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; - 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 -//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 - *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; - -//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; - -#ifdef HAVE_JACK_H -typedef struct _JackData{ - ProgData *pdata; //pointer to prog data - void *jack_lib_handle; //handle for jack library (loaded with dlopen). - 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). - -//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. -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; -#ifdef HAVE_JACK_H - JackData *jdata; -#endif -/**X related info*/ - 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 -/**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_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 -/**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) - char *window_manager; //name of the window manager at program launch - 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 - - pthread_mutex_t pause_mutex; - pthread_mutex_t time_mutex; - -#ifdef HAVE_LIBASOUND - snd_pcm_t *sound_handle; - snd_pcm_uframes_t periodsize; -#else - int sound_handle; - u_int32_t periodsize; -#endif -}; - - -//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. - - -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 -}FrameHeader; - -#endif - diff --git a/recordmydesktop/include/skeleton.h b/recordmydesktop/include/skeleton.h deleted file mode 100644 index 9805cdc..0000000 --- a/recordmydesktop/include/skeleton.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * skeleton.h - * author: Tahseen Mohammad - */ - -#ifndef _SKELETON_H -#define _SKELETON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define SKELETON_VERSION_MAJOR 3 -#define SKELETON_VERSION_MINOR 0 -#define FISHEAD_IDENTIFIER "fishead\0" -#define FISBONE_IDENTIFIER "fisbone\0" -#define FISHEAD_SIZE 64 -#define FISBONE_SIZE 52 -#define FISBONE_MESSAGE_HEADER_OFFSET 44 - -/* fishead_packet holds a fishead header packet. */ -typedef struct { - ogg_uint16_t version_major; /* skeleton version major */ - ogg_uint16_t version_minor; /* skeleton version minor */ - /* Start time of the presentation - * For a new stream presentationtime & basetime is same. */ - ogg_int64_t ptime_n; /* presentation time numerator */ - ogg_int64_t ptime_d; /* presentation time denominator */ - ogg_int64_t btime_n; /* basetime numerator */ - ogg_int64_t btime_d; /* basetime denominator */ - /* will holds the time of origin of the stream, a 20 bit field. */ - unsigned char UTC[20]; -} fishead_packet; - -/* fisbone_packet holds a fisbone header packet. */ -typedef struct { - ogg_uint32_t serial_no; /* serial no of the corresponding stream */ - ogg_uint32_t nr_header_packet; /* number of header packets */ - /* granule rate is the temporal resolution of the logical bitstream */ - ogg_int64_t granule_rate_n; /* granule rate numerator */ - ogg_int64_t granule_rate_d; /* granule rate denominator */ - ogg_int64_t start_granule; /* start granule value */ - ogg_uint32_t preroll; /* preroll */ - unsigned char granule_shift; /* 1 byte value holding the granule shift */ - char *message_header_fields; /* holds all the message header fields */ - /* current total size of the message header fields, for realloc purpose, initially zero */ - ogg_uint32_t current_header_size; -} fisbone_packet; - -extern int write_ogg_page_to_file(ogg_page *og, FILE *out); -extern int add_message_header_field(fisbone_packet *fp, char *header_key, char *header_value); -/* remember to deallocate the returned ogg_packet properly */ -extern int ogg_from_fishead(fishead_packet *fp,ogg_packet *op); -extern int ogg_from_fisbone(fisbone_packet *fp,ogg_packet *op); -extern int fisbone_clear(fisbone_packet *fp); -extern int fishead_from_ogg(ogg_packet *op,fishead_packet *fp); -extern int fisbone_from_ogg(ogg_packet *op,fisbone_packet *fp); -extern int fishead_from_ogg_page(const ogg_page *og,fishead_packet *fp); -extern int fisbone_from_ogg_page(const ogg_page *og,fisbone_packet *fp); -extern int add_fishead_to_stream(ogg_stream_state *os, fishead_packet *fp); -extern int add_fisbone_to_stream(ogg_stream_state *os, fisbone_packet *fp); -extern int add_eos_packet_to_stream(ogg_stream_state *os); -extern int flush_ogg_stream_to_file(ogg_stream_state *os, FILE *out); - -#ifdef __cplusplus -} -#endif - -#endif /* _SKELETON_H */ - - - - - - diff --git a/recordmydesktop/src/Makefile.am b/recordmydesktop/src/Makefile.am index 4c80b7c..c77a83e 100644 --- a/recordmydesktop/src/Makefile.am +++ b/recordmydesktop/src/Makefile.am @@ -36,6 +36,7 @@ recordmydesktop_SOURCES = \ queryextensions.c \ queryextensions.h \ recordmydesktop.c \ + recordmydesktop.h \ rectinsert.c \ rectinsert.h \ register_callbacks.c \ @@ -54,11 +55,14 @@ recordmydesktop_SOURCES = \ rmd_timer.h \ rmdthreads.c \ rmdthreads.h \ + rmdmacro.h \ + rmdtypes.h \ setbrwindow.c \ setbrwindow.h \ shortcuts.c \ shortcuts.h \ skeleton.c \ + skeleton.h \ specsfile.c \ specsfile.h \ update_image.c \ @@ -68,17 +72,14 @@ recordmydesktop_SOURCES = \ wm_check.c \ wm_check.h - -INCLUDES = $(all_includes) -I$(top_srcdir)/include - -recordmydesktop_LDFLAGS = @X_LIBS@ @X_EXTRA_LIBS@ @X_PRE_LIBS@ -recordmydesktop_CFLAGS = -D_THREAD_SAFE -pthread -Wall +recordmydesktop_CPPFLAGS = -D_THREAD_SAFE -pthread -Wall +recordmydesktop_LDFLAGS = @X_LIBS@ @X_EXTRA_LIBS@ @X_PRE_LIBS@ # RectInsert test -TESTS = test-rectinsert +TESTS = test-rectinsert EXTRA_PROGRAMS = test-rectinsert -CLEANFILES = $(EXTRA_PROGRAMS) +CLEANFILES = $(EXTRA_PROGRAMS) test_rectinsert_SOURCES = \ test-rectinsert.c \ @@ -87,7 +88,4 @@ test_rectinsert_SOURCES = \ test-rectinsert-types.h \ rectinsert.c -test_rectinsert_CPPFLAGS = \ - -I$(top_srcdir)/include - test_rectinsert_CFLAGS = -Wall diff --git a/recordmydesktop/src/recordmydesktop.h b/recordmydesktop/src/recordmydesktop.h new file mode 100644 index 0000000..3ee6e83 --- /dev/null +++ b/recordmydesktop/src/recordmydesktop.h @@ -0,0 +1,65 @@ +/****************************************************************************** +* recordMyDesktop * +******************************************************************************* +* * +* Copyright (C) 2006,2007,2008 John Varouhakis * +* * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * +* * +* * +* * +* For further information contact me at johnvarouhakis@gmail.com * +******************************************************************************/ + + +#ifndef RECORDMYDESKTOP_H +#define RECORDMYDESKTOP_H 1 + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +//header inclusion is completely fucked up +//I'll fix it, I promise +#include "rmdtypes.h" + +//These are the cache blocks. They need to be accesible in the +//dbuf macros +u_int32_t *yblocks, + *ublocks, + *vblocks; + +#include "rmdmacro.h" + + + +/**Globals*/ +//I've read somewhere that I'll go to hell for using globals... + +//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 +int capture_busy, + encoder_busy; + +#endif + diff --git a/recordmydesktop/src/rmdmacro.h b/recordmydesktop/src/rmdmacro.h new file mode 100644 index 0000000..453fbea --- /dev/null +++ b/recordmydesktop/src/rmdmacro.h @@ -0,0 +1,111 @@ +/****************************************************************************** +* recordMyDesktop * +******************************************************************************* +* * +* Copyright (C) 2006,2007,2008 John Varouhakis * +* * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * +* * +* * +* * +* For further information contact me at johnvarouhakis@gmail.com * +******************************************************************************/ + +#ifndef RMDMACRO_H +#define RMDMACRO_H 1 + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "rmdtypes.h" + + +//define which 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_32(tmp_val) (((tmp_val)&0x00ff0000)>>16) +#define __GVALUE_32(tmp_val) (((tmp_val)&0x0000ff00)>>8) +#define __BVALUE_32(tmp_val) (((tmp_val)&0x000000ff)) + +#define __R16_MASK 0xf800 +#define __G16_MASK 0x7e0 +#define __B16_MASK 0x1f + +#define __RVALUE_16(tmp_val) ((((tmp_val)&__R16_MASK)>>11)*8) +#define __GVALUE_16(tmp_val) ((((tmp_val)&__G16_MASK)>>5)*4) +#define __BVALUE_16(tmp_val) ((((tmp_val)&__B16_MASK))*8) + +//xfixes pointer data are written as unsigned long +//(even though the server returns CARD32) +//so we need to set the step accordingly to +//avoid problems (amd64 has 8byte ulong) +#define RMD_ULONG_SIZE_T (sizeof(unsigned long)) + +//size of stride when comparing planes(depending on type) +//this is just to avoid thousands of sizeof's +#ifdef HAVE_U_INT64_T + #define COMPARE_STRIDE 8 +#else + #define COMPARE_STRIDE 4 +#endif + +//The width, in bytes, of the blocks +//on which the y,u and v planes are broken. +//These blocks are square. +#define Y_UNIT_WIDTH 0x0010 +#define UV_UNIT_WIDTH 0x0008 + +#ifdef HAVE_LIBASOUND + #define DEFAULT_AUDIO_DEVICE "hw:0,0" +#else + #define DEFAULT_AUDIO_DEVICE "/dev/dsp" +#endif + +#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);\ +};\ + + +#endif diff --git a/recordmydesktop/src/rmdtypes.h b/recordmydesktop/src/rmdtypes.h new file mode 100644 index 0000000..f4099ce --- /dev/null +++ b/recordmydesktop/src/rmdtypes.h @@ -0,0 +1,387 @@ +/****************************************************************************** +* recordMyDesktop * +******************************************************************************* +* * +* Copyright (C) 2006,2007,2008 John Varouhakis * +* * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * +* * +* For further information contact me at johnvarouhakis@gmail.com * +******************************************************************************/ + +#ifndef RMDTYPES_H +#define RMDTYPES_H 1 + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_MACHINE_ENDIAN_H + #include +#else + #include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LIBASOUND + #include +#else + #include + #include +#endif + +#ifdef HAVE_JACK_H + #include + #include + #include +#endif + + +//this type exists only +//for comparing the planes at caching. +//u_int64_t mught not be available everywhere. +//The performance gain comes from casting the unsigned char +//buffers to this type before comparing the two blocks. +//This is made possible by the fact that blocks +//for the Y plane are 16 bytes in width and blocks +//for the U,V planes are 8 bytes in width +#ifdef HAVE_U_INT64_T +typedef u_int64_t cmp_int_t; +#else +typedef u_int32_t cmp_int_t; +#endif + +//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 +}; + +// Boolean type +typedef int boolean; +#define FALSE (0) +#define TRUE (!FALSE) + +// Forward declarations +typedef struct _ProgData ProgData; + +typedef struct _DisplaySpecs{ //this struct holds some basic information + int screen; //about the display,needed mostly for + unsigned int width; //validity checks at startup + unsigned int 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 + 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 +#else + u_int32_t buffsize; +#endif + 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; + 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 +//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 + *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; + +//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; + +#ifdef HAVE_JACK_H +typedef struct _JackData{ + ProgData *pdata; //pointer to prog data + void *jack_lib_handle; //handle for jack library (loaded with dlopen). + 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). + +//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. +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; +#ifdef HAVE_JACK_H + JackData *jdata; +#endif +/**X related info*/ + 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 +/**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_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 +/**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) + char *window_manager; //name of the window manager at program launch + 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 + + pthread_mutex_t pause_mutex; + pthread_mutex_t time_mutex; + +#ifdef HAVE_LIBASOUND + snd_pcm_t *sound_handle; + snd_pcm_uframes_t periodsize; +#else + int sound_handle; + u_int32_t periodsize; +#endif +}; + + +//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. + + +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 +}FrameHeader; + +#endif + diff --git a/recordmydesktop/src/skeleton.h b/recordmydesktop/src/skeleton.h new file mode 100644 index 0000000..9805cdc --- /dev/null +++ b/recordmydesktop/src/skeleton.h @@ -0,0 +1,77 @@ +/* + * skeleton.h + * author: Tahseen Mohammad + */ + +#ifndef _SKELETON_H +#define _SKELETON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define SKELETON_VERSION_MAJOR 3 +#define SKELETON_VERSION_MINOR 0 +#define FISHEAD_IDENTIFIER "fishead\0" +#define FISBONE_IDENTIFIER "fisbone\0" +#define FISHEAD_SIZE 64 +#define FISBONE_SIZE 52 +#define FISBONE_MESSAGE_HEADER_OFFSET 44 + +/* fishead_packet holds a fishead header packet. */ +typedef struct { + ogg_uint16_t version_major; /* skeleton version major */ + ogg_uint16_t version_minor; /* skeleton version minor */ + /* Start time of the presentation + * For a new stream presentationtime & basetime is same. */ + ogg_int64_t ptime_n; /* presentation time numerator */ + ogg_int64_t ptime_d; /* presentation time denominator */ + ogg_int64_t btime_n; /* basetime numerator */ + ogg_int64_t btime_d; /* basetime denominator */ + /* will holds the time of origin of the stream, a 20 bit field. */ + unsigned char UTC[20]; +} fishead_packet; + +/* fisbone_packet holds a fisbone header packet. */ +typedef struct { + ogg_uint32_t serial_no; /* serial no of the corresponding stream */ + ogg_uint32_t nr_header_packet; /* number of header packets */ + /* granule rate is the temporal resolution of the logical bitstream */ + ogg_int64_t granule_rate_n; /* granule rate numerator */ + ogg_int64_t granule_rate_d; /* granule rate denominator */ + ogg_int64_t start_granule; /* start granule value */ + ogg_uint32_t preroll; /* preroll */ + unsigned char granule_shift; /* 1 byte value holding the granule shift */ + char *message_header_fields; /* holds all the message header fields */ + /* current total size of the message header fields, for realloc purpose, initially zero */ + ogg_uint32_t current_header_size; +} fisbone_packet; + +extern int write_ogg_page_to_file(ogg_page *og, FILE *out); +extern int add_message_header_field(fisbone_packet *fp, char *header_key, char *header_value); +/* remember to deallocate the returned ogg_packet properly */ +extern int ogg_from_fishead(fishead_packet *fp,ogg_packet *op); +extern int ogg_from_fisbone(fisbone_packet *fp,ogg_packet *op); +extern int fisbone_clear(fisbone_packet *fp); +extern int fishead_from_ogg(ogg_packet *op,fishead_packet *fp); +extern int fisbone_from_ogg(ogg_packet *op,fisbone_packet *fp); +extern int fishead_from_ogg_page(const ogg_page *og,fishead_packet *fp); +extern int fisbone_from_ogg_page(const ogg_page *og,fisbone_packet *fp); +extern int add_fishead_to_stream(ogg_stream_state *os, fishead_packet *fp); +extern int add_fisbone_to_stream(ogg_stream_state *os, fisbone_packet *fp); +extern int add_eos_packet_to_stream(ogg_stream_state *os); +extern int flush_ogg_stream_to_file(ogg_stream_state *os, FILE *out); + +#ifdef __cplusplus +} +#endif + +#endif /* _SKELETON_H */ + + + + + + -- cgit v1.2.3