diff options
author | iovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a> | 2006-12-10 14:56:00 +0000 |
---|---|---|
committer | iovar <iovar@f606c939-3180-4ac9-a4b8-4b8779d57d0a> | 2006-12-10 14:56:00 +0000 |
commit | 9ed6f5963df909cb4710b7dac1ca27d9e6147f90 (patch) | |
tree | 3d9d663bae2674bc1759b2bcf14a50ad0c847dbe /recordmydesktop/src | |
parent | cef7f3227bc7479254e3d2173680825291c9deb3 (diff) |
Many changes, mostly focusing around proper interleaving of
theora and vorbis streams (which should now be correct).
Also missing eos has been taken care.
New condition variables have been added to signal end of encoding threads
and avoid lockups, caused by the new configuration for eos.
Also the main thread handles better the joins now, making sure that
the encoding threads do not get stuck waiting.
git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@230 f606c939-3180-4ac9-a4b8-4b8779d57d0a
Diffstat (limited to 'recordmydesktop/src')
-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 |
7 files changed, 76 insertions, 33 deletions
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 |