mpegts: Add support for Sections in PMT
authorAlex Converse <alex.converse@gmail.com>
Thu, 6 Oct 2011 01:24:17 +0000 (18:24 -0700)
committerAlex Converse <alex.converse@gmail.com>
Fri, 28 Oct 2011 21:54:14 +0000 (14:54 -0700)
libavformat/mpegts.c
libavformat/mpegts.h
libavformat/wtv.c

index 3703d2c..abc3596 100644 (file)
@@ -1014,9 +1014,28 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size,
     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,
                               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;
     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 &&
                 st->codec->extradata_size > 0)
                 st->need_parsing = 0;
+            if (st->codec->codec_id == CODEC_ID_MPEG4SYSTEMS)
+                mpegts_open_section_filter(ts, pid, m4sl_cb, ts, 1);
         }
         break;
     case 0x1F: /* FMC descriptor */
@@ -1207,6 +1228,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
 
     for(;;) {
         st = 0;
+        pes = NULL;
         stream_type = get8(&p, p_end);
         if (stream_type < 0)
             break;
@@ -1222,19 +1244,27 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
                 st->id = pes->pid;
             }
             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
             pes = add_pes_stream(ts, pid, pcr_pid);
             if (pes) {
                 st = avformat_new_stream(pes->stream, NULL);
                 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)
             goto out;
 
-        if (!pes->stream_type)
+        if (pes && !pes->stream_type)
             mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);
 
         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;
         for(;;) {
             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;
 
-            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);
                 pes->sub_st->codec->codec_tag = st->codec->codec_tag;
             }
index 15eee60..560637b 100644 (file)
@@ -39,6 +39,7 @@
 /* table ids */
 #define PAT_TID   0x00
 #define PMT_TID   0x02
+#define M4OD_TID  0x05
 #define SDT_TID   0x42
 
 #define STREAM_TYPE_VIDEO_MPEG1     0x01
@@ -85,6 +86,7 @@ typedef struct {
  */
 int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
                               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 */
index f848968..cdb5c49 100644 (file)
@@ -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));
                 avio_read(pb, buf, 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)) {
             int stream_index = ff_find_stream_index(s, sid);