diff options
Diffstat (limited to 'recordmydesktop')
| -rw-r--r-- | recordmydesktop/src/rmd_encode_image_buffer.c | 2 | ||||
| -rw-r--r-- | recordmydesktop/src/rmd_flush_to_ogg.c | 201 | ||||
| -rw-r--r-- | recordmydesktop/src/rmd_init_encoder.c | 5 | ||||
| -rw-r--r-- | recordmydesktop/src/rmd_types.h | 46 | 
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 | 
