summaryrefslogtreecommitdiff
path: root/recordmydesktop
diff options
context:
space:
mode:
Diffstat (limited to 'recordmydesktop')
-rw-r--r--recordmydesktop/include/rmdfunc.h25
-rw-r--r--recordmydesktop/include/rmdtypes.h1
-rw-r--r--recordmydesktop/src/Makefile.am4
-rw-r--r--recordmydesktop/src/initialize_data.c147
-rw-r--r--recordmydesktop/src/recordmydesktop.c210
-rw-r--r--recordmydesktop/src/rmdthreads.c111
6 files changed, 294 insertions, 204 deletions
diff --git a/recordmydesktop/include/rmdfunc.h b/recordmydesktop/include/rmdfunc.h
index ec74105..447351a 100644
--- a/recordmydesktop/include/rmdfunc.h
+++ b/recordmydesktop/include/rmdfunc.h
@@ -449,5 +449,30 @@ int PurgeCache(CacheData *cache_data_t,int sound);
*/
void EncodeCache(ProgData *pdata);
+/**
+* Launch and wait capture threads.
+* Also creates and waits the encoding threads when
+* encode-on-the-fly is enabled.
+*
+* \param pdata ProgData struct containing all program data
+*/
+void rmdThreads(ProgData *pdata);
+
+/**
+* initialize lists,mutexes,image buffers, take first screenshot,
+* and anything else needed before launching the capture threads.
+*
+* \param pdata ProgData struct containing all program data
+*
+* \param enc_data reference to enc_data structure
+*
+* \param cache_data reference to cache_data structure
+*
+* \returns 0 on success, other values must cause the program to exit
+*/
+int InitializeData(ProgData *pdata,
+ EncData *enc_data,
+ CacheData *cache_data);
+
#endif
diff --git a/recordmydesktop/include/rmdtypes.h b/recordmydesktop/include/rmdtypes.h
index b50e1e2..b52817c 100644
--- a/recordmydesktop/include/rmdtypes.h
+++ b/recordmydesktop/include/rmdtypes.h
@@ -196,6 +196,7 @@ typedef struct _ProgData{
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)
+ XShmSegmentInfo shminfo;//info structure for the image above.
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
diff --git a/recordmydesktop/src/Makefile.am b/recordmydesktop/src/Makefile.am
index dbf7f68..98ddda2 100644
--- a/recordmydesktop/src/Makefile.am
+++ b/recordmydesktop/src/Makefile.am
@@ -25,7 +25,9 @@ recordmydesktop_SOURCES= recordmydesktop.c\
rmd_cache.c\
load_cache.c\
wm_check.c\
- encode_cache.c
+ encode_cache.c\
+ rmdthreads.c\
+ initialize_data.c
INCLUDES= $(all_includes) -I../include
diff --git a/recordmydesktop/src/initialize_data.c b/recordmydesktop/src/initialize_data.c
new file mode 100644
index 0000000..f06d71e
--- /dev/null
+++ b/recordmydesktop/src/initialize_data.c
@@ -0,0 +1,147 @@
+/*********************************************************************************
+* recordMyDesktop *
+**********************************************************************************
+* *
+* Copyright (C) 2006 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 *
+**********************************************************************************/
+
+
+#include <recordmydesktop.h>
+
+int InitializeData(ProgData *pdata,
+ EncData *enc_data,
+ CacheData *cache_data){
+ int i;
+
+ //these are globals, look for them at the header
+ frames_total=frames_lost=encoder_busy=capture_busy=0;
+
+ fprintf(stderr,"Initializing...\n");
+ MakeMatrices();
+ if(pdata->args.have_dummy_cursor){
+ pdata->dummy_pointer=MakeDummyPointer(&pdata->specs,16,pdata->args.cursor_color,0,&pdata->npxl);
+ pdata->dummy_p_size=16;
+ }
+
+ if((pdata->args.noshared))
+ pdata->datamain=(char *)malloc(pdata->brwin.nbytes);
+
+ if(pdata->args.noshared)
+ pdata->datatemp=(char *)malloc(pdata->brwin.nbytes);
+ pdata->rect_root[0]=pdata->rect_root[1]=NULL;
+ pthread_mutex_init(&pdata->list_mutex[0],NULL);
+ pthread_mutex_init(&pdata->list_mutex[1],NULL);
+ pthread_mutex_init(&pdata->sound_buffer_mutex,NULL);
+ pthread_mutex_init(&pdata->libogg_mutex,NULL);
+ pthread_mutex_init(&pdata->yuv_mutex,NULL);
+
+ pthread_cond_init(&pdata->time_cond,NULL);
+ pthread_cond_init(&pdata->pause_cond,NULL);
+ pthread_cond_init(&pdata->image_buffer_ready,NULL);
+ pthread_cond_init(&pdata->sound_buffer_ready,NULL);
+ pthread_cond_init(&pdata->sound_data_read,NULL);
+ pthread_cond_init(&pdata->theora_lib_clean,NULL);
+ pthread_cond_init(&pdata->vorbis_lib_clean,NULL);
+ pdata->th_encoding_clean=pdata->v_encoding_clean=1;
+ pdata->list_selector=Paused=Aborted=pdata->avd=0;
+ pdata->sound_buffer=NULL;
+ pdata->running=1;
+ time_cond=&pdata->time_cond;
+ pause_cond=&pdata->pause_cond;
+ Running=&pdata->running;
+
+ if((pdata->args.noshared)){
+ pdata->image=XCreateImage(pdata->dpy, pdata->specs.visual, pdata->specs.depth, ZPixmap, 0,pdata->datamain,pdata->brwin.rgeom.width,
+ pdata->brwin.rgeom.height, 8, 0);
+ XInitImage(pdata->image);
+ GetZPixmap(pdata->dpy,pdata->specs.root,pdata->image->data,pdata->brwin.rgeom.x,pdata->brwin.rgeom.y,
+ pdata->brwin.rgeom.width,pdata->brwin.rgeom.height);
+ }
+ if((!pdata->args.noshared)||(!pdata->args.nocondshared)){
+ pdata->shimage=XShmCreateImage (pdata->dpy,pdata->specs.visual,pdata->specs.depth,ZPixmap,pdata->datash,
+ &pdata->shminfo, pdata->brwin.rgeom.width,pdata->brwin.rgeom.height);
+ pdata->shminfo.shmid = shmget (IPC_PRIVATE,
+ pdata->shimage->bytes_per_line * pdata->shimage->height,
+ IPC_CREAT|0777);
+ pdata->shminfo.shmaddr = pdata->shimage->data = shmat (pdata->shminfo.shmid, 0, 0);
+ pdata->shminfo.readOnly = False;
+ if(!XShmAttach(pdata->dpy,&pdata->shminfo)){
+ fprintf(stderr,"Failed to attach shared memory to proccess.\n");
+ return 12;
+ }
+ XShmGetImage(pdata->dpy,pdata->specs.root,pdata->shimage,pdata->brwin.rgeom.x,pdata->brwin.rgeom.y,AllPlanes);
+ }
+ if(!pdata->args.nosound){
+ pdata->sound_handle=OpenDev( pdata->args.device,
+ &pdata->args.channels,
+ &pdata->args.frequency,
+ &pdata->args.buffsize,
+ &pdata->periodsize,
+ &pdata->periodtime,
+ &pdata->hard_pause);
+ if(pdata->sound_handle==NULL){
+ fprintf(stderr,"Error while opening/configuring soundcard %s\nTry running with the --no-sound or specify a correct device.\n",pdata->args.device);
+ return 3;
+ }
+ }
+
+ if(pdata->args.encOnTheFly)
+ InitEncoder(pdata,enc_data,0);
+ else
+ InitCacheData(pdata,enc_data,cache_data);
+
+ for(i=0;i<(pdata->enc_data->yuv.y_width*pdata->enc_data->yuv.y_height);i++)
+ pdata->enc_data->yuv.y[i]=0;
+ for(i=0;i<(pdata->enc_data->yuv.uv_width*pdata->enc_data->yuv.uv_height);i++){
+ pdata->enc_data->yuv.v[i]=pdata->enc_data->yuv.u[i]=127;
+ }
+
+ if((pdata->args.nocondshared)&&(!pdata->args.noshared)){
+ if(pdata->args.no_quick_subsample){
+ UPDATE_YUV_BUFFER_IM_AVG((&pdata->enc_data->yuv),((unsigned char*)pdata->shimage->data),
+ (pdata->enc_data->x_offset),(pdata->enc_data->y_offset),
+ (pdata->brwin.rgeom.width),(pdata->brwin.rgeom.height));
+ }
+ else{
+ UPDATE_YUV_BUFFER_IM((&pdata->enc_data->yuv),((unsigned char*)pdata->shimage->data),
+ (pdata->enc_data->x_offset),(pdata->enc_data->y_offset),
+ (pdata->brwin.rgeom.width),(pdata->brwin.rgeom.height));
+ }
+ }
+ else{
+ if(pdata->args.no_quick_subsample){
+ UPDATE_YUV_BUFFER_IM_AVG((&pdata->enc_data->yuv),((unsigned char*)pdata->image->data),
+ (pdata->enc_data->x_offset),(pdata->enc_data->y_offset),
+ (pdata->brwin.rgeom.width),(pdata->brwin.rgeom.height));
+ }
+ else{
+ UPDATE_YUV_BUFFER_IM((&pdata->enc_data->yuv),((unsigned char*)pdata->image->data),
+ (pdata->enc_data->x_offset),(pdata->enc_data->y_offset),
+ (pdata->brwin.rgeom.width),(pdata->brwin.rgeom.height));
+ }
+ }
+
+ pdata->frametime=(1000000)/pdata->args.fps;
+
+ return 0;
+
+}
diff --git a/recordmydesktop/src/recordmydesktop.c b/recordmydesktop/src/recordmydesktop.c
index 7fd1ebb..decc86d 100644
--- a/recordmydesktop/src/recordmydesktop.c
+++ b/recordmydesktop/src/recordmydesktop.c
@@ -52,16 +52,6 @@ int main(int argc,char **argv){
else{
EncData enc_data;
CacheData cache_data;
- pthread_t poll_damage_t,
- image_capture_t,
- image_encode_t,
- image_cache_t,
- sound_capture_t,
- sound_encode_t,
- sound_cache_t,
- flush_to_ogg_t;
- XShmSegmentInfo shminfo;
- int i;
QUERY_DISPLAY_SPECS(pdata.dpy,&pdata.specs);
if(pdata.specs.depth!=24){
@@ -71,7 +61,6 @@ int main(int argc,char **argv){
if(SetBRWindow(pdata.dpy,&pdata.brwin,&pdata.specs,&pdata.args))
exit(11);
-
//check if we are under compiz or beryl,in which case we must enable full-shots
//and with it use of shared memory.User can override this
pdata.window_manager=((pdata.args.nowmcheck)?NULL:rmdWMCheck(pdata.dpy,pdata.specs.root));
@@ -94,205 +83,20 @@ int main(int argc,char **argv){
QueryExtensions(pdata.dpy,&pdata.args,&pdata.damage_event, &pdata.damage_error);
+ if((exit_status=InitializeData(&pdata,&enc_data,&cache_data))!=0)
+ return exit_status;
-
- //init data
-
- //these are globals, look for them at the header
- frames_total=frames_lost=encoder_busy=capture_busy=0;
-
- fprintf(stderr,"Initializing...\n");
- MakeMatrices();
- if(pdata.args.have_dummy_cursor){
- pdata.dummy_pointer=MakeDummyPointer(&pdata.specs,16,pdata.args.cursor_color,0,&pdata.npxl);
- pdata.dummy_p_size=16;
- }
-
- if((pdata.args.noshared))
- pdata.datamain=(char *)malloc(pdata.brwin.nbytes);
-
- if(pdata.args.noshared)
- pdata.datatemp=(char *)malloc(pdata.brwin.nbytes);
- pdata.rect_root[0]=pdata.rect_root[1]=NULL;
- pthread_mutex_init(&pdata.list_mutex[0],NULL);
- pthread_mutex_init(&pdata.list_mutex[1],NULL);
- pthread_mutex_init(&pdata.sound_buffer_mutex,NULL);
- pthread_mutex_init(&pdata.libogg_mutex,NULL);
-// pthread_mutex_init(&pdata.libtheora_mutex,NULL);
-// pthread_mutex_init(&pdata.libvorbis_mutex,NULL);
- pthread_mutex_init(&pdata.yuv_mutex,NULL);
-
- pthread_cond_init(&pdata.time_cond,NULL);
- pthread_cond_init(&pdata.pause_cond,NULL);
- pthread_cond_init(&pdata.image_buffer_ready,NULL);
- pthread_cond_init(&pdata.sound_buffer_ready,NULL);
- pthread_cond_init(&pdata.sound_data_read,NULL);
- pthread_cond_init(&pdata.theora_lib_clean,NULL);
- pthread_cond_init(&pdata.vorbis_lib_clean,NULL);
- pdata.th_encoding_clean=pdata.v_encoding_clean=1;
- pdata.list_selector=Paused=Aborted=pdata.avd=0;
- pdata.sound_buffer=NULL;
- pdata.running=1;
- time_cond=&pdata.time_cond;
- pause_cond=&pdata.pause_cond;
- Running=&pdata.running;
-
- if((pdata.args.noshared)){
- pdata.image=XCreateImage(pdata.dpy, pdata.specs.visual, pdata.specs.depth, ZPixmap, 0,pdata.datamain,pdata.brwin.rgeom.width,
- pdata.brwin.rgeom.height, 8, 0);
- XInitImage(pdata.image);
- GetZPixmap(pdata.dpy,pdata.specs.root,pdata.image->data,pdata.brwin.rgeom.x,pdata.brwin.rgeom.y,
- pdata.brwin.rgeom.width,pdata.brwin.rgeom.height);
- }
- if((!pdata.args.noshared)||(!pdata.args.nocondshared)){
- pdata.shimage=XShmCreateImage (pdata.dpy,pdata.specs.visual,pdata.specs.depth,ZPixmap,pdata.datash,
- &shminfo, pdata.brwin.rgeom.width,pdata.brwin.rgeom.height);
- shminfo.shmid = shmget (IPC_PRIVATE,
- pdata.shimage->bytes_per_line * pdata.shimage->height,
- IPC_CREAT|0777);
- shminfo.shmaddr = pdata.shimage->data = shmat (shminfo.shmid, 0, 0);
- shminfo.readOnly = False;
- if(!XShmAttach(pdata.dpy,&shminfo)){
- fprintf(stderr,"Failed to attach shared memory to proccess.\n");
- exit(12);
- }
- XShmGetImage(pdata.dpy,pdata.specs.root,pdata.shimage,pdata.brwin.rgeom.x,pdata.brwin.rgeom.y,AllPlanes);
- }
- if(!pdata.args.nosound){
- pdata.sound_handle=OpenDev( pdata.args.device,
- &pdata.args.channels,
- &pdata.args.frequency,
- &pdata.args.buffsize,
- &pdata.periodsize,
- &pdata.periodtime,
- &pdata.hard_pause);
- if(pdata.sound_handle==NULL){
- fprintf(stderr,"Error while opening/configuring soundcard %s\nTry running with the --no-sound or specify a correct device.\n",pdata.args.device);
- exit(3);
- }
- }
-
- if(pdata.args.encOnTheFly)
- InitEncoder(&pdata,&enc_data,0);
- else
- InitCacheData(&pdata,&enc_data,&cache_data);
-
- for(i=0;i<(pdata.enc_data->yuv.y_width*pdata.enc_data->yuv.y_height);i++)
- pdata.enc_data->yuv.y[i]=0;
- for(i=0;i<(pdata.enc_data->yuv.uv_width*pdata.enc_data->yuv.uv_height);i++){
- pdata.enc_data->yuv.v[i]=pdata.enc_data->yuv.u[i]=127;
- }
-
- if((pdata.args.nocondshared)&&(!pdata.args.noshared)){
- if(pdata.args.no_quick_subsample){
- UPDATE_YUV_BUFFER_IM_AVG((&pdata.enc_data->yuv),((unsigned char*)pdata.shimage->data),
- (pdata.enc_data->x_offset),(pdata.enc_data->y_offset),
- (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height));
- }
- else{
- UPDATE_YUV_BUFFER_IM((&pdata.enc_data->yuv),((unsigned char*)pdata.shimage->data),
- (pdata.enc_data->x_offset),(pdata.enc_data->y_offset),
- (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height));
- }
- }
- else{
- if(pdata.args.no_quick_subsample){
- UPDATE_YUV_BUFFER_IM_AVG((&pdata.enc_data->yuv),((unsigned char*)pdata.image->data),
- (pdata.enc_data->x_offset),(pdata.enc_data->y_offset),
- (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height));
- }
- else{
- UPDATE_YUV_BUFFER_IM((&pdata.enc_data->yuv),((unsigned char*)pdata.image->data),
- (pdata.enc_data->x_offset),(pdata.enc_data->y_offset),
- (pdata.brwin.rgeom.width),(pdata.brwin.rgeom.height));
- }
- }
-
- pdata.frametime=(1000000)/pdata.args.fps;
-
- if(pdata.args.delay>0){
- fprintf(stderr,"Will sleep for %d seconds now.\n",pdata.args.delay);
- sleep(pdata.args.delay);
- }
-
- /*start threads*/
- if(!pdata.args.full_shots)
- pthread_create(&poll_damage_t,NULL,(void *)PollDamage,(void *)&pdata);
- pthread_create(&image_capture_t,NULL,(void *)GetFrame,(void *)&pdata);
- if(pdata.args.encOnTheFly)
- pthread_create(&image_encode_t,NULL,(void *)EncodeImageBuffer,(void *)&pdata);
- else
- pthread_create(&image_cache_t,NULL,(void *)CacheImageBuffer,(void *)&pdata);
-
- if(!pdata.args.nosound){
- pthread_create(&sound_capture_t,NULL,(void *)CaptureSound,(void *)&pdata);
- if(pdata.args.encOnTheFly)
- pthread_create(&sound_encode_t,NULL,(void *)EncodeSoundBuffer,(void *)&pdata);
- else
- pthread_create(&sound_cache_t,NULL,(void *)CacheSoundBuffer,(void *)&pdata);
- }
- if(pdata.args.encOnTheFly)
- pthread_create(&flush_to_ogg_t,NULL,(void *)FlushToOgg,(void *)&pdata);
-
-
- RegisterCallbacks(&pdata.args);
- fprintf(stderr,"Capturing!\n");
-
- //wait all threads to finish
-
- pthread_join(image_capture_t,NULL);
- fprintf(stderr,"Shutting down.");
- //if no damage events have been received the thread will get stuck
- while(!pdata.th_enc_thread_waiting && !pdata.th_encoding_clean){
- usleep(10000);
- pthread_cond_signal(&pdata.image_buffer_ready);
- }
-// pthread_cond_broadcast(&pdata.image_buffer_ready);
- if(pdata.args.encOnTheFly){
- pthread_join(image_encode_t,NULL);
- }
- else
- pthread_join(image_cache_t,NULL);
-
-
- fprintf(stderr,".");
- if(!pdata.args.nosound){
- pthread_join(sound_capture_t,NULL);
- fprintf(stderr,".");
- while(!pdata.v_enc_thread_waiting && !pdata.v_encoding_clean){
- usleep(10000);
- pthread_cond_signal(&pdata.sound_data_read);
- }
- if(pdata.args.encOnTheFly){
- pthread_join(sound_encode_t,NULL);
- }
- else{
- pthread_join(sound_cache_t,NULL);
- }
- }
- else
- fprintf(stderr,"..");
-
- if(pdata.args.encOnTheFly)
- pthread_join(flush_to_ogg_t,NULL);
- fprintf(stderr,".");
-
- if(!pdata.args.full_shots)
- pthread_join(poll_damage_t,NULL);
-
+ //this is where the capturing happens.
+ rmdThreads(&pdata);
fprintf(stderr,".");
if((!pdata.args.noshared)||(!pdata.args.nocondshared)){
- XShmDetach (pdata.dpy, &shminfo);
- shmdt (&shminfo.shmaddr);
- shmctl (shminfo.shmid, IPC_RMID, 0);
+ XShmDetach (pdata.dpy, &pdata.shminfo);
+ shmdt (&pdata.shminfo.shmaddr);
+ shmctl (pdata.shminfo.shmid, IPC_RMID, 0);
}
fprintf(stderr,"\n");
-
- //Now that we are done with recording we cancel the timer
- CancelTimer();
-
//encode and then cleanup cache
if(!pdata.args.encOnTheFly){
if(!Aborted){
diff --git a/recordmydesktop/src/rmdthreads.c b/recordmydesktop/src/rmdthreads.c
new file mode 100644
index 0000000..9a93416
--- /dev/null
+++ b/recordmydesktop/src/rmdthreads.c
@@ -0,0 +1,111 @@
+/*********************************************************************************
+* recordMyDesktop *
+**********************************************************************************
+* *
+* Copyright (C) 2006 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 *
+**********************************************************************************/
+
+
+#include <recordmydesktop.h>
+
+void rmdThreads(ProgData *pdata){
+ pthread_t poll_damage_t,
+ image_capture_t,
+ image_encode_t,
+ image_cache_t,
+ sound_capture_t,
+ sound_encode_t,
+ sound_cache_t,
+ flush_to_ogg_t;
+
+
+ if(pdata->args.delay>0){
+ fprintf(stderr,"Will sleep for %d seconds now.\n",pdata->args.delay);
+ sleep(pdata->args.delay);
+ }
+
+ /*start threads*/
+ if(!pdata->args.full_shots)
+ pthread_create(&poll_damage_t,NULL,(void *)PollDamage,(void *)pdata);
+ pthread_create(&image_capture_t,NULL,(void *)GetFrame,(void *)pdata);
+ if(pdata->args.encOnTheFly)
+ pthread_create(&image_encode_t,NULL,(void *)EncodeImageBuffer,(void *)pdata);
+ else
+ pthread_create(&image_cache_t,NULL,(void *)CacheImageBuffer,(void *)pdata);
+
+ if(!pdata->args.nosound){
+ pthread_create(&sound_capture_t,NULL,(void *)CaptureSound,(void *)pdata);
+ if(pdata->args.encOnTheFly)
+ pthread_create(&sound_encode_t,NULL,(void *)EncodeSoundBuffer,(void *)pdata);
+ else
+ pthread_create(&sound_cache_t,NULL,(void *)CacheSoundBuffer,(void *)pdata);
+ }
+ if(pdata->args.encOnTheFly)
+ pthread_create(&flush_to_ogg_t,NULL,(void *)FlushToOgg,(void *)pdata);
+
+ RegisterCallbacks(&pdata->args);
+ fprintf(stderr,"Capturing!\n");
+
+ //wait all threads to finish
+
+ pthread_join(image_capture_t,NULL);
+ fprintf(stderr,"Shutting down.");
+ //if no damage events have been received the thread will get stuck
+ while(!pdata->th_enc_thread_waiting && !pdata->th_encoding_clean){
+ usleep(10000);
+ pthread_cond_signal(&pdata->image_buffer_ready);
+ }
+
+ if(pdata->args.encOnTheFly){
+ pthread_join(image_encode_t,NULL);
+ }
+ else
+ pthread_join(image_cache_t,NULL);
+ fprintf(stderr,".");
+ if(!pdata->args.nosound){
+ pthread_join(sound_capture_t,NULL);
+ fprintf(stderr,".");
+ while(!pdata->v_enc_thread_waiting && !pdata->v_encoding_clean){
+ usleep(10000);
+ pthread_cond_signal(&pdata->sound_data_read);
+ }
+ if(pdata->args.encOnTheFly){
+ pthread_join(sound_encode_t,NULL);
+ }
+ else{
+ pthread_join(sound_cache_t,NULL);
+ }
+ }
+ else
+ fprintf(stderr,"..");
+
+ if(pdata->args.encOnTheFly)
+ pthread_join(flush_to_ogg_t,NULL);
+ fprintf(stderr,".");
+
+ if(!pdata->args.full_shots)
+ pthread_join(poll_damage_t,NULL);
+
+ //Now that we are done with recording we cancel the timer
+ CancelTimer();
+
+}
© All Rights Reserved