summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--recordmydesktop/src/rmd_encode_image_buffer.c2
-rw-r--r--recordmydesktop/src/rmd_flush_to_ogg.c201
-rw-r--r--recordmydesktop/src/rmd_init_encoder.c5
-rw-r--r--recordmydesktop/src/rmd_types.h46
4 files changed, 129 insertions, 125 deletions
diff --git a/recordmydesktop/src/rmd_encode_image_buffer.c b/recordmydesktop/src/rmd_encode_image_buffer.c
index c96412e..f7bd5a8 100644
--- a/recordmydesktop/src/rmd_encode_image_buffer.c
+++ b/recordmydesktop/src/rmd_encode_image_buffer.c
@@ -57,8 +57,8 @@ void *rmdEncodeImageBuffer(ProgData *pdata) {
pthread_mutex_unlock(&pdata->yuv_mutex);
} else {
pthread_mutex_unlock(&pdata->yuv_mutex);
- if (theora_encode_packetout(&enc_data->m_th_st, 0, &enc_data->m_ogg_pckt1) == 1) {
+ if (theora_encode_packetout(&enc_data->m_th_st, 0, &enc_data->m_ogg_pckt1) == 1) {
pthread_mutex_lock(&pdata->libogg_mutex);
ogg_stream_packetin(&enc_data->m_ogg_ts, &enc_data->m_ogg_pckt1);
pdata->avd += pdata->frametime;
diff --git a/recordmydesktop/src/rmd_flush_to_ogg.c b/recordmydesktop/src/rmd_flush_to_ogg.c
index fa6b42e..6cd79fe 100644
--- a/recordmydesktop/src/rmd_flush_to_ogg.c
+++ b/recordmydesktop/src/rmd_flush_to_ogg.c
@@ -44,115 +44,120 @@
//will invalidate it. But we must have pages from
//both streams at every time in
//order to do correct multiplexing
-static void ogg_page_cp(ogg_page *new, ogg_page *old) {
- int i=0;
- register unsigned char *newp,*oldp;
-
- new->header_len=old->header_len;
- new->header=malloc(new->header_len);
- new->body_len=old->body_len;
- new->body=malloc(new->body_len);
-
- newp=new->header;
- oldp=old->header;
- for(i=0;i<new->header_len;i++)
- *(newp++)=*(oldp++);
- newp=new->body;
- oldp=old->body;
- for(i=0;i<new->body_len;i++)
- *(newp++)=*(oldp++);
+static void page_copy(ogg_page *new, ogg_page *old) {
+ new->header_len = old->header_len;
+ new->header = malloc(new->header_len);
+ new->body_len = old->body_len;
+ new->body = malloc(new->body_len);
+
+ memcpy(new->header, old->header, new->header_len);
+ memcpy(new->body, old->body, new->body_len);
}
+
//free our copy
-static void ogg_page_cp_free(ogg_page *pg) {
- pg->header_len=pg->body_len=0;
+static void page_free(ogg_page *pg) {
+ pg->header_len = pg->body_len = 0;
free(pg->header);
free(pg->body);
}
void *rmdFlushToOgg(ProgData *pdata) {
- int videoflag=0,audioflag=0;
- double video_bytesout=0,audio_bytesout=0;
- ogg_page videopage,//owned by libogg
- videopage_copy,//owned by the application
- audiopage,//owned by libogg
- audiopage_copy;//owned by the application
-
- double audiotime=0;
- double videotime=0;
- int working=1,
- th_st_fin=0,
- v_st_fin=(pdata->args.nosound);
- while (working) {
+ int videoflag = 0, audioflag = 0;
+ double video_bytesout = 0, audio_bytesout = 0;
+ ogg_page videopage, //owned by libogg
+ videopage_copy, //owned by the application
+ audiopage, //owned by libogg
+ audiopage_copy; //owned by the application
+
+ double audiotime = 0;
+ double videotime = 0;
+ int th_st_fin = 0,
+ v_st_fin = (pdata->args.nosound);
+
+ while (!(th_st_fin && v_st_fin)) {
int audio_or_video=0;
+
if (pdata->running) {
pthread_mutex_lock(&pdata->libogg_mutex);
if (!videoflag) {
- videoflag=ogg_stream_pageout(&pdata->enc_data->m_ogg_ts,
- &videopage);
- videotime=(videoflag)?
- theora_granule_time(&pdata->enc_data->m_th_st,
- ogg_page_granulepos(&videopage)):-1;
- if (videoflag)ogg_page_cp(&videopage_copy,&videopage);
+ videoflag = ogg_stream_pageout(&pdata->enc_data->m_ogg_ts, &videopage);
+ videotime = videoflag ? theora_granule_time(
+ &pdata->enc_data->m_th_st,
+ ogg_page_granulepos(&videopage)
+ ) : -1;
+
+ if (videoflag)
+ page_copy(&videopage_copy, &videopage);
+ }
+
+ if (!pdata->args.nosound && !audioflag) {
+ audioflag = ogg_stream_pageout(&pdata->enc_data->m_ogg_vs, &audiopage);
+ audiotime = audioflag ? vorbis_granule_time(
+ &pdata->enc_data->m_vo_dsp,
+ ogg_page_granulepos(&audiopage)
+ ) : -1;
+
+ if (audioflag)
+ page_copy(&audiopage_copy, &audiopage);
}
- if (!pdata->args.nosound)
- if (!audioflag) {
- audioflag=ogg_stream_pageout(&pdata->enc_data->m_ogg_vs,
- &audiopage);
- audiotime=(audioflag)?
- vorbis_granule_time(&pdata->enc_data->m_vo_dsp,
- ogg_page_granulepos(&audiopage)):-1;
- if (audioflag)ogg_page_cp(&audiopage_copy,&audiopage);
- }
pthread_mutex_unlock(&pdata->libogg_mutex);
} else {
if (!th_st_fin && !videoflag) {
pthread_mutex_lock(&pdata->libogg_mutex);
- videoflag=ogg_stream_flush(&pdata->enc_data->m_ogg_ts,
- &videopage);
- videotime=(videoflag)?
- theora_granule_time(&pdata->enc_data->m_th_st,
- ogg_page_granulepos(&videopage)):-1;
- if (videoflag)ogg_page_cp(&videopage_copy,&videopage);
+ videoflag = ogg_stream_flush(&pdata->enc_data->m_ogg_ts, &videopage);
+ videotime = videoflag ? theora_granule_time(
+ &pdata->enc_data->m_th_st,
+ ogg_page_granulepos(&videopage)
+ ) : -1;
+
+ if (videoflag)
+ page_copy(&videopage_copy, &videopage);
pthread_mutex_unlock(&pdata->libogg_mutex);
+
//we need the last page to properly close the stream
if (!videoflag) {
- if (!pdata->th_encoding_clean) {
- pthread_mutex_lock(&pdata->theora_lib_mutex);
- pthread_cond_wait(&pdata->theora_lib_clean,
- &pdata->theora_lib_mutex);
- pthread_mutex_unlock(&pdata->theora_lib_mutex);
- }
+ pthread_mutex_lock(&pdata->theora_lib_mutex);
+ while (!pdata->th_encoding_clean)
+ pthread_cond_wait(&pdata->theora_lib_clean, &pdata->theora_lib_mutex);
+ pthread_mutex_unlock(&pdata->theora_lib_mutex);
rmdSyncEncodeImageBuffer(pdata);
}
}
- if (!pdata->args.nosound && !v_st_fin &&!audioflag) {
+
+ if (!pdata->args.nosound && !v_st_fin && !audioflag) {
pthread_mutex_lock(&pdata->libogg_mutex);
- audioflag=ogg_stream_flush(&pdata->enc_data->m_ogg_vs,
- &audiopage);
- audiotime=(audioflag)?
- vorbis_granule_time(&pdata->enc_data->m_vo_dsp,
- ogg_page_granulepos(&audiopage)):-1;
- if (audioflag)ogg_page_cp(&audiopage_copy,&audiopage);
+ audioflag = ogg_stream_flush(&pdata->enc_data->m_ogg_vs, &audiopage);
+ audiotime = audioflag ? vorbis_granule_time(
+ &pdata->enc_data->m_vo_dsp,
+ ogg_page_granulepos(&audiopage)
+ ) : -1;
+
+ if (audioflag)
+ page_copy(&audiopage_copy, &audiopage);
pthread_mutex_unlock(&pdata->libogg_mutex);
+
//we need the last page to properly close the stream
if (!audioflag) {
- if (!pdata->v_encoding_clean) {
- pthread_mutex_lock(&pdata->vorbis_lib_mutex);
- pthread_cond_wait(&pdata->vorbis_lib_clean,
- &pdata->vorbis_lib_mutex);
- pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
- }
+ pthread_mutex_lock(&pdata->vorbis_lib_mutex);
+ while (!pdata->v_encoding_clean)
+ pthread_cond_wait(&pdata->vorbis_lib_clean, &pdata->vorbis_lib_mutex);
+ pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
rmdSyncEncodeSoundBuffer(pdata,NULL);
}
}
}
+
+#if 0
+ /* I don't understand what this is about, if these are finished we want to lose
+ * their pages?
+ */
if (th_st_fin)
videoflag=0;
if (v_st_fin)
audioflag=0;
-
+#endif
if ((!audioflag && !v_st_fin && !pdata->args.nosound) || (!videoflag && !th_st_fin)) {
usleep(10000);
continue;
@@ -163,50 +168,51 @@ void *rmdFlushToOgg(ProgData *pdata) {
} else if (!videoflag) {
audio_or_video=0;
} else {
- if (audiotime<videotime)
+ if (audiotime < videotime)
audio_or_video=0;
else
audio_or_video=1;
}
- if (audio_or_video==1) {
- video_bytesout+=fwrite( videopage_copy.header,1,
- videopage_copy.header_len,
- pdata->enc_data->fp);
+ if (audio_or_video == 1) {
+ video_bytesout += fwrite( videopage_copy.header, 1,
+ videopage_copy.header_len,
+ pdata->enc_data->fp);
- video_bytesout+=fwrite( videopage_copy.body,1,
- videopage_copy.body_len,
- pdata->enc_data->fp);
- videoflag=0;
+ video_bytesout += fwrite( videopage_copy.body, 1,
+ videopage_copy.body_len,
+ pdata->enc_data->fp);
+ videoflag = 0;
if (!pdata->running) {
pthread_mutex_lock(&pdata->libogg_mutex);
if (ogg_page_eos(&videopage_copy))
- th_st_fin=1;
+ th_st_fin = 1;
pthread_mutex_unlock(&pdata->libogg_mutex);
}
- ogg_page_cp_free(&videopage_copy);
+
+ page_free(&videopage_copy);
} else {
- audio_bytesout+=fwrite( audiopage_copy.header,1,
- audiopage_copy.header_len,
- pdata->enc_data->fp);
+ audio_bytesout += fwrite( audiopage_copy.header, 1,
+ audiopage_copy.header_len,
+ pdata->enc_data->fp);
- audio_bytesout+=fwrite( audiopage_copy.body,1,
- audiopage_copy.body_len,
- pdata->enc_data->fp);
- audioflag=0;
+ audio_bytesout += fwrite( audiopage_copy.body, 1,
+ audiopage_copy.body_len,
+ pdata->enc_data->fp);
+ audioflag = 0;
if (!pdata->running) {
pthread_mutex_lock(&pdata->libogg_mutex);
if (ogg_page_eos(&audiopage_copy))
- v_st_fin=1;
+ v_st_fin = 1;
pthread_mutex_unlock(&pdata->libogg_mutex);
}
- ogg_page_cp_free(&audiopage_copy);
- }
- working=(!th_st_fin || !v_st_fin);
+ page_free(&audiopage_copy);
+ }
}
+
pthread_mutex_lock(&pdata->libogg_mutex);
ogg_stream_clear(&pdata->enc_data->m_ogg_ts);
@@ -214,8 +220,8 @@ void *rmdFlushToOgg(ProgData *pdata) {
ogg_stream_clear(&pdata->enc_data->m_ogg_vs);
pthread_mutex_unlock(&pdata->libogg_mutex);
-//this always gives me a segfault :(
-// theora_clear(&pdata->enc_data->m_th_st);
+
+ theora_clear(&pdata->enc_data->m_th_st);
if (pdata->enc_data->fp)
fclose(pdata->enc_data->fp);
@@ -224,5 +230,6 @@ void *rmdFlushToOgg(ProgData *pdata) {
"(%.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/rmd_init_encoder.c b/recordmydesktop/src/rmd_init_encoder.c
index dee0ba3..da442f2 100644
--- a/recordmydesktop/src/rmd_init_encoder.c
+++ b/recordmydesktop/src/rmd_init_encoder.c
@@ -126,7 +126,7 @@ void rmdInitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready) {
//init ogg streams
//skeleton first
- ogg_stream_init(&m_ogg_skel,y0);
+ ogg_stream_init(&m_ogg_skel, y0);
m_add_fishead_packet(&m_ogg_skel);
if (ogg_stream_pageout(&m_ogg_skel,&skel_og_pg)!= 1) {
fprintf (stderr, "Internal Ogg library error.\n");
@@ -134,8 +134,6 @@ void rmdInitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready) {
}
fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
fwrite(skel_og_pg.body,1,skel_og_pg.body_len,enc_data_t->fp);
-
-
ogg_stream_init(&enc_data_t->m_ogg_ts,y1);
if (!pdata->args.nosound)
@@ -326,7 +324,6 @@ void rmdInitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready) {
}
fwrite(skel_og_pg.header,1,skel_og_pg.header_len,enc_data_t->fp);
-
//theora buffer allocation, if any
if (!buffer_ready) {
enc_data_t->yuv.y=(unsigned char *)malloc(enc_data_t->m_th_inf.height*
diff --git a/recordmydesktop/src/rmd_types.h b/recordmydesktop/src/rmd_types.h
index cd2cca4..d80f835 100644
--- a/recordmydesktop/src/rmd_types.h
+++ b/recordmydesktop/src/rmd_types.h
@@ -263,30 +263,30 @@ struct _ProgData {
Display *dpy; //curtrent display
/** Mutexes*/
pthread_mutex_t sound_buffer_mutex,
- snd_buff_ready_mutex,
- img_buff_ready_mutex,
- theora_lib_mutex,
- vorbis_lib_mutex,
- libogg_mutex, //libogg is not thread safe,
- 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
- //and then u and v so this was needed
- //to avoid wrong coloring to render
- //Currently this mutex only prevents
- //the cursor from flickering
+ snd_buff_ready_mutex,
+ img_buff_ready_mutex,
+ theora_lib_mutex, //serializes access to th_encoding_clean w/theora_lib_clean
+ vorbis_lib_mutex, //serializes acces to v_encoding_clean w/vorbis_lib_clean
+ libogg_mutex, //libogg is not thread safe,
+ 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
+ //and then u and v so this was needed
+ //to avoid wrong coloring to render
+ //Currently this mutex only prevents
+ //the cursor from flickering
/**Condition Variables*/
- pthread_cond_t time_cond, //this gets a broadcast by the handler
- //whenever it's time to get a screenshot
- pause_cond, //this is blocks execution,
- //when program is paused
- sound_data_read, //a buffer is ready for proccessing
- 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
+ pthread_cond_t time_cond, //this gets a signal by the handler
+ //whenever it's time to get a screenshot
+ pause_cond, //this is blocks execution,
+ //when program is paused
+ sound_data_read, //a buffer is ready for proccessing
+ 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
/**Buffers,Flags and other vars*/
unsigned char *dummy_pointer, //a dummy pointer to be drawn
//in every frame
© All Rights Reserved