Commit 39cd3674 authored by Jean-Paul Saman's avatar Jean-Paul Saman

stream_out/transcode: replace PICTURE_RING_BUFFER with picture_fifo_t

The PICTURE_RING_BUFFER used a fixed size, which when depleted introduced
delays. Obtaining a new video buffer had to wait till the PICTURE_RING_BUFFER
is available again for the decoder. By removing the fixed PICTURE_RING_BUFFER
and replacing it by a picture_fifo_t this disadvantage is taken away.

The risk now is of course that the picture_fifo_t keeps growing.
parent de497369
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <vlc_filter.h> #include <vlc_filter.h>
#include <vlc_es.h> #include <vlc_es.h>
#include <vlc_codec.h> #include <vlc_codec.h>
#include <vlc_picture_fifo.h>
#define PICTURE_RING_SIZE 64 #define PICTURE_RING_SIZE 64
#define SUBPICTURE_RING_SIZE 20 #define SUBPICTURE_RING_SIZE 20
...@@ -23,8 +23,7 @@ struct sout_stream_sys_t ...@@ -23,8 +23,7 @@ struct sout_stream_sys_t
block_t *p_buffers; block_t *p_buffers;
vlc_mutex_t lock_out; vlc_mutex_t lock_out;
vlc_cond_t cond; vlc_cond_t cond;
picture_t * pp_pics[PICTURE_RING_SIZE]; picture_fifo_t *pp_pics;
int i_first_pic, i_last_pic;
bool b_error; bool b_error;
/* Audio */ /* Audio */
......
...@@ -80,22 +80,6 @@ static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic ) ...@@ -80,22 +80,6 @@ static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic )
static picture_t *video_new_buffer_decoder( decoder_t *p_dec ) static picture_t *video_new_buffer_decoder( decoder_t *p_dec )
{ {
sout_stream_sys_t *p_ssys = p_dec->p_owner->p_sys; sout_stream_sys_t *p_ssys = p_dec->p_owner->p_sys;
if( p_ssys->i_threads >= 1 )
{
int i_first_pic = p_ssys->i_first_pic;
if( p_ssys->i_first_pic != p_ssys->i_last_pic )
{
/* Encoder still has stuff to encode, wait to clear-up the list */
while( p_ssys->i_first_pic == i_first_pic )
{
#warning THERE IS DEFINITELY A BUG! LOCKING IS INSUFFICIENT!
msleep( 10000 );
barrier ();
}
}
}
p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec; p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
return picture_NewFromFormat( &p_dec->fmt_out.video ); return picture_NewFromFormat( &p_dec->fmt_out.video );
} }
...@@ -137,7 +121,7 @@ static void* EncoderThread( vlc_object_t* p_this ) ...@@ -137,7 +121,7 @@ static void* EncoderThread( vlc_object_t* p_this )
block_t *p_block; block_t *p_block;
vlc_mutex_lock( &p_sys->lock_out ); vlc_mutex_lock( &p_sys->lock_out );
while( p_sys->i_last_pic == p_sys->i_first_pic ) while( (p_pic = picture_fifo_Pop( p_sys->pp_pics )) == NULL )
{ {
vlc_cond_wait( &p_sys->cond, &p_sys->lock_out ); vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );
if( !vlc_object_alive (p_sys) || p_sys->b_error ) break; if( !vlc_object_alive (p_sys) || p_sys->b_error ) break;
...@@ -147,9 +131,6 @@ static void* EncoderThread( vlc_object_t* p_this ) ...@@ -147,9 +131,6 @@ static void* EncoderThread( vlc_object_t* p_this )
vlc_mutex_unlock( &p_sys->lock_out ); vlc_mutex_unlock( &p_sys->lock_out );
break; break;
} }
p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
p_sys->i_first_pic %= PICTURE_RING_SIZE;
vlc_mutex_unlock( &p_sys->lock_out ); vlc_mutex_unlock( &p_sys->lock_out );
video_timer_start( id->p_encoder ); video_timer_start( id->p_encoder );
...@@ -163,12 +144,6 @@ static void* EncoderThread( vlc_object_t* p_this ) ...@@ -163,12 +144,6 @@ static void* EncoderThread( vlc_object_t* p_this )
picture_Release( p_pic ); picture_Release( p_pic );
} }
while( p_sys->i_last_pic != p_sys->i_first_pic )
{
p_pic = p_sys->pp_pics[p_sys->i_first_pic++];
p_sys->i_first_pic %= PICTURE_RING_SIZE;
picture_Release( p_pic );
}
block_ChainRelease( p_sys->p_buffers ); block_ChainRelease( p_sys->p_buffers );
vlc_restorecancel (canc); vlc_restorecancel (canc);
...@@ -270,16 +245,22 @@ int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id ) ...@@ -270,16 +245,22 @@ int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
p_sys->id_video = id; p_sys->id_video = id;
vlc_mutex_init( &p_sys->lock_out ); vlc_mutex_init( &p_sys->lock_out );
vlc_cond_init( &p_sys->cond ); vlc_cond_init( &p_sys->cond );
memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) ); p_sys->pp_pics = picture_fifo_New();
p_sys->i_first_pic = 0; if( p_sys->pp_pics == NULL )
p_sys->i_last_pic = 0; {
msg_Err( p_stream, "cannot create picture fifo" );
module_unneed( id->p_decoder, id->p_decoder->p_module );
id->p_decoder->p_module = NULL;
free( id->p_decoder->p_owner );
return VLC_ENOMEM;
}
p_sys->p_buffers = NULL; p_sys->p_buffers = NULL;
p_sys->b_die = p_sys->b_error = 0; p_sys->b_die = p_sys->b_error = 0;
if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority ) ) if( vlc_thread_create( p_sys, "encoder", EncoderThread, i_priority ) )
{ {
msg_Err( p_stream, "cannot spawn encoder thread" ); msg_Err( p_stream, "cannot spawn encoder thread" );
module_unneed( id->p_decoder, id->p_decoder->p_module ); module_unneed( id->p_decoder, id->p_decoder->p_module );
id->p_decoder->p_module = 0; id->p_decoder->p_module = NULL;
free( id->p_decoder->p_owner ); free( id->p_decoder->p_owner );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -555,15 +536,20 @@ static int transcode_video_encoder_open( sout_stream_t *p_stream, ...@@ -555,15 +536,20 @@ static int transcode_video_encoder_open( sout_stream_t *p_stream,
void transcode_video_close( sout_stream_t *p_stream, void transcode_video_close( sout_stream_t *p_stream,
sout_stream_id_t *id ) sout_stream_id_t *id )
{ {
if( p_stream->p_sys->i_threads >= 1 ) sout_stream_sys_t *p_sys = p_stream->p_sys;
if( p_sys->i_threads >= 1 )
{ {
vlc_mutex_lock( &p_stream->p_sys->lock_out ); vlc_mutex_lock( &p_sys->lock_out );
vlc_object_kill( p_stream->p_sys ); vlc_object_kill( p_sys );
vlc_cond_signal( &p_stream->p_sys->cond ); vlc_cond_signal( &p_sys->cond );
vlc_mutex_unlock( &p_stream->p_sys->lock_out ); vlc_mutex_unlock( &p_sys->lock_out );
vlc_thread_join( p_stream->p_sys ); vlc_thread_join( p_sys );
vlc_mutex_destroy( &p_stream->p_sys->lock_out ); vlc_mutex_destroy( &p_sys->lock_out );
vlc_cond_destroy( &p_stream->p_sys->cond ); vlc_cond_destroy( &p_sys->cond );
picture_fifo_Delete( p_sys->pp_pics );
p_sys->pp_pics = NULL;
} }
video_timer_close( id->p_encoder ); video_timer_close( id->p_encoder );
...@@ -607,7 +593,6 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id, ...@@ -607,7 +593,6 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id,
return VLC_SUCCESS; return VLC_SUCCESS;
} }
while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) ) while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
{ {
subpicture_t *p_subpic = NULL; subpicture_t *p_subpic = NULL;
...@@ -780,14 +765,12 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id, ...@@ -780,14 +765,12 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id,
else else
{ {
vlc_mutex_lock( &p_sys->lock_out ); vlc_mutex_lock( &p_sys->lock_out );
p_sys->pp_pics[p_sys->i_last_pic++] = p_pic; picture_fifo_Push( p_sys->pp_pics, p_pic );
p_sys->i_last_pic %= PICTURE_RING_SIZE;
*out = p_sys->p_buffers; *out = p_sys->p_buffers;
p_sys->p_buffers = NULL; p_sys->p_buffers = NULL;
if( p_pic2 != NULL ) if( p_pic2 != NULL )
{ {
p_sys->pp_pics[p_sys->i_last_pic++] = p_pic2; picture_fifo_Push( p_sys->pp_pics, p_pic2 );
p_sys->i_last_pic %= PICTURE_RING_SIZE;
} }
vlc_cond_signal( &p_sys->cond ); vlc_cond_signal( &p_sys->cond );
vlc_mutex_unlock( &p_sys->lock_out ); vlc_mutex_unlock( &p_sys->lock_out );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment