Commit 857a43d1 authored by Laurent Aimar's avatar Laurent Aimar

Split up DecoderDecode function.

No functionnal changes.
parent 2624f9af
...@@ -53,7 +53,7 @@ static decoder_t *CreateDecoder( input_thread_t *, es_format_t *, int, sout_inst ...@@ -53,7 +53,7 @@ static decoder_t *CreateDecoder( input_thread_t *, es_format_t *, int, sout_inst
static void DeleteDecoder( decoder_t * ); static void DeleteDecoder( decoder_t * );
static void *DecoderThread( vlc_object_t * ); static void *DecoderThread( vlc_object_t * );
static int DecoderDecode( decoder_t * p_dec, block_t *p_block ); static int DecoderProcess( decoder_t * p_dec, block_t *p_block );
static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date ); static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date );
/* Buffers allocation callbacks for the decoders */ /* Buffers allocation callbacks for the decoders */
...@@ -109,14 +109,18 @@ struct decoder_owner_sys_t ...@@ -109,14 +109,18 @@ struct decoder_owner_sys_t
vout_thread_t *p_vout; vout_thread_t *p_vout;
/* -- Theses variables need locking on read *and* write -- */ /* -- Theses variables need locking on read *and* write -- */
/* */
/* Pause */ /* Pause */
bool b_paused; bool b_paused;
mtime_t i_pause_date; mtime_t i_pause_date;
/* CC */ /* CC */
bool b_cc_supported; struct
bool pb_cc_present[4]; {
decoder_t *pp_cc[4]; bool b_supported;
bool pb_present[4];
decoder_t *pp_decoder[4];
} cc;
/* Delay */ /* Delay */
mtime_t i_ts_delay; mtime_t i_ts_delay;
...@@ -304,7 +308,7 @@ void input_DecoderDelete( decoder_t *p_dec ) ...@@ -304,7 +308,7 @@ void input_DecoderDelete( decoder_t *p_dec )
} }
/* */ /* */
if( p_dec->p_owner->b_cc_supported ) if( p_dec->p_owner->cc.b_supported )
{ {
int i; int i;
for( i = 0; i < 4; i++ ) for( i = 0; i < 4; i++ )
...@@ -359,7 +363,7 @@ void input_DecoderDecode( decoder_t * p_dec, block_t *p_block ) ...@@ -359,7 +363,7 @@ void input_DecoderDecode( decoder_t * p_dec, block_t *p_block )
} }
else else
{ {
DecoderDecode( p_dec, p_block ); DecoderProcess( p_dec, p_block );
} }
} }
} }
...@@ -381,7 +385,7 @@ void input_DecoderIsCcPresent( decoder_t *p_dec, bool pb_present[4] ) ...@@ -381,7 +385,7 @@ void input_DecoderIsCcPresent( decoder_t *p_dec, bool pb_present[4] )
vlc_mutex_lock( &p_owner->lock ); vlc_mutex_lock( &p_owner->lock );
for( i = 0; i < 4; i++ ) for( i = 0; i < 4; i++ )
pb_present[i] = p_owner->pb_cc_present[i]; pb_present[i] = p_owner->cc.pb_present[i];
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
} }
int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel ) int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel )
...@@ -390,7 +394,7 @@ int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel ) ...@@ -390,7 +394,7 @@ int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel )
//msg_Warn( p_dec, "input_DecoderSetCcState: %d @%d", b_decode, i_channel ); //msg_Warn( p_dec, "input_DecoderSetCcState: %d @%d", b_decode, i_channel );
if( i_channel < 0 || i_channel >= 4 || !p_owner->pb_cc_present[i_channel] ) if( i_channel < 0 || i_channel >= 4 || !p_owner->cc.pb_present[i_channel] )
return VLC_EGENERIC; return VLC_EGENERIC;
if( b_decode ) if( b_decode )
...@@ -423,7 +427,7 @@ int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel ) ...@@ -423,7 +427,7 @@ int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel )
p_cc->p_owner->p_clock = p_owner->p_clock; p_cc->p_owner->p_clock = p_owner->p_clock;
vlc_mutex_lock( &p_owner->lock ); vlc_mutex_lock( &p_owner->lock );
p_owner->pp_cc[i_channel] = p_cc; p_owner->cc.pp_decoder[i_channel] = p_cc;
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
} }
else else
...@@ -431,8 +435,8 @@ int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel ) ...@@ -431,8 +435,8 @@ int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel )
decoder_t *p_cc; decoder_t *p_cc;
vlc_mutex_lock( &p_owner->lock ); vlc_mutex_lock( &p_owner->lock );
p_cc = p_owner->pp_cc[i_channel]; p_cc = p_owner->cc.pp_decoder[i_channel];
p_owner->pp_cc[i_channel] = NULL; p_owner->cc.pp_decoder[i_channel] = NULL;
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
if( p_cc ) if( p_cc )
...@@ -450,11 +454,11 @@ int input_DecoderGetCcState( decoder_t *p_dec, bool *pb_decode, int i_channel ) ...@@ -450,11 +454,11 @@ int input_DecoderGetCcState( decoder_t *p_dec, bool *pb_decode, int i_channel )
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
*pb_decode = false; *pb_decode = false;
if( i_channel < 0 || i_channel >= 4 || !p_owner->pb_cc_present[i_channel] ) if( i_channel < 0 || i_channel >= 4 || !p_owner->cc.pb_present[i_channel] )
return VLC_EGENERIC; return VLC_EGENERIC;
vlc_mutex_lock( &p_owner->lock ); vlc_mutex_lock( &p_owner->lock );
*pb_decode = p_owner->pp_cc[i_channel] != NULL; *pb_decode = p_owner->cc.pp_decoder[i_channel] != NULL;
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -632,13 +636,13 @@ static decoder_t * CreateDecoder( input_thread_t *p_input, ...@@ -632,13 +636,13 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
} }
} }
/* */ /* */
p_owner->b_cc_supported = false; p_owner->cc.b_supported = false;
if( i_object_type == VLC_OBJECT_DECODER ) if( i_object_type == VLC_OBJECT_DECODER )
{ {
if( p_owner->p_packetizer && p_owner->p_packetizer->pf_get_cc ) if( p_owner->p_packetizer && p_owner->p_packetizer->pf_get_cc )
p_owner->b_cc_supported = true; p_owner->cc.b_supported = true;
if( p_dec->pf_get_cc ) if( p_dec->pf_get_cc )
p_owner->b_cc_supported = true; p_owner->cc.b_supported = true;
} }
vlc_mutex_init( &p_owner->lock ); vlc_mutex_init( &p_owner->lock );
...@@ -647,8 +651,8 @@ static decoder_t * CreateDecoder( input_thread_t *p_input, ...@@ -647,8 +651,8 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
p_owner->i_pause_date = 0; p_owner->i_pause_date = 0;
for( i = 0; i < 4; i++ ) for( i = 0; i < 4; i++ )
{ {
p_owner->pb_cc_present[i] = false; p_owner->cc.pb_present[i] = false;
p_owner->pp_cc[i] = NULL; p_owner->cc.pp_decoder[i] = NULL;
} }
p_owner->i_ts_delay = 0; p_owner->i_ts_delay = 0;
return p_dec; return p_dec;
...@@ -672,11 +676,11 @@ static void *DecoderThread( vlc_object_t *p_this ) ...@@ -672,11 +676,11 @@ static void *DecoderThread( vlc_object_t *p_this )
{ {
if( ( p_block = block_FifoGet( p_owner->p_fifo ) ) == NULL ) if( ( p_block = block_FifoGet( p_owner->p_fifo ) ) == NULL )
{ {
p_dec->b_error = 1; p_dec->b_error = true;
break; break;
} }
if( DecoderDecode( p_dec, p_block ) != VLC_SUCCESS ) if( DecoderProcess( p_dec, p_block ) != VLC_SUCCESS )
break; break;
} }
...@@ -802,12 +806,12 @@ static void DecoderAoutBufferFixTs( aout_buffer_t *p_buffer, int *pi_rate, ...@@ -802,12 +806,12 @@ static void DecoderAoutBufferFixTs( aout_buffer_t *p_buffer, int *pi_rate,
if( !p_buffer->start_date && !p_buffer->end_date ) if( !p_buffer->start_date && !p_buffer->end_date )
*pi_rate = input_clock_GetRate( p_clock ); *pi_rate = input_clock_GetRate( p_clock );
if( p_buffer->start_date ) if( p_buffer->start_date > 0 )
p_buffer->start_date = p_buffer->start_date =
input_clock_GetTS( p_clock, pi_rate, input_clock_GetTS( p_clock, pi_rate,
i_ts_delay, p_buffer->start_date + i_es_delay ); i_ts_delay, p_buffer->start_date + i_es_delay );
if( p_buffer->end_date ) if( p_buffer->end_date > 0 )
p_buffer->end_date = p_buffer->end_date =
input_clock_GetTS( p_clock, pi_rate, input_clock_GetTS( p_clock, pi_rate,
i_ts_delay, p_buffer->end_date + i_es_delay ); i_ts_delay, p_buffer->end_date + i_es_delay );
...@@ -820,7 +824,7 @@ static void DecoderVoutBufferFixTs( picture_t *p_picture, int *pi_rate, ...@@ -820,7 +824,7 @@ static void DecoderVoutBufferFixTs( picture_t *p_picture, int *pi_rate,
if( !p_clock ) if( !p_clock )
return; return;
if( p_picture->date ) if( p_picture->date > 0 )
p_picture->date = p_picture->date =
input_clock_GetTS( p_clock, pi_rate, input_clock_GetTS( p_clock, pi_rate,
i_ts_delay, p_picture->date + i_es_delay ); i_ts_delay, p_picture->date + i_es_delay );
...@@ -836,12 +840,12 @@ static void DecoderSpuBufferFixTs( subpicture_t *p_subpic, ...@@ -836,12 +840,12 @@ static void DecoderSpuBufferFixTs( subpicture_t *p_subpic,
if( !p_clock ) if( !p_clock )
return; return;
if( p_subpic->i_start ) if( p_subpic->i_start > 0 )
p_subpic->i_start = p_subpic->i_start =
input_clock_GetTS( p_clock, NULL, input_clock_GetTS( p_clock, NULL,
i_ts_delay, p_subpic->i_start + i_es_delay ); i_ts_delay, p_subpic->i_start + i_es_delay );
if( p_subpic->i_stop ) if( p_subpic->i_stop > 0 )
p_subpic->i_stop = p_subpic->i_stop =
input_clock_GetTS( p_clock, NULL, input_clock_GetTS( p_clock, NULL,
i_ts_delay, p_subpic->i_stop + i_es_delay ); i_ts_delay, p_subpic->i_stop + i_es_delay );
...@@ -966,7 +970,7 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc ) ...@@ -966,7 +970,7 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
assert( p_dec_cc->pf_get_cc != NULL ); assert( p_dec_cc->pf_get_cc != NULL );
/* Do not try retreiving CC if not wanted (sout) or cannot be retreived */ /* Do not try retreiving CC if not wanted (sout) or cannot be retreived */
if( !p_owner->b_cc_supported ) if( !p_owner->cc.b_supported )
return; return;
p_cc = p_dec_cc->pf_get_cc( p_dec_cc, pb_present ); p_cc = p_dec_cc->pf_get_cc( p_dec_cc, pb_present );
...@@ -976,20 +980,20 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc ) ...@@ -976,20 +980,20 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
vlc_mutex_lock( &p_owner->lock ); vlc_mutex_lock( &p_owner->lock );
for( i = 0, i_cc_decoder = 0; i < 4; i++ ) for( i = 0, i_cc_decoder = 0; i < 4; i++ )
{ {
p_owner->pb_cc_present[i] |= pb_present[i]; p_owner->cc.pb_present[i] |= pb_present[i];
if( p_owner->pp_cc[i] ) if( p_owner->cc.pp_decoder[i] )
i_cc_decoder++; i_cc_decoder++;
} }
for( i = 0; i < 4; i++ ) for( i = 0; i < 4; i++ )
{ {
if( !p_owner->pp_cc[i] ) if( !p_owner->cc.pp_decoder[i] )
continue; continue;
if( i_cc_decoder > 1 ) if( i_cc_decoder > 1 )
DecoderDecode( p_owner->pp_cc[i], block_Duplicate( p_cc ) ); DecoderProcess( p_owner->cc.pp_decoder[i], block_Duplicate( p_cc ) );
else else
DecoderDecode( p_owner->pp_cc[i], p_cc ); DecoderProcess( p_owner->cc.pp_decoder[i], p_cc );
i_cc_decoder--; i_cc_decoder--;
} }
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
...@@ -1242,242 +1246,275 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) ...@@ -1242,242 +1246,275 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
} }
} }
/** /* This function process a block for sout
* Decode a block
*
* \param p_dec the decoder object
* \param p_block the block to decode
* \return VLC_SUCCESS or an error code
*/ */
static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block )
{ {
decoder_owner_sys_t *p_owner = (decoder_owner_sys_t *)p_dec->p_owner; decoder_owner_sys_t *p_owner = (decoder_owner_sys_t *)p_dec->p_owner;
const bool b_telx = p_dec->fmt_in.i_codec == VLC_FOURCC('t','e','l','x'); const bool b_telx = p_dec->fmt_in.i_codec == VLC_FOURCC('t','e','l','x');
block_t *p_sout_block;
if( p_block && p_block->i_buffer <= 0 ) while( ( p_sout_block =
p_dec->pf_packetize( p_dec, p_block ? &p_block : NULL ) ) )
{ {
block_Release( p_block ); if( !p_owner->p_sout_input )
return VLC_SUCCESS;
}
#ifdef ENABLE_SOUT
if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
{
block_t *p_sout_block;
while( ( p_sout_block =
p_dec->pf_packetize( p_dec, p_block ? &p_block : NULL ) ) )
{ {
if( !p_owner->p_sout_input ) es_format_Copy( &p_owner->sout, &p_dec->fmt_out );
p_owner->sout.i_group = p_dec->fmt_in.i_group;
p_owner->sout.i_id = p_dec->fmt_in.i_id;
if( p_dec->fmt_in.psz_language )
{ {
es_format_Copy( &p_owner->sout, &p_dec->fmt_out ); if( p_owner->sout.psz_language )
free( p_owner->sout.psz_language );
p_owner->sout.psz_language =
strdup( p_dec->fmt_in.psz_language );
}
p_owner->sout.i_group = p_dec->fmt_in.i_group; p_owner->p_sout_input =
p_owner->sout.i_id = p_dec->fmt_in.i_id; sout_InputNew( p_owner->p_sout,
if( p_dec->fmt_in.psz_language ) &p_owner->sout );
{
if( p_owner->sout.psz_language )
free( p_owner->sout.psz_language );
p_owner->sout.psz_language =
strdup( p_dec->fmt_in.psz_language );
}
p_owner->p_sout_input = if( p_owner->p_sout_input == NULL )
sout_InputNew( p_owner->p_sout, {
&p_owner->sout ); msg_Err( p_dec, "cannot create packetizer output (%4.4s)",
(char *)&p_owner->sout.i_codec );
p_dec->b_error = true;
if( p_owner->p_sout_input == NULL ) while( p_sout_block )
{ {
msg_Err( p_dec, "cannot create packetizer output (%4.4s)", block_t *p_next = p_sout_block->p_next;
(char *)&p_owner->sout.i_codec ); block_Release( p_sout_block );
p_dec->b_error = true; p_sout_block = p_next;
while( p_sout_block )
{
block_t *p_next = p_sout_block->p_next;
block_Release( p_sout_block );
p_sout_block = p_next;
}
break;
} }
break;
} }
}
while( p_sout_block ) while( p_sout_block )
{ {
block_t *p_next = p_sout_block->p_next; block_t *p_next = p_sout_block->p_next;
p_sout_block->p_next = NULL; p_sout_block->p_next = NULL;
DecoderWaitUnpause( p_dec ); DecoderWaitUnpause( p_dec );
mtime_t i_ts_delay; mtime_t i_ts_delay;
mtime_t i_es_delay; mtime_t i_es_delay;
DecoderGetDelays( p_dec, &i_ts_delay, &i_es_delay ); DecoderGetDelays( p_dec, &i_ts_delay, &i_es_delay );
DecoderSoutBufferFixTs( p_sout_block, p_owner->p_clock, DecoderSoutBufferFixTs( p_sout_block, p_owner->p_clock,
i_ts_delay, i_es_delay, b_telx ); i_ts_delay, i_es_delay, b_telx );
sout_InputSendBuffer( p_owner->p_sout_input, sout_InputSendBuffer( p_owner->p_sout_input,
p_sout_block ); p_sout_block );
p_sout_block = p_next; p_sout_block = p_next;
} }
/* For now it's enough, as only sout impact on this flag */ /* For now it's enough, as only sout impact on this flag */
if( p_owner->p_sout->i_out_pace_nocontrol > 0 && if( p_owner->p_sout->i_out_pace_nocontrol > 0 &&
p_owner->p_input->p->b_out_pace_control ) p_owner->p_input->p->b_out_pace_control )
{ {
msg_Dbg( p_dec, "switching to sync mode" ); msg_Dbg( p_dec, "switching to sync mode" );
p_owner->p_input->p->b_out_pace_control = false; p_owner->p_input->p->b_out_pace_control = false;
} }
else if( p_owner->p_sout->i_out_pace_nocontrol <= 0 && else if( p_owner->p_sout->i_out_pace_nocontrol <= 0 &&
!p_owner->p_input->p->b_out_pace_control ) !p_owner->p_input->p->b_out_pace_control )
{ {
msg_Dbg( p_dec, "switching to async mode" ); msg_Dbg( p_dec, "switching to async mode" );
p_owner->p_input->p->b_out_pace_control = true; p_owner->p_input->p->b_out_pace_control = true;
}
} }
} }
else }
#endif
if( p_dec->fmt_in.i_cat == AUDIO_ES ) /* This function process a video block
*/
static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block )
{
decoder_owner_sys_t *p_owner = (decoder_owner_sys_t *)p_dec->p_owner;
if( p_block )
DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
if( p_owner->p_packetizer )
{ {
if( p_block ) block_t *p_packetized_block;
DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block ); decoder_t *p_packetizer = p_owner->p_packetizer;
if( p_owner->p_packetizer ) while( (p_packetized_block =
p_packetizer->pf_packetize( p_packetizer, p_block ? &p_block : NULL )) )
{ {
block_t *p_packetized_block; if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
decoder_t *p_packetizer = p_owner->p_packetizer;
while( (p_packetized_block =
p_packetizer->pf_packetize( p_packetizer, p_block ? &p_block : NULL )) )
{ {
if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra ) es_format_Clean( &p_dec->fmt_in );
{ es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
es_format_Clean( &p_dec->fmt_in ); }
es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out ); if( p_packetizer->pf_get_cc )
} DecoderGetCc( p_dec, p_packetizer );
while( p_packetized_block ) while( p_packetized_block )
{ {
block_t *p_next = p_packetized_block->p_next; block_t *p_next = p_packetized_block->p_next;
p_packetized_block->p_next = NULL; p_packetized_block->p_next = NULL;
DecoderDecodeAudio( p_dec, p_packetized_block ); DecoderDecodeVideo( p_dec, p_packetized_block );
p_packetized_block = p_next; p_packetized_block = p_next;
}
} }
} }
else if( p_block )
{
DecoderDecodeAudio( p_dec, p_block );
}
} }
else if( p_dec->fmt_in.i_cat == VIDEO_ES ) else if( p_block )
{ {
if( p_block ) DecoderDecodeVideo( p_dec, p_block );
DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block ); }
}
if( p_owner->p_packetizer ) /* This function process a audio block
{ */
block_t *p_packetized_block; static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block )
decoder_t *p_packetizer = p_owner->p_packetizer; {
decoder_owner_sys_t *p_owner = (decoder_owner_sys_t *)p_dec->p_owner;
if( p_block )
DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
if( p_owner->p_packetizer )
{
block_t *p_packetized_block;
decoder_t *p_packetizer = p_owner->p_packetizer;
while( (p_packetized_block = while( (p_packetized_block =
p_packetizer->pf_packetize( p_packetizer, p_block ? &p_block : NULL )) ) p_packetizer->pf_packetize( p_packetizer, p_block ? &p_block : NULL )) )
{
if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
{ {
if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra ) es_format_Clean( &p_dec->fmt_in );
{ es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
es_format_Clean( &p_dec->fmt_in ); }
es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
}
if( p_packetizer->pf_get_cc )
DecoderGetCc( p_dec, p_packetizer );
while( p_packetized_block ) while( p_packetized_block )
{ {
block_t *p_next = p_packetized_block->p_next; block_t *p_next = p_packetized_block->p_next;
p_packetized_block->p_next = NULL; p_packetized_block->p_next = NULL;
DecoderDecodeVideo( p_dec, p_packetized_block ); DecoderDecodeAudio( p_dec, p_packetized_block );
p_packetized_block = p_next; p_packetized_block = p_next;
}
} }
} }
else if( p_block )
{
DecoderDecodeVideo( p_dec, p_block );
}
} }
else if( p_dec->fmt_in.i_cat == SPU_ES ) else if( p_block )
{ {
input_thread_t *p_input = p_owner->p_input; DecoderDecodeAudio( p_dec, p_block );
vout_thread_t *p_vout; }
subpicture_t *p_spu; }
bool b_flushing = p_owner->i_preroll_end == INT64_MAX;
bool b_flush = false;
if( p_block ) /* This function process a subtitle block
{ */
DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block ); static void DecoderProcessSpu( decoder_t *p_dec, block_t *p_block )
b_flush = (p_block->i_flags & BLOCK_FLAG_CORE_FLUSH) != 0; {
} decoder_owner_sys_t *p_owner = (decoder_owner_sys_t *)p_dec->p_owner;
const bool b_telx = p_dec->fmt_in.i_codec == VLC_FOURCC('t','e','l','x');
if( !b_flushing && b_flush && p_owner->p_spu_vout ) input_thread_t *p_input = p_owner->p_input;
{ vout_thread_t *p_vout;
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE ); subpicture_t *p_spu;
bool b_flushing = p_owner->i_preroll_end == INT64_MAX;
bool b_flush = false;
if( p_vout && p_owner->p_spu_vout == p_vout ) if( p_block )
spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR, {
p_owner->i_spu_channel ); DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
b_flush = (p_block->i_flags & BLOCK_FLAG_CORE_FLUSH) != 0;
}
if( p_vout ) if( !b_flushing && b_flush && p_owner->p_spu_vout )
vlc_object_release( p_vout ); {
} p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
while( (p_spu = p_dec->pf_decode_sub( p_dec, p_block ? &p_block : NULL ) ) ) if( p_vout && p_owner->p_spu_vout == p_vout )
{ spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR,
vlc_mutex_lock( &p_input->p->counters.counters_lock ); p_owner->i_spu_channel );
stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_sub, 1, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_vout )
if( p_vout && p_owner->p_spu_vout == p_vout ) vlc_object_release( p_vout );
{ }
/* Preroll does not work very well with subtitle */
if( p_spu->i_start > 0 &&
p_spu->i_start < p_owner->i_preroll_end &&
( p_spu->i_stop <= 0 || p_spu->i_stop < p_owner->i_preroll_end ) )
{
subpicture_Delete( p_spu );
}
else
{
DecoderWaitUnpause( p_dec );
mtime_t i_ts_delay; while( (p_spu = p_dec->pf_decode_sub( p_dec, p_block ? &p_block : NULL ) ) )
mtime_t i_es_delay; {
DecoderGetDelays( p_dec, &i_ts_delay, &i_es_delay ); vlc_mutex_lock( &p_input->p->counters.counters_lock );
stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_sub, 1, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
DecoderSpuBufferFixTs( p_spu, p_owner->p_clock, i_ts_delay, i_es_delay, b_telx ); p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
spu_DisplaySubpicture( p_vout->p_spu, p_spu ); if( p_vout && p_owner->p_spu_vout == p_vout )
} {
/* Preroll does not work very well with subtitle */
if( p_spu->i_start > 0 &&
p_spu->i_start < p_owner->i_preroll_end &&
( p_spu->i_stop <= 0 || p_spu->i_stop < p_owner->i_preroll_end ) )
{
subpicture_Delete( p_spu );
} }
else else
{ {
msg_Warn( p_dec, "no vout found, leaking subpicture" ); DecoderWaitUnpause( p_dec );
mtime_t i_ts_delay;
mtime_t i_es_delay;
DecoderGetDelays( p_dec, &i_ts_delay, &i_es_delay );
DecoderSpuBufferFixTs( p_spu, p_owner->p_clock, i_ts_delay, i_es_delay, b_telx );
spu_DisplaySubpicture( p_vout->p_spu, p_spu );
} }
if( p_vout )
vlc_object_release( p_vout );
} }
else
{
msg_Warn( p_dec, "no vout found, leaking subpicture" );
}
if( p_vout )
vlc_object_release( p_vout );
}
}
/**
* Decode a block
*
* \param p_dec the decoder object
* \param p_block the block to decode
* \return VLC_SUCCESS or an error code
*/
static int DecoderProcess( decoder_t *p_dec, block_t *p_block )
{
if( p_block && p_block->i_buffer <= 0 )
{
block_Release( p_block );
return VLC_SUCCESS;
}
#ifdef ENABLE_SOUT
if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
{
DecoderProcessSout( p_dec, p_block );
}
else
#endif
if( p_dec->fmt_in.i_cat == AUDIO_ES )
{
DecoderProcessAudio( p_dec, p_block );
}
else if( p_dec->fmt_in.i_cat == VIDEO_ES )
{
DecoderProcessVideo( p_dec, p_block );
}
else if( p_dec->fmt_in.i_cat == SPU_ES )
{
DecoderProcessSpu( p_dec, p_block );
} }
else else
{ {
msg_Err( p_dec, "unknown ES format" ); msg_Err( p_dec, "unknown ES format" );
p_dec->b_error = 1; p_dec->b_error = true;
} }
return p_dec->b_error ? VLC_EGENERIC : VLC_SUCCESS; return p_dec->b_error ? VLC_EGENERIC : VLC_SUCCESS;
......
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