Browse code

mpegts: Add support for multiple mp4 descriptors

Alex Converse authored on 2011/10/05 15:43:59
Showing 3 changed files
... ...
@@ -42,6 +42,8 @@
42 42
 
43 43
 #define MAX_PES_PAYLOAD 200*1024
44 44
 
45
+#define MAX_MP4_DESCR_COUNT 16
46
+
45 47
 enum MpegTSFilterType {
46 48
     MPEGTS_PES,
47 49
     MPEGTS_SECTION,
... ...
@@ -905,8 +907,7 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size,
905 905
 
906 906
 int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
907 907
                               const uint8_t **pp, const uint8_t *desc_list_end,
908
-                              int mp4_dec_config_descr_len, int mp4_es_id, int pid,
909
-                              uint8_t *mp4_dec_config_descr)
908
+                              Mp4Descr *mp4_descr, int mp4_descr_count, int pid)
910 909
 {
911 910
     const uint8_t *desc_end;
912 911
     int desc_len, desc_tag, desc_es_id;
... ...
@@ -932,10 +933,12 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
932 932
     switch(desc_tag) {
933 933
     case 0x1E: /* SL descriptor */
934 934
         desc_es_id = get16(pp, desc_end);
935
-        if (mp4_dec_config_descr_len && mp4_es_id == desc_es_id) {
935
+        for (i = 0; i < mp4_descr_count; i++)
936
+        if (mp4_descr[i].dec_config_descr_len &&
937
+            mp4_descr[i].es_id == desc_es_id) {
936 938
             AVIOContext pb;
937
-            ffio_init_context(&pb, mp4_dec_config_descr,
938
-                          mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
939
+            ffio_init_context(&pb, mp4_descr[i].dec_config_descr,
940
+                          mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
939 941
             ff_mp4_read_dec_config_descr(fc, st, &pb);
940 942
             if (st->codec->codec_id == CODEC_ID_AAC &&
941 943
                 st->codec->extradata_size > 0)
... ...
@@ -944,11 +947,11 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
944 944
         break;
945 945
     case 0x1F: /* FMC descriptor */
946 946
         get16(pp, desc_end);
947
-        if (st->codec->codec_id == CODEC_ID_AAC_LATM &&
948
-            mp4_dec_config_descr_len && mp4_es_id == pid) {
947
+        if (mp4_descr_count > 0 && st->codec->codec_id == CODEC_ID_AAC_LATM &&
948
+            mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) {
949 949
             AVIOContext pb;
950
-            ffio_init_context(&pb, mp4_dec_config_descr,
951
-                          mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
950
+            ffio_init_context(&pb, mp4_descr->dec_config_descr,
951
+                          mp4_descr->dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
952 952
             ff_mp4_read_dec_config_descr(fc, st, &pb);
953 953
             if (st->codec->codec_id == CODEC_ID_AAC &&
954 954
                 st->codec->extradata_size > 0)
... ...
@@ -1032,9 +1035,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
1032 1032
     int program_info_length, pcr_pid, pid, stream_type;
1033 1033
     int desc_list_len;
1034 1034
     uint32_t prog_reg_desc = 0; /* registration descriptor */
1035
-    uint8_t *mp4_dec_config_descr = NULL;
1036
-    int mp4_dec_config_descr_len = 0;
1037
-    int mp4_es_id = 0;
1035
+
1036
+    Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }};
1037
+    int mp4_descr_count = 0;
1038
+    int i;
1038 1039
 
1039 1040
     av_dlog(ts->stream, "PMT: len %i\n", section_len);
1040 1041
     hex_dump_debug(ts->stream, (uint8_t *)section, section_len);
... ...
@@ -1076,8 +1080,11 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
1076 1076
             get8(&p, p_end); // scope
1077 1077
             get8(&p, p_end); // label
1078 1078
             len -= 2;
1079
-            mp4_read_iods(ts->stream, p, len, &mp4_es_id,
1080
-                          &mp4_dec_config_descr, &mp4_dec_config_descr_len);
1079
+            if (mp4_descr_count < MAX_MP4_DESCR_COUNT) {
1080
+                mp4_descr_count++;
1081
+                mp4_read_iods(ts->stream, p, len, &mp4_descr->es_id,
1082
+                              &mp4_descr->dec_config_descr, &mp4_descr->dec_config_descr_len);
1083
+            }
1081 1084
         } else if (tag == 0x05 && len >= 4) { // registration descriptor
1082 1085
             prog_reg_desc = bytestream_get_le32(&p);
1083 1086
             len -= 4;
... ...
@@ -1136,7 +1143,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
1136 1136
             break;
1137 1137
         for(;;) {
1138 1138
             if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end,
1139
-                mp4_dec_config_descr_len, mp4_es_id, pid, mp4_dec_config_descr) < 0)
1139
+                mp4_descr, mp4_descr_count, pid) < 0)
1140 1140
                 break;
1141 1141
 
1142 1142
             if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) {
... ...
@@ -1148,7 +1155,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
1148 1148
     }
1149 1149
 
1150 1150
  out:
1151
-    av_free(mp4_dec_config_descr);
1151
+    for (i = 0; i < mp4_descr_count; i++)
1152
+        av_free(mp4_descr[i].dec_config_descr);
1152 1153
 }
1153 1154
 
1154 1155
 static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
... ...
@@ -64,6 +64,12 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
64 64
                            const uint8_t *buf, int len);
65 65
 void ff_mpegts_parse_close(MpegTSContext *ts);
66 66
 
67
+typedef struct {
68
+    int es_id;
69
+    int dec_config_descr_len;
70
+    uint8_t *dec_config_descr;
71
+} Mp4Descr;
72
+
67 73
 /**
68 74
  * Parse an MPEG-2 descriptor
69 75
  * @param[in] fc                    Format context (used for logging only)
... ...
@@ -79,7 +85,6 @@ void ff_mpegts_parse_close(MpegTSContext *ts);
79 79
  */
80 80
 int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
81 81
                               const uint8_t **pp, const uint8_t *desc_list_end,
82
-                              int mp4_dec_config_descr_len, int mp4_es_id, int pid,
83
-                              uint8_t *mp4_dec_config_descr);
82
+                              Mp4Descr *mp4_descr, int mp4_descr_count, int pid);
84 83
 
85 84
 #endif /* AVFORMAT_MPEGTS_H */
... ...
@@ -837,7 +837,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p
837 837
                 buf_size = FFMIN(len - consumed, sizeof(buf));
838 838
                 avio_read(pb, buf, buf_size);
839 839
                 consumed += buf_size;
840
-                ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, 0, 0, 0, 0);
840
+                ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0);
841 841
             }
842 842
         } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
843 843
             int stream_index = ff_find_stream_index(s, sid);