mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
add ff_parse_mpeg2_descriptor; make MPEG2 descriptor parsing routines available to other modules.
Originally committed as revision 26125 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
0af1671e53
commit
cc9038e95c
@ -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);
|
||||
|
@ -63,4 +63,22 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
|
||||
const uint8_t *buf, int len);
|
||||
void ff_mpegts_parse_close(MpegTSContext *ts);
|
||||
|
||||
/**
|
||||
* Parse an MPEG-2 descriptor
|
||||
* @param[in] fc Format context (used for logging only)
|
||||
* @param st Stream
|
||||
* @param stream_type STREAM_TYPE_xxx
|
||||
* @param pp Descriptor buffer pointer
|
||||
* @param desc_list_end End of buffer
|
||||
* @param mp4_dec_config_descr_len Length of 'mp4_dec_config_descr', or zero if not present
|
||||
* @param mp4_es_id
|
||||
* @param pid
|
||||
* @param mp4_dec_config_descr
|
||||
* @return <0 to stop processing
|
||||
*/
|
||||
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);
|
||||
|
||||
#endif /* AVFORMAT_MPEGTS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user