|
|
|
@ -893,16 +893,101 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, |
|
|
|
|
const uint8_t **pp, const uint8_t *desc_list_end, |
|
|
|
|
int mp4_dec_config_descr_len, int mp4_es_id, int pid, |
|
|
|
|
uint8_t *mp4_dec_config_descr) |
|
|
|
|
{ |
|
|
|
|
const uint8_t *desc_end; |
|
|
|
|
int desc_len, desc_tag; |
|
|
|
|
char language[4]; |
|
|
|
|
|
|
|
|
|
desc_tag = get8(pp, desc_list_end); |
|
|
|
|
if (desc_tag < 0) |
|
|
|
|
return -1; |
|
|
|
|
desc_len = get8(pp, desc_list_end); |
|
|
|
|
if (desc_len < 0) |
|
|
|
|
return -1; |
|
|
|
|
desc_end = *pp + desc_len; |
|
|
|
|
if (desc_end > desc_list_end) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
dprintf(fc, "tag: 0x%02x len=%d\n", desc_tag, desc_len); |
|
|
|
|
|
|
|
|
|
if (st->codec->codec_id == CODEC_ID_NONE && |
|
|
|
|
stream_type == STREAM_TYPE_PRIVATE_DATA) |
|
|
|
|
mpegts_find_stream_type(st, desc_tag, DESC_types); |
|
|
|
|
|
|
|
|
|
switch(desc_tag) { |
|
|
|
|
case 0x1F: /* FMC descriptor */ |
|
|
|
|
get16(pp, desc_end); |
|
|
|
|
if (st->codec->codec_id == CODEC_ID_AAC_LATM && |
|
|
|
|
mp4_dec_config_descr_len && mp4_es_id == pid) { |
|
|
|
|
ByteIOContext pb; |
|
|
|
|
init_put_byte(&pb, mp4_dec_config_descr, |
|
|
|
|
mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL); |
|
|
|
|
ff_mp4_read_dec_config_descr(fc, st, &pb); |
|
|
|
|
if (st->codec->codec_id == CODEC_ID_AAC && |
|
|
|
|
st->codec->extradata_size > 0) |
|
|
|
|
st->need_parsing = 0; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 0x56: /* DVB teletext descriptor */ |
|
|
|
|
language[0] = get8(pp, desc_end); |
|
|
|
|
language[1] = get8(pp, desc_end); |
|
|
|
|
language[2] = get8(pp, desc_end); |
|
|
|
|
language[3] = 0; |
|
|
|
|
av_metadata_set2(&st->metadata, "language", language, 0); |
|
|
|
|
break; |
|
|
|
|
case 0x59: /* subtitling descriptor */ |
|
|
|
|
language[0] = get8(pp, desc_end); |
|
|
|
|
language[1] = get8(pp, desc_end); |
|
|
|
|
language[2] = get8(pp, desc_end); |
|
|
|
|
language[3] = 0; |
|
|
|
|
get8(pp, desc_end); |
|
|
|
|
if (st->codec->extradata) { |
|
|
|
|
if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, *pp, 4)) |
|
|
|
|
av_log_ask_for_sample(fc, "DVB sub with multiple IDs\n"); |
|
|
|
|
} else { |
|
|
|
|
st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE); |
|
|
|
|
if (st->codec->extradata) { |
|
|
|
|
st->codec->extradata_size = 4; |
|
|
|
|
memcpy(st->codec->extradata, *pp, 4); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
*pp += 4; |
|
|
|
|
av_metadata_set2(&st->metadata, "language", language, 0); |
|
|
|
|
break; |
|
|
|
|
case 0x0a: /* ISO 639 language descriptor */ |
|
|
|
|
language[0] = get8(pp, desc_end); |
|
|
|
|
language[1] = get8(pp, desc_end); |
|
|
|
|
language[2] = get8(pp, desc_end); |
|
|
|
|
language[3] = 0; |
|
|
|
|
av_metadata_set2(&st->metadata, "language", language, 0); |
|
|
|
|
break; |
|
|
|
|
case 0x05: /* registration descriptor */ |
|
|
|
|
st->codec->codec_tag = bytestream_get_le32(pp); |
|
|
|
|
dprintf(fc, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag); |
|
|
|
|
if (st->codec->codec_id == CODEC_ID_NONE && |
|
|
|
|
stream_type == STREAM_TYPE_PRIVATE_DATA) |
|
|
|
|
mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
*pp = desc_end; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) |
|
|
|
|
{ |
|
|
|
|
MpegTSContext *ts = filter->u.section_filter.opaque; |
|
|
|
|
SectionHeader h1, *h = &h1; |
|
|
|
|
PESContext *pes; |
|
|
|
|
AVStream *st; |
|
|
|
|
const uint8_t *p, *p_end, *desc_list_end, *desc_end; |
|
|
|
|
const uint8_t *p, *p_end, *desc_list_end; |
|
|
|
|
int program_info_length, pcr_pid, pid, stream_type; |
|
|
|
|
int desc_list_len, desc_len, desc_tag; |
|
|
|
|
char language[4]; |
|
|
|
|
int desc_list_len; |
|
|
|
|
uint32_t prog_reg_desc = 0; /* registration descriptor */ |
|
|
|
|
uint8_t *mp4_dec_config_descr = NULL; |
|
|
|
|
int mp4_dec_config_descr_len = 0; |
|
|
|
@ -1005,81 +1090,9 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len |
|
|
|
|
if (desc_list_end > p_end) |
|
|
|
|
break; |
|
|
|
|
for(;;) { |
|
|
|
|
desc_tag = get8(&p, desc_list_end); |
|
|
|
|
if (desc_tag < 0) |
|
|
|
|
if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end, |
|
|
|
|
mp4_dec_config_descr_len, mp4_es_id, pid, mp4_dec_config_descr) < 0) |
|
|
|
|
break; |
|
|
|
|
desc_len = get8(&p, desc_list_end); |
|
|
|
|
if (desc_len < 0) |
|
|
|
|
break; |
|
|
|
|
desc_end = p + desc_len; |
|
|
|
|
if (desc_end > desc_list_end) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
dprintf(ts->stream, "tag: 0x%02x len=%d\n", |
|
|
|
|
desc_tag, desc_len); |
|
|
|
|
|
|
|
|
|
if (st->codec->codec_id == CODEC_ID_NONE && |
|
|
|
|
stream_type == STREAM_TYPE_PRIVATE_DATA) |
|
|
|
|
mpegts_find_stream_type(st, desc_tag, DESC_types); |
|
|
|
|
|
|
|
|
|
switch(desc_tag) { |
|
|
|
|
case 0x1F: /* FMC descriptor */ |
|
|
|
|
get16(&p, desc_end); |
|
|
|
|
if (st->codec->codec_id == CODEC_ID_AAC_LATM && |
|
|
|
|
mp4_dec_config_descr_len && mp4_es_id == pid) { |
|
|
|
|
ByteIOContext pb; |
|
|
|
|
init_put_byte(&pb, mp4_dec_config_descr, |
|
|
|
|
mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL); |
|
|
|
|
ff_mp4_read_dec_config_descr(ts->stream, st, &pb); |
|
|
|
|
if (st->codec->codec_id == CODEC_ID_AAC && |
|
|
|
|
st->codec->extradata_size > 0) |
|
|
|
|
st->need_parsing = 0; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 0x56: /* DVB teletext descriptor */ |
|
|
|
|
language[0] = get8(&p, desc_end); |
|
|
|
|
language[1] = get8(&p, desc_end); |
|
|
|
|
language[2] = get8(&p, desc_end); |
|
|
|
|
language[3] = 0; |
|
|
|
|
av_metadata_set2(&st->metadata, "language", language, 0); |
|
|
|
|
break; |
|
|
|
|
case 0x59: /* subtitling descriptor */ |
|
|
|
|
language[0] = get8(&p, desc_end); |
|
|
|
|
language[1] = get8(&p, desc_end); |
|
|
|
|
language[2] = get8(&p, desc_end); |
|
|
|
|
language[3] = 0; |
|
|
|
|
get8(&p, desc_end); |
|
|
|
|
if (st->codec->extradata) { |
|
|
|
|
if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, p, 4)) |
|
|
|
|
av_log_ask_for_sample(ts->stream, "DVB sub with multiple IDs\n"); |
|
|
|
|
} else { |
|
|
|
|
st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE); |
|
|
|
|
if (st->codec->extradata) { |
|
|
|
|
st->codec->extradata_size = 4; |
|
|
|
|
memcpy(st->codec->extradata, p, 4); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
p += 4; |
|
|
|
|
av_metadata_set2(&st->metadata, "language", language, 0); |
|
|
|
|
break; |
|
|
|
|
case 0x0a: /* ISO 639 language descriptor */ |
|
|
|
|
language[0] = get8(&p, desc_end); |
|
|
|
|
language[1] = get8(&p, desc_end); |
|
|
|
|
language[2] = get8(&p, desc_end); |
|
|
|
|
language[3] = 0; |
|
|
|
|
av_metadata_set2(&st->metadata, "language", language, 0); |
|
|
|
|
break; |
|
|
|
|
case 0x05: /* registration descriptor */ |
|
|
|
|
st->codec->codec_tag = bytestream_get_le32(&p); |
|
|
|
|
dprintf(ts->stream, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag); |
|
|
|
|
if (st->codec->codec_id == CODEC_ID_NONE && |
|
|
|
|
stream_type == STREAM_TYPE_PRIVATE_DATA) |
|
|
|
|
mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
p = desc_end; |
|
|
|
|
|
|
|
|
|
if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) { |
|
|
|
|
ff_program_add_stream_index(ts->stream, h->id, pes->sub_st->index); |
|
|
|
|