Commit 4079bb24 authored by Thomas Guillem's avatar Thomas Guillem

decoder: add decoder_QueueVideoWithCc

This replaces the pf_get_cc callback for video decoders. Packetizers should
still use pf_get_cc.
parent 548d2cf6
......@@ -125,11 +125,11 @@ struct decoder_t
void ( * pf_flush ) ( decoder_t * );
/* Closed Caption (CEA 608/708) extraction.
* If set, it *may* be called after pf_decode/pf_packetize
* returned data. It should return CC for the pictures returned by the
* last pf_packetize/pf_decode call only,
* If set, it *may* be called after pf_packetize returned data. It should
* return CC for the pictures returned by the last pf_packetize call only,
* pb_present will be used to known which cc channel are present (but
* globaly, not necessary for the current packet */
* globaly, not necessary for the current packet. Video decoders should use
* the decoder_QueueVideoWithCc() function to pass closed captions. */
block_t * ( * pf_get_cc ) ( decoder_t *, bool pb_present[4] );
/* Meta data at codec level
......@@ -173,8 +173,9 @@ struct decoder_t
* XXX use decoder_GetDisplayRate */
int (*pf_get_display_rate)( decoder_t * );
/* XXX use decoder_QueueVideo */
int (*pf_queue_video)( decoder_t *, picture_t * );
/* XXX use decoder_QueueVideo or decoder_QueueVideoWithCc */
int (*pf_queue_video)( decoder_t *, picture_t *, block_t *p_cc,
bool p_cc_present[4] );
/* XXX use decoder_QueueAudio */
int (*pf_queue_audio)( decoder_t *, block_t * );
/* XXX use decoder_QueueSub */
......@@ -299,7 +300,22 @@ static inline int decoder_QueueVideo( decoder_t *dec, picture_t *p_pic )
{
assert( p_pic->p_next == NULL );
assert( dec->pf_queue_video != NULL );
return dec->pf_queue_video( dec, p_pic );
return dec->pf_queue_video( dec, p_pic, NULL, NULL );
}
/**
* This function queues a single picture with CC to the video output
*
* This function also queues the Closed Captions associated with the picture.
*
* \return 0 if the picture is queued, -1 on error
*/
static inline int decoder_QueueVideoWithCc( decoder_t *dec, picture_t *p_pic,
block_t *p_cc, bool p_cc_present[4] )
{
assert( p_pic->p_next == NULL );
assert( dec->pf_queue_video != NULL );
return dec->pf_queue_video( dec, p_pic, p_cc, p_cc_present );
}
/**
......
......@@ -112,7 +112,6 @@ static void CloseDecoder( vlc_object_t * );
static int DecodeVideo( decoder_t *, block_t *);
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] );
#endif
static picture_t *GetNewPicture( decoder_t * );
......@@ -193,7 +192,6 @@ static int OpenDecoder( vlc_object_t *p_this )
p_sys->i_cc_dts = 0;
p_sys->i_cc_flags = 0;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
p_dec->pf_get_cc = GetCc;
cc_Init( &p_sys->cc );
#endif
p_sys->p_gop_user_data = NULL;
......@@ -598,13 +596,34 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_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 */
return VLCDEC_SUCCESS;
block_t **pp_block = &p_block;
picture_t *p_pic;
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;
}
......@@ -687,34 +706,6 @@ static picture_t *GetNewPicture( decoder_t *p_dec )
return p_pic;
}
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
/*****************************************************************************
* GetCc: Retrieves the Closed Captions for the CC decoder.
*****************************************************************************/
static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_cc = NULL;
for( int i = 0; i < 4; i++ )
pb_present[i] = p_sys->cc.pb_present[i];
if( p_sys->cc.i_data <= 0 )
return NULL;
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 );
return p_cc;
}
#endif
/*****************************************************************************
* GetAR: Get aspect ratio
*****************************************************************************/
......
......@@ -77,7 +77,8 @@ 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 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 picture_t *video_new_buffer_decoder( decoder_t * );
inline static picture_t *video_new_buffer_filter( filter_t * );
......@@ -484,12 +485,17 @@ static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
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_sys_t *p_sys = p_stream->p_sys;
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 )
{
video_format_t fmt_out, fmt_in;
......
......@@ -148,10 +148,15 @@ static void* EncoderThread( void *obj )
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;
(void) p_cc_present;
if( unlikely( p_cc != NULL ) )
block_Release( p_cc );
vlc_mutex_lock(&id->fifo.lock);
*id->fifo.pic.last = p_pic;
id->fifo.pic.last = &p_pic->p_next;
......@@ -775,7 +780,6 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
block_t *in, block_t **out )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
picture_t *p_pic = NULL;
*out = NULL;
bool b_error = false;
......
......@@ -908,6 +908,7 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
}
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 )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
......@@ -919,6 +920,8 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
{
vlc_mutex_unlock( &p_owner->lock );
picture_Release( p_picture );
if( unlikely( p_cc != NULL ) )
block_Release( p_cc );
return -1;
}
......@@ -934,9 +937,13 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
vout_Flush( p_vout, VLC_TS_INVALID+1 );
}
if( p_dec->pf_get_cc &&
( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
DecoderGetCc( p_dec, p_dec );
if( unlikely( p_cc != NULL ) )
{
if( ( !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 )
{
......@@ -1035,13 +1042,14 @@ static void DecoderUpdateStatVideo( decoder_owner_sys_t *p_owner,
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 );
unsigned i_lost = 0;
decoder_owner_sys_t *p_owner = p_dec->p_owner;
int ret = DecoderPlayVideo( p_dec, p_pic, &i_lost );
int ret = DecoderPlayVideo( p_dec, p_pic, p_cc, p_cc_present, &i_lost );
p_owner->pf_update_stat( p_owner, 1, i_lost );
return ret;
......
......@@ -121,8 +121,13 @@ 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;
picture_fifo_Push( p_image->outfifo, p_pic );
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