summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--recordmydesktop/include/recordmydesktop.h12
-rw-r--r--recordmydesktop/src/cache_audio.c8
-rw-r--r--recordmydesktop/src/cache_frame.c3
-rw-r--r--recordmydesktop/src/encode_image_buffer.c10
-rw-r--r--recordmydesktop/src/encode_sound_buffer.c25
-rw-r--r--recordmydesktop/src/flush_to_ogg.c20
-rw-r--r--recordmydesktop/src/load_cache.c7
-rw-r--r--recordmydesktop/src/recordmydesktop.c36
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
© All Rights Reserved