1 /****************************************************************************** 2 * recordMyDesktop * 3 ******************************************************************************* 4 * * 5 * Copyright (C) 2006,2007,2008 John Varouhakis * 6 * * 7 * * 8 * This program is free software; you can redistribute it and/or modify * 9 * it under the terms of the GNU General Public License as published by * 10 * the Free Software Foundation; either version 2 of the License, or * 11 * (at your option) any later version. * 12 * * 13 * This program is distributed in the hope that it will be useful, * 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 * GNU General Public License for more details. * 17 * * 18 * You should have received a copy of the GNU General Public License * 19 * along with this program; if not, write to the Free Software * 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 21 * * 22 * For further information contact me at johnvarouhakis@gmail.com * 23 ******************************************************************************/ 24 25 #ifndef RMDTYPES_H 26 #define RMDTYPES_H 1 27 28 #include "config.h" 29 30 #include <stdio.h> 31 #include <pthread.h> 32 #include <zlib.h> 33 #include <X11/Xlib.h> 34 #include <theora/theora.h> 35 #include <vorbis/codec.h> 36 #include <vorbis/vorbisenc.h> 37 #include <ogg/ogg.h> 38 39 #ifdef HAVE_LIBASOUND 40 #include <alsa/asoundlib.h> 41 42 #define DEFAULT_AUDIO_DEVICE "hw:0,0" 43 #else 44 #include <sys/ioctl.h> 45 #include <sys/soundcard.h> 46 47 #define DEFAULT_AUDIO_DEVICE "/dev/dsp" 48 #endif 49 50 #ifdef HAVE_LIBJACK 51 #include <jack/jack.h> 52 #include <jack/ringbuffer.h> 53 #endif 54 55 56 //this type exists only 57 //for comparing the planes at caching. 58 //u_int64_t mught not be available everywhere. 59 //The performance gain comes from casting the unsigned char 60 //buffers to this type before comparing the two blocks. 61 //This is made possible by the fact that blocks 62 //for the Y plane are 16 bytes in width and blocks 63 //for the U,V planes are 8 bytes in width 64 #ifdef HAVE_U_INT64_T 65 typedef u_int64_t cmp_int_t; 66 #else 67 typedef u_int32_t cmp_int_t; 68 #endif 69 70 //type of pixel proccessing for the Cb,Cr planes 71 //when converting from full rgb to 4:2:2 Ycbcr 72 enum{ 73 __PXL_DISCARD, //only select 1 pixel in every block of four 74 __PXL_AVERAGE //calculate the average of all four pixels 75 }; 76 77 // Boolean type 78 typedef int boolean; 79 #ifndef FALSE 80 #define FALSE (0) 81 #endif 82 #ifndef TRUE 83 #define TRUE (!FALSE) 84 #endif 85 86 // Forward declarations 87 typedef struct _ProgData ProgData; 88 89 typedef struct _DisplaySpecs{ //this struct holds some basic information 90 int screen; //about the display,needed mostly for 91 unsigned int width, height; //validity checks at startup 92 Window root; 93 Visual *visual; 94 GC gc; 95 int depth; 96 }DisplaySpecs; 97 98 typedef struct _RectArea{ //an area that has been damaged gets stored 99 XRectangle rect; //in a list comprised of structs of this type 100 struct _RectArea *prev,*next; 101 }RectArea; 102 103 typedef struct _BRWindow{ //'basic recorded window' specs 104 XRectangle rect; //window attributes 105 XRectangle rrect; //part of window that is recorded 106 int nbytes; //size of zpixmap when screenshoting 107 Window windowid; //id 108 }BRWindow; 109 110 //defaults in the following comment lines may be out of sync with reality 111 //check the SetupDefaultArgs() function further bellow 112 typedef struct _ProgArgs{ 113 int delay; //start up delay 114 Window windowid; //window to record(default root) 115 char *display; //display to connect(default :0) 116 int x,y; //x,y offset(default 0,0) 117 unsigned int width,height; //defaults to window width and height 118 char *filename; //output file(default out.[ogg|*]) 119 int cursor_color; //black or white=>1 or 0 120 int have_dummy_cursor; //disable/enable drawing of the dummy cursor 121 int xfixes_cursor; //disable/enable drawing of a cursor obtained 122 //through the xfixes extension 123 float fps; //desired framerate(default 15) 124 unsigned int frequency; //desired frequency (default 22050) 125 unsigned int channels; //no of channels(default 2) 126 char *device; //default sound device 127 #ifdef HAVE_LIBASOUND 128 snd_pcm_uframes_t buffsize; //buffer size(in frames) for sound capturing 129 #else 130 u_int32_t buffsize; 131 #endif 132 const char* rescue_path; 133 int nosound; //do not record sound(default 0) 134 int noshared; //do not use shared memory extension(default 0) 135 int nowmcheck; //do not check if there's a 3d comp window manager 136 //(which changes full-shots and with-shared to 1) 137 int full_shots; //do not poll damage, take full screenshots 138 int follow_mouse; //capture area follows the mouse(fullshots auto enabled) 139 int no_encode; //do not encode or delete the temporary files(debug opt) 140 int no_quick_subsample; //average pixels in chroma planes 141 int v_bitrate,v_quality,s_quality; //video bitrate,video-sound quality 142 int encOnTheFly; //encode while recording, no caching(default 0) 143 char *workdir; //directory to be used for cache files(default $HOME) 144 char *pause_shortcut; //pause/unpause shortcut sequence(Control+Alt+p) 145 char *stop_shortcut; //stop shortcut sequence(Control+Alt+s) 146 int noframe; //don't draw a frame around the recording area 147 int zerocompression; //image data are always flushed uncompressed 148 int overwrite; //overwite a previously existing file 149 //(do not add a .number postfix) 150 int use_jack; //record audio with jack 151 unsigned int jack_nports; 152 char **jack_port_names; 153 float jack_ringbuffer_secs; 154 }ProgArgs; 155 156 //this struct holds anything related to encoding AND 157 //writting out to file. 158 typedef struct _EncData{ 159 ogg_stream_state m_ogg_ts; //theora 160 ogg_stream_state m_ogg_vs; //vorbis 161 ogg_page m_ogg_pg; //this could be avoided since 162 // it is used only while initializing 163 ogg_packet m_ogg_pckt1; //theora stream 164 ogg_packet m_ogg_pckt2; //vorbis stream 165 //theora data 166 theora_state m_th_st; 167 theora_info m_th_inf; 168 theora_comment m_th_cmmnt; 169 yuv_buffer yuv; 170 //vorbis data 171 vorbis_info m_vo_inf; 172 vorbis_comment m_vo_cmmnt; 173 vorbis_dsp_state m_vo_dsp; 174 vorbis_block m_vo_block; 175 //these should be 0, since area is quantized 176 //before input 177 int x_offset, 178 y_offset; 179 //our file 180 FILE *fp; 181 }EncData; 182 183 //this struct will hold a few basic 184 //information, needed for caching the frames. 185 typedef struct _CacheData{ 186 char *workdir, //The directory were the project 187 //will be stored, while recording. 188 //Since this will take a lot of space, the user must be 189 //able to change the location. 190 *projname, //This is the name of the folder that 191 //will hold the project. 192 //It is rMD-session-%d where %d is the pid 193 //of the current proccess. 194 //This way, running two instances 195 //will not create problems 196 //and also, a frontend can identify 197 //leftovers from a possible crash 198 //and delete them 199 *specsfile, //workdir+projname+specs.txt 200 *imgdata, //workdir+projname+img.out.gz 201 *audiodata; //workdir+projname+audio.pcm 202 203 gzFile *ifp; //image data file pointer 204 FILE *uncifp; //uncompressed image data file pointer 205 206 FILE *afp; //audio data file pointer 207 208 }CacheData; 209 210 //sound buffer 211 //sound keeps coming so we que it in this list 212 //which we then traverse 213 typedef struct _SndBuffer{ 214 signed char *data; 215 struct _SndBuffer *next; 216 }SndBuffer; 217 218 #ifdef HAVE_LIBJACK 219 typedef struct _JackData{ 220 ProgData *pdata; //pointer to prog data 221 jack_client_t *client; 222 unsigned int buffersize, //buffer size for every port in frames. 223 frequency, //samplerate with which jack server was started. 224 nports; //number of ports. 225 float ringbuffer_secs; 226 char **port_names; //names of ports(as specified in args). 227 jack_port_t **ports; //connections to thes ports. 228 jack_default_audio_sample_t **portbuf; //retrieval of audio buffers. 229 pthread_mutex_t *snd_buff_ready_mutex; //mutex and cond_var 230 pthread_cond_t *sound_data_read; //in the pdata struct 231 jack_ringbuffer_t *sound_buffer; //data exchange happens through this 232 int capture_started; //used to hold recording in the beginning 233 }JackData; 234 #endif 235 236 typedef struct _HotKey{ //Hold info about the shortcuts 237 int modnum; //modnum is the number of modifier masks 238 unsigned int mask[4]; //that should be checked (the initial 239 int key; //user requested modifier plus it's 240 }HotKey; //combinations with LockMask and NumLockMask). 241 242 //this structure holds any data related to the program 243 //It's usage is mostly to be given as an argument to the 244 //threads,so they will have access to the program data, avoiding 245 //at the same time usage of any globals. 246 struct _ProgData { 247 /**recordMyDesktop specific structs*/ 248 ProgArgs args; //the program arguments 249 DisplaySpecs specs; //Display specific information 250 BRWindow brwin; //recording window 251 RectArea *rect_root; //the interchanging list roots for storing 252 //the changed regions 253 SndBuffer *sound_buffer; 254 EncData *enc_data; 255 CacheData *cache_data; 256 HotKey pause_key, //Shortcuts 257 stop_key; 258 #ifdef HAVE_LIBJACK 259 JackData *jdata; 260 #endif 261 /**X related info*/ 262 Display *dpy; //curtrent display 263 /** Mutexes*/ 264 pthread_mutex_t sound_buffer_mutex, 265 snd_buff_ready_mutex, 266 img_buff_ready_mutex, 267 theora_lib_mutex, 268 vorbis_lib_mutex, 269 libogg_mutex, //libogg is not thread safe, 270 yuv_mutex; //this might not be needed since we only have 271 //one read-only and one write-only thread 272 //also on previous versions, 273 //y component was looped separately 274 //and then u and v so this was needed 275 //to avoid wrong coloring to render 276 //Currently this mutex only prevents 277 //the cursor from flickering 278 /**Condition Variables*/ 279 pthread_cond_t time_cond, //this gets a broadcast by the handler 280 //whenever it's time to get a screenshot 281 pause_cond, //this is blocks execution, 282 //when program is paused 283 sound_data_read, //a buffer is ready for proccessing 284 image_buffer_ready, //image encoding finished 285 theora_lib_clean, //the flush_ogg thread cannot 286 //procceed to creating last 287 vorbis_lib_clean; //packages until these two libs 288 //are no longer used, by other threads 289 /**Buffers,Flags and other vars*/ 290 unsigned char *dummy_pointer, //a dummy pointer to be drawn 291 //in every frame 292 //data is casted to unsigned for 293 //later use in YUV buffer 294 npxl; //this is the no pixel convention 295 //when drawing the dummy pointer 296 unsigned int periodtime,//time that a sound buffer lasts (microsecs) 297 frametime; //time that a frame lasts (microsecs) 298 Window shaped_w; //frame 299 int damage_event, //damage event base code 300 damage_error, //damage error base code 301 shm_opcode, //MIT-Shm opcode 302 dummy_p_size, //dummy pointer size,initially 16x16,always square 303 th_encoding_clean, //thread exit inidcator 304 v_encoding_clean, // >> >> 305 v_enc_thread_waiting, //these indicate a wait 306 th_enc_thread_waiting, //condition on the cond vars. 307 timer_alive, //determines loop of timer thread 308 hard_pause, //if sound device doesn't support pause 309 //we have to close and reopen 310 avd, //syncronization among audio and video 311 sound_framesize; //size of each sound frame 312 313 /** Progam state vars */ 314 boolean running; //1 while the program is capturing/paused/encoding 315 boolean paused; //1 while the program is paused 316 boolean aborted; //1 if we should abort 317 boolean pause_state_changed; //1 if pause state changed 318 319 //the following values are of no effect 320 //but they might be usefull later for profiling 321 unsigned int frames_total, //frames calculated by total time expirations 322 frames_lost; //the value of shame 323 324 //used to determine frame drop which can 325 //happen on failure to receive a signal over a condition variable 326 boolean capture_busy, 327 encoder_busy; 328 329 pthread_mutex_t pause_mutex; 330 pthread_mutex_t time_mutex; 331 332 #ifdef HAVE_LIBASOUND 333 snd_pcm_t *sound_handle; 334 snd_pcm_uframes_t periodsize; 335 #else 336 int sound_handle; 337 u_int32_t periodsize; 338 #endif 339 }; 340 341 342 //This is the header of every frame. 343 //Reconstruction will be correct only if made on 344 //the same platform. 345 346 //We need the total number of blocks 347 //for each plane. 348 349 //The number of the frame compared to the 350 //number of time expirations at the time of 351 //caching, will enable us to make up for lost frames. 352 353 354 typedef struct _FrameHeader{ 355 char frame_prefix[4]; //always FRAM 356 u_int32_t frameno, //number of frame(cached frames) 357 current_total; //number of frames that should have been 358 //taken at time of caching this one 359 u_int32_t Ynum, //number of changed blocks in the Y plane 360 Unum, //number of changed blocks in the U plane 361 Vnum; //number of changed blocks in the V plane 362 }FrameHeader; 363 364 #endif 365 366