Commit c0e99ce5 authored by François Cartegnie's avatar François Cartegnie 🤞

codec/esout: add support for CEA708

parent 5ac1ca3f
......@@ -194,6 +194,7 @@ struct decoder_t
struct decoder_cc_desc_t
{
uint8_t i_608_channels; /* 608 channels bitmap */
uint64_t i_708_channels; /* 708 */
int i_reorder_depth; /* reorder depth, -1 for no reorder, 0 for old P/B flag based */
};
......
......@@ -866,6 +866,7 @@ static void DecodeSidedata( decoder_t *p_dec, const AVFrame *frame, picture_t *p
p_cc->i_pts = p_cc->i_dts;
decoder_cc_desc_t desc;
desc.i_608_channels = p_sys->cc.i_608channels;
desc.i_708_channels = p_sys->cc.i_708channels;
desc.i_reorder_depth = 4;
decoder_QueueCc( p_dec, p_cc, &desc );
}
......
......@@ -42,6 +42,7 @@ enum cc_payload_type_e
typedef struct
{
/* Which channel are present */
uint64_t i_708channels;
uint8_t i_608channels;
/* */
......@@ -63,6 +64,7 @@ typedef struct
static inline void cc_Init( cc_data_t *c )
{
c->i_608channels = 0;
c->i_708channels = 0;
c->i_data = 0;
c->b_reorder = false;
c->i_payload_type = CC_PAYLOAD_NONE;
......@@ -83,6 +85,8 @@ static inline void cc_AppendData( cc_data_t *c, uint8_t cc_preamble, const uint8
uint8_t i_field = cc_preamble & 0x03;
if( i_field == 0 || i_field == 1 )
c->i_608channels |= (3 << (2 * i_field));
else
c->i_708channels |= 1;
c->p_data[c->i_data++] = cc_preamble;
c->p_data[c->i_data++] = cc[0];
......
......@@ -719,6 +719,7 @@ static void SendCc( decoder_t *p_dec )
p_cc->i_flags = p_sys->i_cc_flags & BLOCK_FLAG_TYPE_MASK;
decoder_cc_desc_t desc;
desc.i_608_channels = p_sys->cc.i_608channels;
desc.i_708_channels = p_sys->cc.i_708channels;
desc.i_reorder_depth = p_sys->cc.b_reorder ? 0 : -1;
decoder_QueueCc( p_dec, p_cc, &desc );
}
......
......@@ -97,6 +97,7 @@ block_t * cc_storage_get_current( cc_storage_t *p_ccs, decoder_cc_desc_t *p_desc
p_block->i_flags = p_ccs->i_flags & BLOCK_FLAG_TYPE_MASK;
p_desc->i_608_channels = p_ccs->current.i_608channels;
p_desc->i_708_channels = p_ccs->current.i_708channels;
p_desc->i_reorder_depth = p_ccs->current.b_reorder ? 4 : -1;
}
cc_Flush( &p_ccs->current );
......
......@@ -329,6 +329,7 @@ static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc )
p_cc->i_flags = p_sys->i_cc_flags & BLOCK_FLAG_TYPE_MASK;
p_desc->i_608_channels = p_sys->cc.i_608channels;
p_desc->i_708_channels = p_sys->cc.i_708channels;
p_desc->i_reorder_depth = p_sys->cc.b_reorder ? 0 : -1;
}
cc_Flush( &p_sys->cc );
......
......@@ -776,6 +776,7 @@ static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc )
p_cc->i_flags = p_sys->i_cc_flags & BLOCK_FLAG_TYPE_MASK;
p_desc->i_608_channels = p_sys->cc.i_608channels;
p_desc->i_708_channels = p_sys->cc.i_708channels;
p_desc->i_reorder_depth = p_sys->cc.b_reorder ? 4 : -1;
}
cc_Flush( &p_sys->cc );
......
......@@ -131,7 +131,7 @@ struct decoder_owner_sys_t
bool b_idle;
/* CC */
#define MAX_CC_DECODERS 4 /* The es_out only creates one type of es */
#define MAX_CC_DECODERS 64 /* The es_out only creates one type of es */
struct
{
bool b_supported;
......@@ -915,8 +915,10 @@ static void DecoderPlayCc( decoder_t *p_dec, block_t *p_cc,
p_owner->cc.desc = *p_desc;
/* Fanout data to all decoders. */
uint64_t i_bitmap = p_owner->cc.desc.i_608_channels;
/* Fanout data to all decoders. We do not know if es_out
selected 608 or 708. */
uint64_t i_bitmap = p_owner->cc.desc.i_608_channels |
p_owner->cc.desc.i_708_channels;
for( int i=0; i_bitmap > 0; i_bitmap >>= 1, i++ )
{
......@@ -1777,6 +1779,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
p_owner->cc.b_supported = ( p_sout == NULL );
p_owner->cc.desc.i_608_channels = 0;
p_owner->cc.desc.i_708_channels = 0;
for( unsigned i = 0; i < MAX_CC_DECODERS; i++ )
p_owner->cc.pp_decoder[i] = NULL;
p_owner->i_ts_delay = 0;
......@@ -2142,6 +2145,11 @@ static bool input_DecoderHasCCChanFlag( decoder_t *p_dec,
i_max_channels = 4;
i_bitmap = p_owner->cc.desc.i_608_channels;
}
else if( codec == VLC_CODEC_CEA708 )
{
i_max_channels = 64;
i_bitmap = p_owner->cc.desc.i_708_channels;
}
else return false;
return ( i_channel >= 0 && i_channel < i_max_channels &&
......
......@@ -213,6 +213,8 @@ static inline int EsOutGetClosedCaptionsChannel( const es_format_t *p_fmt )
int i_channel;
if( p_fmt->i_codec == VLC_CODEC_CEA608 && p_fmt->subs.cc.i_channel < 4 )
i_channel = p_fmt->subs.cc.i_channel;
else if( p_fmt->i_codec == VLC_CODEC_CEA708 && p_fmt->subs.cc.i_channel < 64 )
i_channel = p_fmt->subs.cc.i_channel;
else
i_channel = -1;
return i_channel;
......@@ -2123,6 +2125,9 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
decoder_cc_desc_t desc;
input_DecoderGetCcDesc( es->p_dec, &desc );
if( var_InheritInteger( p_input, "captions" ) == 708 )
EsOutCreateCCChannels( out, VLC_CODEC_CEA708, desc.i_708_channels,
_("DTVCC Closed captions %u"), es );
EsOutCreateCCChannels( out, VLC_CODEC_CEA608, desc.i_608_channels,
_("Closed captions %u"), es );
......
......@@ -611,6 +611,11 @@ static const char *const ppsz_clock_descriptions[] =
#define INPUT_SUBTRACK_ID_LONGTEXT N_( \
"Stream ID of the subtitle track to use.")
#define INPUT_CAPTIONS_TEXT N_(N_("Closed Captions decoder"))
#define INPUT_CAPTIONS_LONGTEXT N_("Preferred closed captions decoder")
static const int pi_captions[] = { 608, 708 };
static const char *const ppsz_captions[] = { N_("EIA/CEA 608"), N_("CEA 708") };
#define INPUT_PREFERREDRESOLUTION_TEXT N_("Preferred video resolution")
#define INPUT_PREFERREDRESOLUTION_LONGTEXT N_( \
"When several video formats are available, select one whose " \
......@@ -1731,6 +1736,10 @@ vlc_module_begin ()
add_integer( "sub-track-id", -1,
INPUT_SUBTRACK_ID_TEXT, INPUT_SUBTRACK_ID_LONGTEXT, true )
change_safe ()
add_integer( "captions", 608,
INPUT_CAPTIONS_TEXT, INPUT_CAPTIONS_LONGTEXT, true )
change_integer_list( pi_captions, ppsz_captions )
change_safe ()
add_integer( "preferred-resolution", -1, INPUT_PREFERREDRESOLUTION_TEXT,
INPUT_PREFERREDRESOLUTION_LONGTEXT, false )
change_safe ()
......
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