diff options
-rw-r--r-- | recordmydesktop/include/recordmydesktop.h | 12 | ||||
-rw-r--r-- | recordmydesktop/src/cache_audio.c | 8 | ||||
-rw-r--r-- | recordmydesktop/src/cache_frame.c | 3 | ||||
-rw-r--r-- | recordmydesktop/src/encode_image_buffer.c | 10 | ||||
-rw-r--r-- | recordmydesktop/src/encode_sound_buffer.c | 25 | ||||
-rw-r--r-- | recordmydesktop/src/flush_to_ogg.c | 20 | ||||
-rw-r--r-- | recordmydesktop/src/load_cache.c | 7 | ||||
-rw-r--r-- | recordmydesktop/src/recordmydesktop.c | 36 |
8 files changed, 86 insertions, 35 deletions
diff --git a/recordmydesktop/include/recordmydesktop.h b/recordmydesktop/include/recordmydesktop.h index 585a3d1..59ac109 100644 --- a/recordmydesktop/include/recordmydesktop.h +++ b/recordmydesktop/include/recordmydesktop.h @@ -255,7 +255,9 @@ typedef struct _ProgData{ frametime; pthread_mutex_t list_mutex[2],//mutexes for concurrency protection of the lists sound_buffer_mutex, - libogg_mutex,//libogg is not thread safe + 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 @@ -265,7 +267,13 @@ typedef struct _ProgData{ 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 + 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; diff --git a/recordmydesktop/src/cache_audio.c b/recordmydesktop/src/cache_audio.c index 99465de..afd08cf 100644 --- a/recordmydesktop/src/cache_audio.c +++ b/recordmydesktop/src/cache_audio.c @@ -41,9 +41,13 @@ void *CacheSoundBuffer(ProgData *pdata){ pthread_mutex_init(&tmut,NULL); pthread_cond_wait(&pdata->pause_cond,&tmut); } - - if(pdata->sound_buffer==NULL) + if(pdata->sound_buffer==NULL){ + pdata->v_enc_thread_waiting=1; pthread_cond_wait(&pdata->sound_data_read,&smut); + pdata->v_enc_thread_waiting=0; + } + if(pdata->sound_buffer==NULL || !pdata->running) + break; pthread_mutex_lock(&pdata->sound_buffer_mutex); buff=pdata->sound_buffer; diff --git a/recordmydesktop/src/cache_frame.c b/recordmydesktop/src/cache_frame.c index 813b9e0..d77308a 100644 --- a/recordmydesktop/src/cache_frame.c +++ b/recordmydesktop/src/cache_frame.c @@ -111,7 +111,10 @@ void *CacheImageBuffer(ProgData *pdata){ FrameHeader fheader; ynum=unum=vnum=0; + pdata->th_enc_thread_waiting=1; pthread_cond_wait(&pdata->image_buffer_ready,&imut); + pdata->th_enc_thread_waiting=0; + if(Paused) pthread_cond_wait(&pdata->pause_cond,&pmut); pthread_mutex_lock(&pdata->yuv_mutex); diff --git a/recordmydesktop/src/encode_image_buffer.c b/recordmydesktop/src/encode_image_buffer.c index 60d87c4..3c50a6f 100644 --- a/recordmydesktop/src/encode_image_buffer.c +++ b/recordmydesktop/src/encode_image_buffer.c @@ -29,12 +29,16 @@ void *EncodeImageBuffer(ProgData *pdata){ pthread_mutex_t pmut,imut; pthread_mutex_init(&pmut,NULL); pthread_mutex_init(&imut,NULL); + pdata->th_encoding_clean=0; while(pdata->running){ + pdata->th_enc_thread_waiting=1; pthread_cond_wait(&pdata->image_buffer_ready,&imut); + pdata->th_enc_thread_waiting=0; encoder_busy=1; if(Paused) pthread_cond_wait(&pdata->pause_cond,&pmut);//this may not be needed pthread_mutex_lock(&pdata->yuv_mutex); +// pthread_mutex_lock(&pdata->libtheora_mutex); if(theora_encode_YUVin(&pdata->enc_data->m_th_st,&pdata->enc_data->yuv)){ fprintf(stderr,"Encoder not ready!\n"); pthread_mutex_unlock(&pdata->yuv_mutex); @@ -48,10 +52,12 @@ void *EncodeImageBuffer(ProgData *pdata){ pdata->avd+=pdata->frametime; } } +// pthread_mutex_unlock(&pdata->libtheora_mutex); encoder_busy=0; } //last packet - + pdata->th_encoding_clean=1; + pthread_cond_signal(&pdata->theora_lib_clean); // SyncEncodeImageBuffer(pdata); pthread_exit(&errno); } @@ -59,6 +65,7 @@ void *EncodeImageBuffer(ProgData *pdata){ //this function is meant to be called normally //not through a thread of it's own void SyncEncodeImageBuffer(ProgData *pdata){ +// pthread_mutex_lock(&pdata->libtheora_mutex); if(theora_encode_YUVin(&pdata->enc_data->m_th_st, &pdata->enc_data->yuv)){ fprintf(stderr,"Encoder not ready!\n"); @@ -74,5 +81,6 @@ void SyncEncodeImageBuffer(ProgData *pdata){ pdata->avd+=pdata->frametime; } } +// pthread_mutex_unlock(&pdata->libtheora_mutex); } diff --git a/recordmydesktop/src/encode_sound_buffer.c b/recordmydesktop/src/encode_sound_buffer.c index e72884b..d4c673b 100644 --- a/recordmydesktop/src/encode_sound_buffer.c +++ b/recordmydesktop/src/encode_sound_buffer.c @@ -32,6 +32,7 @@ void *EncodeSoundBuffer(ProgData *pdata){ int sampread=pdata->periodsize; pthread_mutex_t smut; pthread_mutex_init(&smut,NULL); + pdata->v_encoding_clean=0; while((pdata->running)){ float **vorbis_buffer; int count=0,i,j; @@ -43,15 +44,20 @@ void *EncodeSoundBuffer(ProgData *pdata){ pthread_cond_wait(&pdata->pause_cond,&tmut); } - if(pdata->sound_buffer==NULL) + if(pdata->sound_buffer==NULL){ + pdata->v_enc_thread_waiting=1; pthread_cond_wait(&pdata->sound_data_read,&smut); - + pdata->v_enc_thread_waiting=0; + } + if(pdata->sound_buffer==NULL || !pdata->running) + break; pthread_mutex_lock(&pdata->sound_buffer_mutex); buff=pdata->sound_buffer; //advance the list pdata->sound_buffer=pdata->sound_buffer->next; pthread_mutex_unlock(&pdata->sound_buffer_mutex); +// pthread_mutex_lock(&pdata->libvorbis_mutex); vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,sampread); for(i=0;i<sampread;i++){ for(j=0;j<pdata->args.channels;j++){ @@ -62,24 +68,27 @@ void *EncodeSoundBuffer(ProgData *pdata){ } vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread); + pthread_mutex_lock(&pdata->libogg_mutex); while(vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp,&pdata->enc_data->m_vo_block)==1){ vorbis_analysis(&pdata->enc_data->m_vo_block,NULL); vorbis_bitrate_addblock(&pdata->enc_data->m_vo_block); while(vorbis_bitrate_flushpacket(&pdata->enc_data->m_vo_dsp,&pdata->enc_data->m_ogg_pckt2)){ - pthread_mutex_lock(&pdata->libogg_mutex); ogg_stream_packetin(&pdata->enc_data->m_ogg_vs,&pdata->enc_data->m_ogg_pckt2); - pthread_mutex_unlock(&pdata->libogg_mutex); } } + pthread_mutex_unlock(&pdata->libogg_mutex); + +// pthread_mutex_unlock(&pdata->libvorbis_mutex); pdata->avd-=pdata->periodtime; free(buff->data); free(buff); } - + pdata->v_encoding_clean=1; + pthread_cond_signal(&pdata->vorbis_lib_clean); // SyncEncodeSoundBuffer(pdata,NULL); pthread_exit(&errno); } @@ -88,6 +97,7 @@ void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff){ float **vorbis_buffer; int count=0,i,j; int sampread=(buff!=NULL)?pdata->periodsize:0; +// pthread_mutex_lock(&pdata->libvorbis_mutex); vorbis_buffer=vorbis_analysis_buffer(&pdata->enc_data->m_vo_dsp,sampread); for(i=0;i<sampread;i++){ for(j=0;j<pdata->args.channels;j++){ @@ -98,6 +108,7 @@ void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff){ } vorbis_analysis_wrote(&pdata->enc_data->m_vo_dsp,sampread); + pthread_mutex_lock(&pdata->libogg_mutex); while(vorbis_analysis_blockout(&pdata->enc_data->m_vo_dsp,&pdata->enc_data->m_vo_block)==1){ @@ -108,9 +119,11 @@ void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff){ ogg_stream_packetin(&pdata->enc_data->m_ogg_vs,&pdata->enc_data->m_ogg_pckt2); } } - if(!pdata->running)pdata->enc_data->m_ogg_vs.e_o_s=1; pthread_mutex_unlock(&pdata->libogg_mutex); + if(!pdata->running)pdata->enc_data->m_ogg_vs.e_o_s=1; +// pthread_mutex_unlock(&pdata->libvorbis_mutex); + pdata->avd-=pdata->periodtime; } diff --git a/recordmydesktop/src/flush_to_ogg.c b/recordmydesktop/src/flush_to_ogg.c index 2390810..10d9553 100644 --- a/recordmydesktop/src/flush_to_ogg.c +++ b/recordmydesktop/src/flush_to_ogg.c @@ -65,6 +65,9 @@ void *FlushToOgg(ProgData *pdata){ double audiotime=0; double videotime=0; + pthread_mutex_t imut,vmut; + pthread_mutex_init(&imut,NULL); + pthread_mutex_init(&vmut,NULL); int working=1, th_st_fin=0, v_st_fin=(pdata->args.nosound); @@ -93,7 +96,12 @@ void *FlushToOgg(ProgData *pdata){ if(videoflag)ogg_page_cp(&videopage_copy,&videopage); pthread_mutex_unlock(&pdata->libogg_mutex); //we need the last page to properly close the stream - if(!videoflag)SyncEncodeImageBuffer(pdata); + if(!videoflag){ + if(!pdata->th_encoding_clean){ + pthread_cond_wait(&pdata->theora_lib_clean,&imut); + } + SyncEncodeImageBuffer(pdata); + } } if(!pdata->args.nosound && !v_st_fin &&!audioflag){ pthread_mutex_lock(&pdata->libogg_mutex); @@ -102,7 +110,12 @@ void *FlushToOgg(ProgData *pdata){ if(audioflag)ogg_page_cp(&audiopage_copy,&audiopage); pthread_mutex_unlock(&pdata->libogg_mutex); //we need the last page to properly close the stream - if(!audioflag)SyncEncodeSoundBuffer(pdata,NULL); + if(!audioflag){ + if(!pdata->v_encoding_clean){ + pthread_cond_wait(&pdata->vorbis_lib_clean,&vmut); + } + SyncEncodeSoundBuffer(pdata,NULL); + } } } if(th_st_fin)videoflag=0; @@ -150,8 +163,6 @@ void *FlushToOgg(ProgData *pdata){ working=(!th_st_fin || !v_st_fin); } - //last packages - pthread_mutex_lock(&pdata->libogg_mutex); ogg_stream_clear(&pdata->enc_data->m_ogg_ts); if(!pdata->args.nosound) @@ -161,7 +172,6 @@ void *FlushToOgg(ProgData *pdata){ // theora_clear(&pdata->enc_data->m_th_st); if(pdata->enc_data->fp)fclose(pdata->enc_data->fp); - fprintf(stderr,"\r \nDone.\nWritten %.0f bytes\n(%.0f of which were video data and %.0f audio data)\n\n",video_bytesout+audio_bytesout,video_bytesout,audio_bytesout); pthread_exit(&errno); } diff --git a/recordmydesktop/src/load_cache.c b/recordmydesktop/src/load_cache.c index 41568c9..7693774 100644 --- a/recordmydesktop/src/load_cache.c +++ b/recordmydesktop/src/load_cache.c @@ -194,8 +194,11 @@ void *LoadCache(ProgData *pdata){ } } } - SyncEncodeImageBuffer(pdata); - SyncEncodeSoundBuffer(pdata,sound_data); +// SyncEncodeImageBuffer(pdata); +// SyncEncodeSoundBuffer(pdata,sound_data); + pdata->v_encoding_clean=pdata->th_encoding_clean=1; + pthread_cond_signal(&pdata->theora_lib_clean); + pthread_cond_signal(&pdata->vorbis_lib_clean); fprintf(stdout,"\n"); CLEAR_FRAME(&frame) free(sound_data); diff --git a/recordmydesktop/src/recordmydesktop.c b/recordmydesktop/src/recordmydesktop.c index f15bdc9..0a9aa79 100644 --- a/recordmydesktop/src/recordmydesktop.c +++ b/recordmydesktop/src/recordmydesktop.c @@ -119,6 +119,8 @@ int main(int argc,char **argv){ 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); @@ -126,6 +128,9 @@ int main(int argc,char **argv){ 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; @@ -233,34 +238,31 @@ int main(int argc,char **argv){ pthread_join(image_capture_t,NULL); fprintf(stderr,"Shutting down."); //if no damage events have been received the thread will get stuck - pthread_cond_broadcast(&pdata.image_buffer_ready); - if(pdata.args.encOnTheFly) + 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){ - int *snd_exit; - pthread_join(sound_capture_t,(void *)(&snd_exit)); + 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){ - if(!(*snd_exit)) - pthread_join(sound_encode_t,NULL); - else{ - pthread_cancel(sound_encode_t); - exit_status=*snd_exit; - } + pthread_join(sound_encode_t,NULL); } else{ - if(!(*snd_exit)) - pthread_join(sound_cache_t,NULL); - else{ - pthread_cancel(sound_cache_t); - exit_status=*snd_exit; - } + pthread_join(sound_cache_t,NULL); } } else |