Commit 0f3c2024 authored by François Cartegnie's avatar François Cartegnie 🤞

input: decoder: split into decoder_QueueVideo / QueueCC

Captions are sent in picture decode order. Picture output for each
block is not guaranteed.

Split to dedicated queuing.

reverts 4079bb24
parent 28c1d48f
...@@ -174,10 +174,11 @@ struct decoder_t ...@@ -174,10 +174,11 @@ struct decoder_t
int (*pf_get_display_rate)( decoder_t * ); int (*pf_get_display_rate)( decoder_t * );
/* XXX use decoder_QueueVideo or decoder_QueueVideoWithCc */ /* XXX use decoder_QueueVideo or decoder_QueueVideoWithCc */
int (*pf_queue_video)( decoder_t *, picture_t *, block_t *p_cc, int (*pf_queue_video)( decoder_t *, picture_t * );
bool p_cc_present[4] );
/* XXX use decoder_QueueAudio */ /* XXX use decoder_QueueAudio */
int (*pf_queue_audio)( decoder_t *, block_t * ); int (*pf_queue_audio)( decoder_t *, block_t * );
/* XXX use decoder_QueueCC */
int (*pf_queue_cc)( decoder_t *, block_t *, bool p_cc_present[4] );
/* XXX use decoder_QueueSub */ /* XXX use decoder_QueueSub */
int (*pf_queue_sub)( decoder_t *, subpicture_t *); int (*pf_queue_sub)( decoder_t *, subpicture_t *);
void *p_queue_ctx; void *p_queue_ctx;
...@@ -300,22 +301,23 @@ static inline int decoder_QueueVideo( decoder_t *dec, picture_t *p_pic ) ...@@ -300,22 +301,23 @@ static inline int decoder_QueueVideo( decoder_t *dec, picture_t *p_pic )
{ {
assert( p_pic->p_next == NULL ); assert( p_pic->p_next == NULL );
assert( dec->pf_queue_video != NULL ); assert( dec->pf_queue_video != NULL );
return dec->pf_queue_video( dec, p_pic, NULL, NULL ); return dec->pf_queue_video( dec, p_pic );
} }
/** /**
* This function queues a single picture with CC to the video output * This function queues queues the Closed Captions
* *
* This function also queues the Closed Captions associated with the picture. * \return 0 if queued, -1 on error
*
* \return 0 if the picture is queued, -1 on error
*/ */
static inline int decoder_QueueVideoWithCc( decoder_t *dec, picture_t *p_pic, static inline int decoder_QueueCc( decoder_t *dec, block_t *p_cc,
block_t *p_cc, bool p_cc_present[4] ) bool p_cc_present[4] )
{ {
assert( p_pic->p_next == NULL ); if( dec->pf_queue_cc == NULL )
assert( dec->pf_queue_video != NULL ); {
return dec->pf_queue_video( dec, p_pic, p_cc, p_cc_present ); block_Release( p_cc );
return -1;
}
return dec->pf_queue_cc( dec, p_cc, p_cc_present );
} }
/** /**
......
...@@ -99,7 +99,9 @@ struct decoder_sys_t ...@@ -99,7 +99,9 @@ struct decoder_sys_t
uint32_t i_cc_flags; uint32_t i_cc_flags;
mtime_t i_cc_pts; mtime_t i_cc_pts;
mtime_t i_cc_dts; mtime_t i_cc_dts;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
cc_data_t cc; cc_data_t cc;
#endif
uint8_t *p_gop_user_data; uint8_t *p_gop_user_data;
uint32_t i_gop_user_data; uint32_t i_gop_user_data;
}; };
...@@ -112,6 +114,7 @@ static void CloseDecoder( vlc_object_t * ); ...@@ -112,6 +114,7 @@ static void CloseDecoder( vlc_object_t * );
static int DecodeVideo( decoder_t *, block_t *); static int DecodeVideo( decoder_t *, block_t *);
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0) #if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
static void SendCc( decoder_t *p_dec );
#endif #endif
static picture_t *GetNewPicture( decoder_t * ); static picture_t *GetNewPicture( decoder_t * );
...@@ -432,21 +435,29 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -432,21 +435,29 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
& PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B ) & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_B )
p_sys->i_cc_flags = BLOCK_FLAG_TYPE_B; p_sys->i_cc_flags = BLOCK_FLAG_TYPE_B;
else p_sys->i_cc_flags = BLOCK_FLAG_TYPE_I; else p_sys->i_cc_flags = BLOCK_FLAG_TYPE_I;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
bool b_top_field_first = p_sys->p_info->current_picture->flags bool b_top_field_first = p_sys->p_info->current_picture->flags
& PIC_FLAG_TOP_FIELD_FIRST; & PIC_FLAG_TOP_FIELD_FIRST;
#endif
if( p_sys->i_gop_user_data > 2 ) if( p_sys->i_gop_user_data > 2 )
{ {
/* We now have picture info for any cached user_data out of the gop */ /* We now have picture info for any cached user_data out of the gop */
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
cc_ProbeAndExtract( &p_sys->cc, b_top_field_first, cc_ProbeAndExtract( &p_sys->cc, b_top_field_first,
&p_sys->p_gop_user_data[0], p_sys->i_gop_user_data ); &p_sys->p_gop_user_data[0], p_sys->i_gop_user_data );
#endif
p_sys->i_gop_user_data = 0; p_sys->i_gop_user_data = 0;
} }
/* Extract the CC from the user_data of the picture */ /* Extract the CC from the user_data of the picture */
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
if( p_info->user_data_len > 2 ) if( p_info->user_data_len > 2 )
cc_ProbeAndExtract( &p_sys->cc, b_top_field_first, cc_ProbeAndExtract( &p_sys->cc, b_top_field_first,
&p_info->user_data[0], p_info->user_data_len ); &p_info->user_data[0], p_info->user_data_len );
if( p_sys->cc.i_data )
SendCc( p_dec );
#endif
} }
} }
break; break;
...@@ -594,34 +605,13 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -594,34 +605,13 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
static int DecodeVideo( decoder_t *p_dec, block_t *p_block) static int DecodeVideo( decoder_t *p_dec, block_t *p_block)
{ {
decoder_sys_t *p_sys = p_dec->p_sys;
if( p_block == NULL ) /* No Drain */ if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS; return VLCDEC_SUCCESS;
block_t **pp_block = &p_block; block_t **pp_block = &p_block;
picture_t *p_pic; picture_t *p_pic;
while( ( p_pic = DecodeBlock( p_dec, pp_block ) ) != NULL ) while( ( p_pic = DecodeBlock( p_dec, pp_block ) ) != NULL )
{ decoder_QueueVideo( p_dec, p_pic );
block_t *p_cc = NULL;
bool *pb_present = NULL;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
pb_present = p_sys->cc.pb_present;
if( p_sys->cc.i_data > 0 )
{
p_cc = block_Alloc( p_sys->cc.i_data);
if( p_cc )
{
memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
p_cc->i_dts =
p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
p_cc->i_flags = ( p_sys->cc.b_reorder ? p_sys->i_cc_flags : BLOCK_FLAG_TYPE_P ) & ( BLOCK_FLAG_TYPE_I|BLOCK_FLAG_TYPE_P|BLOCK_FLAG_TYPE_B);
}
cc_Flush( &p_sys->cc );
}
#endif
decoder_QueueVideoWithCc( p_dec, p_pic, p_cc, pb_present );
}
return VLCDEC_SUCCESS; return VLCDEC_SUCCESS;
} }
...@@ -633,6 +623,10 @@ static void CloseDecoder( vlc_object_t *p_this ) ...@@ -633,6 +623,10 @@ static void CloseDecoder( vlc_object_t *p_this )
decoder_t *p_dec = (decoder_t *)p_this; decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
cc_Flush( &p_sys->cc );
#endif
DpbClean( p_dec ); DpbClean( p_dec );
free( p_sys->p_gop_user_data ); free( p_sys->p_gop_user_data );
...@@ -651,7 +645,9 @@ static void Reset( decoder_t *p_dec ) ...@@ -651,7 +645,9 @@ static void Reset( decoder_t *p_dec )
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
cc_Flush( &p_sys->cc ); cc_Flush( &p_sys->cc );
#endif
mpeg2_reset( p_sys->p_mpeg2dec, 0 ); mpeg2_reset( p_sys->p_mpeg2dec, 0 );
DpbClean( p_dec ); DpbClean( p_dec );
} }
...@@ -704,6 +700,32 @@ static picture_t *GetNewPicture( decoder_t *p_dec ) ...@@ -704,6 +700,32 @@ static picture_t *GetNewPicture( decoder_t *p_dec )
return p_pic; return p_pic;
} }
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
/*****************************************************************************
* SendCc: Sends the Closed Captions for the CC decoder.
*****************************************************************************/
static void SendCc( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_cc = NULL;
if( p_sys->cc.i_data <= 0 )
return;
p_cc = block_Alloc( p_sys->cc.i_data);
if( p_cc )
{
memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
p_cc->i_dts =
p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
p_cc->i_flags = ( p_sys->cc.b_reorder ? p_sys->i_cc_flags : BLOCK_FLAG_TYPE_P ) & ( BLOCK_FLAG_TYPE_I|BLOCK_FLAG_TYPE_P|BLOCK_FLAG_TYPE_B);
decoder_QueueCc( p_dec, p_cc, p_sys->cc.pb_present );
}
cc_Flush( &p_sys->cc );
return;
}
#endif
/***************************************************************************** /*****************************************************************************
* GetAR: Get aspect ratio * GetAR: Get aspect ratio
*****************************************************************************/ *****************************************************************************/
......
...@@ -77,8 +77,7 @@ static sout_stream_id_sys_t *Add( sout_stream_t *, const es_format_t * ); ...@@ -77,8 +77,7 @@ static sout_stream_id_sys_t *Add( sout_stream_t *, const es_format_t * );
static void Del ( sout_stream_t *, sout_stream_id_sys_t * ); static void Del ( sout_stream_t *, sout_stream_id_sys_t * );
static int Send( sout_stream_t *, sout_stream_id_sys_t *, block_t * ); static int Send( sout_stream_t *, sout_stream_id_sys_t *, block_t * );
static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic, static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic );
block_t *p_cc, bool p_cc_present[4] );
inline static int video_update_format_decoder( decoder_t *p_dec ); inline static int video_update_format_decoder( decoder_t *p_dec );
inline static picture_t *video_new_buffer_decoder( decoder_t * ); inline static picture_t *video_new_buffer_decoder( decoder_t * );
inline static picture_t *video_new_buffer_filter( filter_t * ); inline static picture_t *video_new_buffer_filter( filter_t * );
...@@ -485,17 +484,12 @@ static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id ) ...@@ -485,17 +484,12 @@ static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
p_sys->b_inited = false; p_sys->b_inited = false;
} }
static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic, static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic )
block_t *p_cc, bool p_cc_present[4] )
{ {
sout_stream_t *p_stream = p_dec->p_queue_ctx; sout_stream_t *p_stream = p_dec->p_queue_ctx;
sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_sys_t *p_sys = p_stream->p_sys;
picture_t *p_new_pic; picture_t *p_new_pic;
(void) p_cc_present;
if( unlikely( p_cc != NULL ) )
block_Release( p_cc );
if( p_sys->i_height || p_sys->i_width ) if( p_sys->i_height || p_sys->i_width )
{ {
video_format_t fmt_out, fmt_in; video_format_t fmt_out, fmt_in;
......
...@@ -148,15 +148,10 @@ static void* EncoderThread( void *obj ) ...@@ -148,15 +148,10 @@ static void* EncoderThread( void *obj )
return NULL; return NULL;
} }
static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic, static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic )
block_t *p_cc, bool p_cc_present[4] )
{ {
sout_stream_id_sys_t *id = p_dec->p_queue_ctx; sout_stream_id_sys_t *id = p_dec->p_queue_ctx;
(void) p_cc_present;
if( unlikely( p_cc != NULL ) )
block_Release( p_cc );
vlc_mutex_lock(&id->fifo.lock); vlc_mutex_lock(&id->fifo.lock);
*id->fifo.pic.last = p_pic; *id->fifo.pic.last = p_pic;
id->fifo.pic.last = &p_pic->p_next; id->fifo.pic.last = &p_pic->p_next;
......
...@@ -872,8 +872,8 @@ static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block ) ...@@ -872,8 +872,8 @@ static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block )
} }
#endif #endif
static void DecoderExtractCc( decoder_t *p_dec, block_t *p_cc, static void DecoderPlayCc( decoder_t *p_dec, block_t *p_cc,
bool pb_present[4] ) bool pb_present[4] )
{ {
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
bool b_processed = false; bool b_processed = false;
...@@ -904,7 +904,7 @@ static void DecoderExtractCc( decoder_t *p_dec, block_t *p_cc, ...@@ -904,7 +904,7 @@ static void DecoderExtractCc( decoder_t *p_dec, block_t *p_cc,
block_Release( p_cc ); block_Release( p_cc );
} }
static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc ) static void PacketizerGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
{ {
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
block_t *p_cc; block_t *p_cc;
...@@ -919,11 +919,26 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc ) ...@@ -919,11 +919,26 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
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 );
if( !p_cc ) if( !p_cc )
return; return;
DecoderExtractCc( p_dec, p_cc, pb_present ); DecoderPlayCc( p_dec, p_cc, pb_present );
}
static int DecoderQueueCc( decoder_t *p_videodec, block_t *p_cc,
bool p_cc_present[4] )
{
decoder_owner_sys_t *p_owner = p_videodec->p_owner;
if( unlikely( p_cc != NULL ) )
{
if( p_owner->cc.b_supported &&
( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
DecoderPlayCc( p_videodec, p_cc, p_cc_present );
else
block_Release( p_cc );
}
return 0;
} }
static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture, static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
block_t *p_cc, bool p_cc_present[4],
unsigned *restrict pi_lost_sum ) unsigned *restrict pi_lost_sum )
{ {
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
...@@ -935,8 +950,6 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture, ...@@ -935,8 +950,6 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
{ {
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
picture_Release( p_picture ); picture_Release( p_picture );
if( unlikely( p_cc != NULL ) )
block_Release( p_cc );
return -1; return -1;
} }
...@@ -952,15 +965,6 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture, ...@@ -952,15 +965,6 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
vout_Flush( p_vout, VLC_TS_INVALID+1 ); vout_Flush( p_vout, VLC_TS_INVALID+1 );
} }
if( unlikely( p_cc != NULL ) )
{
if( p_owner->cc.b_supported &&
( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
DecoderExtractCc( p_dec, p_cc, p_cc_present );
else
block_Release( p_cc );
}
if( p_picture->date <= VLC_TS_INVALID ) if( p_picture->date <= VLC_TS_INVALID )
{ {
msg_Warn( p_dec, "non-dated video buffer received" ); msg_Warn( p_dec, "non-dated video buffer received" );
...@@ -1058,14 +1062,13 @@ static void DecoderUpdateStatVideo( decoder_owner_sys_t *p_owner, ...@@ -1058,14 +1062,13 @@ static void DecoderUpdateStatVideo( decoder_owner_sys_t *p_owner,
vlc_mutex_unlock( &input_priv(p_input)->counters.counters_lock ); vlc_mutex_unlock( &input_priv(p_input)->counters.counters_lock );
} }
static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic, static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic )
block_t *p_cc, bool p_cc_present[4] )
{ {
assert( p_pic ); assert( p_pic );
unsigned i_lost = 0; unsigned i_lost = 0;
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
int ret = DecoderPlayVideo( p_dec, p_pic, p_cc, p_cc_present, &i_lost ); int ret = DecoderPlayVideo( p_dec, p_pic, &i_lost );
p_owner->pf_update_stat( p_owner, 1, i_lost ); p_owner->pf_update_stat( p_owner, 1, i_lost );
return ret; return ret;
...@@ -1382,7 +1385,7 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block ) ...@@ -1382,7 +1385,7 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
} }
if( p_packetizer->pf_get_cc ) if( p_packetizer->pf_get_cc )
DecoderGetCc( p_dec, p_packetizer ); PacketizerGetCc( p_dec, p_packetizer );
while( p_packetized_block ) while( p_packetized_block )
{ {
...@@ -1686,6 +1689,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, ...@@ -1686,6 +1689,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
{ {
case VIDEO_ES: case VIDEO_ES:
p_dec->pf_queue_video = DecoderQueueVideo; p_dec->pf_queue_video = DecoderQueueVideo;
p_dec->pf_queue_cc = DecoderQueueCc;
p_owner->pf_update_stat = DecoderUpdateStatVideo; p_owner->pf_update_stat = DecoderUpdateStatVideo;
break; break;
case AUDIO_ES: case AUDIO_ES:
......
...@@ -121,13 +121,8 @@ void image_HandlerDelete( image_handler_t *p_image ) ...@@ -121,13 +121,8 @@ void image_HandlerDelete( image_handler_t *p_image )
* *
*/ */
static int ImageQueueVideo( decoder_t *p_dec, picture_t *p_pic, static int ImageQueueVideo( decoder_t *p_dec, picture_t *p_pic )
block_t *p_cc, bool p_cc_present[4] )
{ {
(void) p_cc_present;
if( unlikely( p_cc != NULL ) )
block_Release( p_cc );
image_handler_t *p_image = p_dec->p_queue_ctx; image_handler_t *p_image = p_dec->p_queue_ctx;
picture_fifo_Push( p_image->outfifo, p_pic ); picture_fifo_Push( p_image->outfifo, p_pic );
return 0; return 0;
......
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