mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-18 21:45:10 +00:00
libavcodec/mpeg12dec.c: support DVB CC format 0x0502 in user_data
Reviewed-by: Marth64 <marth64@proxyid.net> Signed-off-by: Marth64 <marth64@proxyid.net>
This commit is contained in:
parent
084d3515ca
commit
78c4d6c136
@ -66,7 +66,8 @@ enum Mpeg2ClosedCaptionsFormat {
|
||||
CC_FORMAT_AUTO,
|
||||
CC_FORMAT_A53_PART4,
|
||||
CC_FORMAT_SCTE20,
|
||||
CC_FORMAT_DVD
|
||||
CC_FORMAT_DVD,
|
||||
CC_FORMAT_DVB_0502
|
||||
};
|
||||
|
||||
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_DVB_0502) &&
|
||||
buf_size >= 12 &&
|
||||
p[0] == 0x05 && p[1] == 0x02) {
|
||||
/* extract DVB 0502 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_DVB_0502, "DVB 0502");
|
||||
}
|
||||
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" },
|
||||
{ "dvb_0502", "pick DVB 0502 CC substream", 0, AV_OPT_TYPE_CONST,
|
||||
{ .i64 = CC_FORMAT_DVB_0502 }, .flags = M2V_PARAM, .unit = "cc_format" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user