|
|
@ -30,6 +30,7 @@ |
|
|
|
#include "mpegts.h" |
|
|
|
#include "mpegts.h" |
|
|
|
#include "internal.h" |
|
|
|
#include "internal.h" |
|
|
|
#include "seek.h" |
|
|
|
#include "seek.h" |
|
|
|
|
|
|
|
#include "isom.h" |
|
|
|
|
|
|
|
|
|
|
|
/* 1.0 second at 24Mbit/s */ |
|
|
|
/* 1.0 second at 24Mbit/s */ |
|
|
|
#define MAX_SCAN_PACKETS 32000 |
|
|
|
#define MAX_SCAN_PACKETS 32000 |
|
|
@ -852,6 +853,42 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid) |
|
|
|
return pes; |
|
|
|
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) |
|
|
|
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
MpegTSContext *ts = filter->u.section_filter.opaque; |
|
|
|
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; |
|
|
|
int desc_list_len, desc_len, desc_tag; |
|
|
|
char language[4]; |
|
|
|
char language[4]; |
|
|
|
uint32_t prog_reg_desc = 0; /* registration descriptor */ |
|
|
|
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 |
|
|
|
#ifdef DEBUG |
|
|
|
dprintf(ts->stream, "PMT: len %i\n", section_len); |
|
|
|
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; |
|
|
|
uint8_t tag, len; |
|
|
|
tag = get8(&p, p_end); |
|
|
|
tag = get8(&p, p_end); |
|
|
|
len = 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) |
|
|
|
if(len > program_info_length - 2) |
|
|
|
//something else is broken, exit the program_descriptors_loop
|
|
|
|
//something else is broken, exit the program_descriptors_loop
|
|
|
|
break; |
|
|
|
break; |
|
|
|
program_info_length -= len + 2; |
|
|
|
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); |
|
|
|
prog_reg_desc = bytestream_get_le32(&p); |
|
|
|
len -= 4; |
|
|
|
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); |
|
|
|
mpegts_find_stream_type(st, desc_tag, DESC_types); |
|
|
|
|
|
|
|
|
|
|
|
switch(desc_tag) { |
|
|
|
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 */ |
|
|
|
case 0x56: /* DVB teletext descriptor */ |
|
|
|
language[0] = get8(&p, desc_end); |
|
|
|
language[0] = get8(&p, desc_end); |
|
|
|
language[1] = get8(&p, desc_end); |
|
|
|
language[1] = get8(&p, desc_end); |
|
|
|