In ts demuxer, support aac flexmux using extradata in iods, issue #2346

Originally committed as revision 25806 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Baptiste Coudurier 2010-11-23 00:51:12 +00:00
parent 91360ce61d
commit 798c6facb7
5 changed files with 157 additions and 82 deletions

View file

@ -30,6 +30,7 @@
#include "mpegts.h"
#include "internal.h"
#include "seek.h"
#include "isom.h"
/* 1.0 second at 24Mbit/s */
#define MAX_SCAN_PACKETS 32000
@ -852,6 +853,42 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid)
return pes;
}
static int mp4_read_iods(AVFormatContext *s, uint8_t *buf, unsigned size,
uint16_t *es_id, uint8_t **dec_config_descr,
int *dec_config_descr_size)
{
ByteIOContext pb;
int tag;
unsigned len;
init_put_byte(&pb, buf, size, 0, NULL, NULL, NULL, NULL);
len = ff_mp4_read_descr(s, &pb, &tag);
if (tag == MP4IODescrTag) {
get_be16(&pb); // ID
get_byte(&pb);
get_byte(&pb);
get_byte(&pb);
get_byte(&pb);
get_byte(&pb);
len = ff_mp4_read_descr(s, &pb, &tag);
if (tag == MP4ESDescrTag) {
*es_id = get_be16(&pb); /* ES_ID */
dprintf(s, "ES_ID %#x\n", *es_id);
get_byte(&pb); /* priority */
len = ff_mp4_read_descr(s, &pb, &tag);
if (tag == MP4DecConfigDescrTag) {
*dec_config_descr = av_malloc(len);
if (!*dec_config_descr)
return AVERROR(ENOMEM);
*dec_config_descr_size = len;
get_buffer(&pb, *dec_config_descr, len);
}
}
}
return 0;
}
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
{
MpegTSContext *ts = filter->u.section_filter.opaque;
@ -863,6 +900,9 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
int desc_list_len, desc_len, desc_tag;
char language[4];
uint32_t prog_reg_desc = 0; /* registration descriptor */
uint8_t *mp4_dec_config_descr = NULL;
int mp4_dec_config_descr_len = 0;
int mp4_es_id = 0;
#ifdef DEBUG
dprintf(ts->stream, "PMT: len %i\n", section_len);
@ -895,11 +935,20 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
uint8_t tag, len;
tag = get8(&p, p_end);
len = get8(&p, p_end);
dprintf(ts->stream, "program tag: 0x%02x len=%d\n", tag, len);
if(len > program_info_length - 2)
//something else is broken, exit the program_descriptors_loop
break;
program_info_length -= len + 2;
if(tag == 0x05 && len >= 4) { // registration descriptor
if (tag == 0x1d) { // IOD descriptor
get8(&p, p_end); // scope
get8(&p, p_end); // label
len -= 2;
mp4_read_iods(ts->stream, p, len, &mp4_es_id,
&mp4_dec_config_descr, &mp4_dec_config_descr_len);
} else if (tag == 0x05 && len >= 4) { // registration descriptor
prog_reg_desc = bytestream_get_le32(&p);
len -= 4;
}
@ -968,6 +1017,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
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);