You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
mpegts: Add support for Sections in PMT
This commit is contained in:
@@ -1014,9 +1014,28 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
|
||||||
|
{
|
||||||
|
MpegTSContext *ts = filter->u.section_filter.opaque;
|
||||||
|
SectionHeader h1, *h = &h1;
|
||||||
|
const uint8_t *p, *p_end;
|
||||||
|
|
||||||
|
av_dlog(ts->stream, "m4SL/od:\n");
|
||||||
|
hex_dump_debug(ts->stream, (uint8_t *)section, section_len);
|
||||||
|
|
||||||
|
p_end = section + section_len - 4;
|
||||||
|
p = section;
|
||||||
|
if (parse_section_header(h, &p, p_end) < 0)
|
||||||
|
return;
|
||||||
|
if (h->tid != M4OD_TID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
|
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
|
||||||
const uint8_t **pp, const uint8_t *desc_list_end,
|
const uint8_t **pp, const uint8_t *desc_list_end,
|
||||||
Mp4Descr *mp4_descr, int mp4_descr_count, int pid)
|
Mp4Descr *mp4_descr, int mp4_descr_count, int pid,
|
||||||
|
MpegTSContext *ts)
|
||||||
{
|
{
|
||||||
const uint8_t *desc_end;
|
const uint8_t *desc_end;
|
||||||
int desc_len, desc_tag, desc_es_id;
|
int desc_len, desc_tag, desc_es_id;
|
||||||
@@ -1052,6 +1071,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
|
|||||||
if (st->codec->codec_id == CODEC_ID_AAC &&
|
if (st->codec->codec_id == CODEC_ID_AAC &&
|
||||||
st->codec->extradata_size > 0)
|
st->codec->extradata_size > 0)
|
||||||
st->need_parsing = 0;
|
st->need_parsing = 0;
|
||||||
|
if (st->codec->codec_id == CODEC_ID_MPEG4SYSTEMS)
|
||||||
|
mpegts_open_section_filter(ts, pid, m4sl_cb, ts, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1F: /* FMC descriptor */
|
case 0x1F: /* FMC descriptor */
|
||||||
@@ -1207,6 +1228,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
|
|||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
st = 0;
|
st = 0;
|
||||||
|
pes = NULL;
|
||||||
stream_type = get8(&p, p_end);
|
stream_type = get8(&p, p_end);
|
||||||
if (stream_type < 0)
|
if (stream_type < 0)
|
||||||
break;
|
break;
|
||||||
@@ -1222,19 +1244,27 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
|
|||||||
st->id = pes->pid;
|
st->id = pes->pid;
|
||||||
}
|
}
|
||||||
st = pes->st;
|
st = pes->st;
|
||||||
} else {
|
} else if (stream_type != 0x13) {
|
||||||
if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
|
if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
|
||||||
pes = add_pes_stream(ts, pid, pcr_pid);
|
pes = add_pes_stream(ts, pid, pcr_pid);
|
||||||
if (pes) {
|
if (pes) {
|
||||||
st = avformat_new_stream(pes->stream, NULL);
|
st = avformat_new_stream(pes->stream, NULL);
|
||||||
st->id = pes->pid;
|
st->id = pes->pid;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int idx = ff_find_stream_index(ts->stream, pid);
|
||||||
|
if (idx >= 0) {
|
||||||
|
st = ts->stream->streams[idx];
|
||||||
|
} else {
|
||||||
|
st = avformat_new_stream(pes->stream, NULL);
|
||||||
|
st->id = pid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!st)
|
if (!st)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!pes->stream_type)
|
if (pes && !pes->stream_type)
|
||||||
mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);
|
mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);
|
||||||
|
|
||||||
add_pid_to_pmt(ts, h->id, pid);
|
add_pid_to_pmt(ts, h->id, pid);
|
||||||
@@ -1249,10 +1279,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
|
|||||||
break;
|
break;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end,
|
if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end,
|
||||||
mp4_descr, mp4_descr_count, pid) < 0)
|
mp4_descr, mp4_descr_count, pid, ts) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) {
|
if (pes && 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);
|
ff_program_add_stream_index(ts->stream, h->id, pes->sub_st->index);
|
||||||
pes->sub_st->codec->codec_tag = st->codec->codec_tag;
|
pes->sub_st->codec->codec_tag = st->codec->codec_tag;
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
/* table ids */
|
/* table ids */
|
||||||
#define PAT_TID 0x00
|
#define PAT_TID 0x00
|
||||||
#define PMT_TID 0x02
|
#define PMT_TID 0x02
|
||||||
|
#define M4OD_TID 0x05
|
||||||
#define SDT_TID 0x42
|
#define SDT_TID 0x42
|
||||||
|
|
||||||
#define STREAM_TYPE_VIDEO_MPEG1 0x01
|
#define STREAM_TYPE_VIDEO_MPEG1 0x01
|
||||||
@@ -85,6 +86,7 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
|
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
|
||||||
const uint8_t **pp, const uint8_t *desc_list_end,
|
const uint8_t **pp, const uint8_t *desc_list_end,
|
||||||
Mp4Descr *mp4_descr, int mp4_descr_count, int pid);
|
Mp4Descr *mp4_descr, int mp4_descr_count, int pid,
|
||||||
|
MpegTSContext *ts);
|
||||||
|
|
||||||
#endif /* AVFORMAT_MPEGTS_H */
|
#endif /* AVFORMAT_MPEGTS_H */
|
||||||
|
@@ -837,7 +837,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p
|
|||||||
buf_size = FFMIN(len - consumed, sizeof(buf));
|
buf_size = FFMIN(len - consumed, sizeof(buf));
|
||||||
avio_read(pb, buf, buf_size);
|
avio_read(pb, buf, buf_size);
|
||||||
consumed += buf_size;
|
consumed += buf_size;
|
||||||
ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0);
|
ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
} else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
|
} else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
|
||||||
int stream_index = ff_find_stream_index(s, sid);
|
int stream_index = ff_find_stream_index(s, sid);
|
||||||
|
Reference in New Issue
Block a user