From c0e99ce597812f10b3ebb733b2e4d22bc879c1b7 Mon Sep 17 00:00:00 2001 From: Francois Cartegnie Date: Thu, 5 Oct 2017 16:51:32 +0200 Subject: [PATCH] codec/esout: add support for CEA708 --- include/vlc_codec.h | 1 + modules/codec/avcodec/video.c | 1 + modules/codec/cc.h | 4 ++++ modules/codec/libmpeg2.c | 1 + modules/packetizer/hxxx_common.c | 1 + modules/packetizer/mpegvideo.c | 1 + modules/packetizer/vc1.c | 1 + src/input/decoder.c | 14 +++++++++++--- src/input/es_out.c | 5 +++++ src/libvlc-module.c | 9 +++++++++ 10 files changed, 35 insertions(+), 3 deletions(-) diff --git a/include/vlc_codec.h b/include/vlc_codec.h index cbb689ece1..3499ede27c 100644 --- a/include/vlc_codec.h +++ b/include/vlc_codec.h @@ -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 */ }; diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c index 9f53f0c17a..f6aeb48783 100644 --- a/modules/codec/avcodec/video.c +++ b/modules/codec/avcodec/video.c @@ -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 ); } diff --git a/modules/codec/cc.h b/modules/codec/cc.h index f5d902a8a4..fb80d176f1 100644 --- a/modules/codec/cc.h +++ b/modules/codec/cc.h @@ -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]; diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c index 2abd8e9cdf..f58972ad18 100644 --- a/modules/codec/libmpeg2.c +++ b/modules/codec/libmpeg2.c @@ -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 ); } diff --git a/modules/packetizer/hxxx_common.c b/modules/packetizer/hxxx_common.c index bcfeae15dc..45b33fdc1a 100644 --- a/modules/packetizer/hxxx_common.c +++ b/modules/packetizer/hxxx_common.c @@ -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 ); diff --git a/modules/packetizer/mpegvideo.c b/modules/packetizer/mpegvideo.c index 0f1af4d225..703b1d78e1 100644 --- a/modules/packetizer/mpegvideo.c +++ b/modules/packetizer/mpegvideo.c @@ -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 ); diff --git a/modules/packetizer/vc1.c b/modules/packetizer/vc1.c index a3b9dddfe7..901e2c03d8 100644 --- a/modules/packetizer/vc1.c +++ b/modules/packetizer/vc1.c @@ -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 ); diff --git a/src/input/decoder.c b/src/input/decoder.c index 1818224ff8..a79891da55 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -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 && diff --git a/src/input/es_out.c b/src/input/es_out.c index 40456d1059..227f15faa0 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -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 ); diff --git a/src/libvlc-module.c b/src/libvlc-module.c index 15939f4a19..e3e43296bd 100644 --- a/src/libvlc-module.c +++ b/src/libvlc-module.c @@ -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 () -- 2.11.4.GIT