Browse code

mpegts: MP4 OD support

Alex Converse authored on 2011/10/11 04:50:00
Showing 2 changed files
... ...
@@ -148,6 +148,7 @@ int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag);
148 148
 int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb);
149 149
 void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
150 150
 
151
+#define MP4ODescrTag                    0x01
151 152
 #define MP4IODescrTag                   0x02
152 153
 #define MP4ESDescrTag                   0x03
153 154
 #define MP4DecConfigDescrTag            0x04
... ...
@@ -74,6 +74,7 @@ typedef struct MpegTSSectionFilter {
74 74
 
75 75
 struct MpegTSFilter {
76 76
     int pid;
77
+    int es_id;
77 78
     int last_cc; /* last cc code (-1 if first packet) */
78 79
     enum MpegTSFilterType type;
79 80
     union {
... ...
@@ -317,6 +318,7 @@ static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int
317 317
     ts->pids[pid] = filter;
318 318
     filter->type = MPEGTS_SECTION;
319 319
     filter->pid = pid;
320
+    filter->es_id = -1;
320 321
     filter->last_cc = -1;
321 322
     sec = &filter->u.section_filter;
322 323
     sec->section_cb = section_cb;
... ...
@@ -345,6 +347,7 @@ static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid,
345 345
     ts->pids[pid] = filter;
346 346
     filter->type = MPEGTS_PES;
347 347
     filter->pid = pid;
348
+    filter->es_id = -1;
348 349
     filter->last_cc = -1;
349 350
     pes = &filter->u.pes_filter;
350 351
     pes->pes_cb = pes_cb;
... ...
@@ -934,6 +937,20 @@ static int parse_MP4IODescrTag(MP4DescrParseContext *d, int64_t off, int len)
934 934
     return parse_mp4_descr_arr(d, off, len);
935 935
 }
936 936
 
937
+static int parse_MP4ODescrTag(MP4DescrParseContext *d, int64_t off, int len)
938
+{
939
+    int id_flags;
940
+    if (len < 2)
941
+        return 0;
942
+    id_flags = avio_rb16(&d->pb);
943
+    if (!(id_flags & 0x0020)) { //URL_Flag
944
+        update_offsets(&d->pb, &off, &len);
945
+        return parse_mp4_descr_arr(d, off, len); //ES_Descriptor[]
946
+    } else {
947
+        return 0;
948
+    }
949
+}
950
+
937 951
 static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len)
938 952
 {
939 953
     int es_id = 0;
... ...
@@ -987,6 +1004,9 @@ static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len,
987 987
     case MP4IODescrTag:
988 988
         parse_MP4IODescrTag(d, off, len1);
989 989
         break;
990
+    case MP4ODescrTag:
991
+        parse_MP4ODescrTag(d, off, len1);
992
+        break;
990 993
     case MP4ESDescrTag:
991 994
         parse_MP4ESDescrTag(d, off, len1);
992 995
         break;
... ...
@@ -1014,6 +1034,70 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size,
1014 1014
     return 0;
1015 1015
 }
1016 1016
 
1017
+static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size,
1018
+                       Mp4Descr *descr, int *descr_count, int max_descr_count)
1019
+{
1020
+    MP4DescrParseContext d;
1021
+    if (init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count) < 0)
1022
+        return -1;
1023
+
1024
+    parse_mp4_descr_arr(&d, avio_tell(&d.pb), size);
1025
+
1026
+    *descr_count = d.descr_count;
1027
+    return 0;
1028
+}
1029
+
1030
+static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, const uint8_t *p_end)
1031
+{
1032
+    AVIOContext pb;
1033
+    Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }};
1034
+    int mp4_descr_count = 0;
1035
+    int i, pid;
1036
+
1037
+    mp4_read_od(s, p, (unsigned)(p_end - p), mp4_descr, &mp4_descr_count, MAX_MP4_DESCR_COUNT);
1038
+
1039
+    for (pid = 0; pid < NB_PID_MAX; pid++) {
1040
+        if (!ts->pids[pid])
1041
+             continue;
1042
+        for (i = 0; i < mp4_descr_count; i++) {
1043
+            PESContext *pes;
1044
+            AVStream *st;
1045
+            if (ts->pids[pid]->es_id != mp4_descr[i].es_id)
1046
+                continue;
1047
+            if (!(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES)) {
1048
+                av_log(s, AV_LOG_ERROR, "pid %x is not PES\n", pid);
1049
+                continue;
1050
+            }
1051
+            pes = ts->pids[pid]->u.pes_filter.opaque;
1052
+            st = pes->st;
1053
+            if (!st) {
1054
+                continue;
1055
+            }
1056
+
1057
+            ffio_init_context(&pb, mp4_descr[i].dec_config_descr,
1058
+                              mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
1059
+            ff_mp4_read_dec_config_descr(s, st, &pb);
1060
+            if (st->codec->codec_id == CODEC_ID_AAC &&
1061
+                st->codec->extradata_size > 0)
1062
+                st->need_parsing = 0;
1063
+            if (st->codec->codec_id == CODEC_ID_H264 &&
1064
+                st->codec->extradata_size > 0)
1065
+                st->need_parsing = 0;
1066
+
1067
+            if (st->codec->codec_id <= CODEC_ID_NONE) {
1068
+            } else if (st->codec->codec_id < CODEC_ID_FIRST_AUDIO) {
1069
+                st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
1070
+            } else if (st->codec->codec_id < CODEC_ID_FIRST_SUBTITLE) {
1071
+                st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
1072
+            } else if (st->codec->codec_id < CODEC_ID_FIRST_UNKNOWN) {
1073
+                st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
1074
+            }
1075
+        }
1076
+    }
1077
+    for (i = 0; i < mp4_descr_count; i++)
1078
+        av_free(mp4_descr[i].dec_config_descr);
1079
+}
1080
+
1017 1081
 static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
1018 1082
 {
1019 1083
     MpegTSContext *ts = filter->u.section_filter.opaque;
... ...
@@ -1030,6 +1114,7 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_le
1030 1030
     if (h->tid != M4OD_TID)
1031 1031
         return;
1032 1032
 
1033
+    SL_packet(ts->stream, ts, p, p_end);
1033 1034
 }
1034 1035
 
1035 1036
 int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
... ...
@@ -1061,6 +1146,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
1061 1061
     switch(desc_tag) {
1062 1062
     case 0x1E: /* SL descriptor */
1063 1063
         desc_es_id = get16(pp, desc_end);
1064
+        if (ts && ts->pids[pid])
1065
+            ts->pids[pid]->es_id = desc_es_id;
1064 1066
         for (i = 0; i < mp4_descr_count; i++)
1065 1067
         if (mp4_descr[i].dec_config_descr_len &&
1066 1068
             mp4_descr[i].es_id == desc_es_id) {
... ...
@@ -1258,6 +1345,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
1258 1258
             } else {
1259 1259
                 st = avformat_new_stream(pes->stream, NULL);
1260 1260
                 st->id = pid;
1261
+                st->codec->codec_type = AVMEDIA_TYPE_DATA;
1261 1262
             }
1262 1263
         }
1263 1264