Originally from: Fixes #2481, by applying patch from kenny at the-b org. This adds dec… https://github.com/MythTV/mythtv/commit/49d3294c9a4ef20a699c2bb2da08f33b294c86b3
Referencing: Trac #2481 (Closed Captioning contained in MPEG user data fields) – MythTV https://code.mythtv.org/trac/ticket/2481 Modified in: Simplify DTV CEA-608 handling a bit & add some range checking. https://github.com/MythTV/mythtv/commit/be6a2b4e4b90717924aea69f09baf49b168b745a Some tweaks to cc implementation in mpeg12.c: make the C ANSI compati… https://github.com/MythTV/mythtv/commit/77cff32fb074d974b8e10361834efece3694f00f See also: https://github.com/CCExtractor/ccextractor/blob/master/src/lib_ccx/es_userdata.c --- libavcodec/mpeg12dec.c | 67 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index c0ed6a9d5b..e1503a9df8 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -66,7 +66,8 @@ enum Mpeg2ClosedCaptionsFormat { CC_FORMAT_AUTO, CC_FORMAT_A53_PART4, CC_FORMAT_SCTE20, - CC_FORMAT_DVD + CC_FORMAT_DVD, + CC_FORMAT_DISH }; typedef struct Mpeg1Context { @@ -2059,6 +2060,68 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, mpeg_set_cc_format(avctx, CC_FORMAT_DVD, "DVD"); } return 1; + } else if ((!s1->cc_format || s1->cc_format == CC_FORMAT_DISH) && + buf_size >= 12 && + p[0] == 0x05 && p[1] == 0x02) { + /* extract Dish Network DVB CC data */ + const uint8_t cc_header = 0xf8 | 0x04 /* valid */ | 0x00 /* line 21 field 1 */; + uint8_t cc_data[4] = {0}; + int cc_count = 0; + uint8_t dvb_cc_type = p[7]; + p += 8; + buf_size -= 8; + + if (dvb_cc_type == 0x05 && buf_size >= 7) { + dvb_cc_type = p[6]; + p += 7; + buf_size -= 7; + } + + if (dvb_cc_type == 0x02 && buf_size >= 4) { /* 2-byte caption, can be repeated */ + cc_count = 1; + cc_data[0] = p[1]; + cc_data[1] = p[2]; + dvb_cc_type = p[3]; + + /* Only repeat characters when the next type flag + * is 0x04 and the characters are repeatable (i.e., less than + * 32 with the parity stripped). + */ + if (dvb_cc_type == 0x04 && (cc_data[0] & 0x7f) < 32) { + cc_count = 2; + cc_data[2] = cc_data[0]; + cc_data[3] = cc_data[1]; + } + } else if (dvb_cc_type == 0x04 && buf_size >= 5) { /* 4-byte caption, not repeated */ + cc_count = 2; + cc_data[0] = p[1]; + cc_data[1] = p[2]; + cc_data[2] = p[3]; + cc_data[3] = p[4]; + } + + if (cc_count > 0) { + int ret; + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count * UINT64_C(3)); + if (new_size > 3 * A53_MAX_CC_COUNT) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) { + s1->a53_buf_ref->data[0] = cc_header; + s1->a53_buf_ref->data[1] = cc_data[0]; + s1->a53_buf_ref->data[2] = cc_data[1]; + if (cc_count == 2) { + s1->a53_buf_ref->data[3] = cc_header; + s1->a53_buf_ref->data[4] = cc_data[2]; + s1->a53_buf_ref->data[5] = cc_data[3]; + } + } + + mpeg_set_cc_format(avctx, CC_FORMAT_DISH, "Dish Network DVB"); + } + return 1; } return 0; } @@ -2629,6 +2692,8 @@ static const AVOption mpeg2video_options[] = { { .i64 = CC_FORMAT_SCTE20 }, .flags = M2V_PARAM, .unit = "cc_format" }, { "dvd", "pick DVD CC substream", 0, AV_OPT_TYPE_CONST, { .i64 = CC_FORMAT_DVD }, .flags = M2V_PARAM, .unit = "cc_format" }, + { "dish", "pick Dish Network DVB CC substream", 0, AV_OPT_TYPE_CONST, + { .i64 = CC_FORMAT_DISH }, .flags = M2V_PARAM, .unit = "cc_format" }, { NULL } }; -- 2.43.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".