add ff_parse_mpeg2_descriptor; make MPEG2 descriptor parsing routines available to...
authorPeter Ross <pross@xvid.org>
Wed, 29 Dec 2010 12:45:31 +0000 (12:45 +0000)
committerPeter Ross <pross@xvid.org>
Wed, 29 Dec 2010 12:45:31 +0000 (12:45 +0000)
Originally committed as revision 26125 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/mpegts.c
libavformat/mpegts.h

index bbb00d3..01b69a7 100644 (file)
@@ -893,16 +893,101 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size,
     return 0;
 }
 
     return 0;
 }
 
+int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
+                              const uint8_t **pp, const uint8_t *desc_list_end,
+                              int mp4_dec_config_descr_len, int mp4_es_id, int pid,
+                              uint8_t *mp4_dec_config_descr)
+{
+    const uint8_t *desc_end;
+    int desc_len, desc_tag;
+    char language[4];
+
+    desc_tag = get8(pp, desc_list_end);
+    if (desc_tag < 0)
+        return -1;
+    desc_len = get8(pp, desc_list_end);
+    if (desc_len < 0)
+        return -1;
+    desc_end = *pp + desc_len;
+    if (desc_end > desc_list_end)
+        return -1;
+
+    dprintf(fc, "tag: 0x%02x len=%d\n", desc_tag, desc_len);
+
+    if (st->codec->codec_id == CODEC_ID_NONE &&
+        stream_type == STREAM_TYPE_PRIVATE_DATA)
+        mpegts_find_stream_type(st, desc_tag, DESC_types);
+
+    switch(desc_tag) {
+    case 0x1F: /* FMC descriptor */
+        get16(pp, 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(fc, 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 */
+        language[0] = get8(pp, desc_end);
+        language[1] = get8(pp, desc_end);
+        language[2] = get8(pp, desc_end);
+        language[3] = 0;
+        av_metadata_set2(&st->metadata, "language", language, 0);
+        break;
+    case 0x59: /* subtitling descriptor */
+        language[0] = get8(pp, desc_end);
+        language[1] = get8(pp, desc_end);
+        language[2] = get8(pp, desc_end);
+        language[3] = 0;
+        get8(pp, desc_end);
+        if (st->codec->extradata) {
+            if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, *pp, 4))
+                av_log_ask_for_sample(fc, "DVB sub with multiple IDs\n");
+        } else {
+            st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (st->codec->extradata) {
+                st->codec->extradata_size = 4;
+                memcpy(st->codec->extradata, *pp, 4);
+            }
+        }
+        *pp += 4;
+        av_metadata_set2(&st->metadata, "language", language, 0);
+        break;
+    case 0x0a: /* ISO 639 language descriptor */
+        language[0] = get8(pp, desc_end);
+        language[1] = get8(pp, desc_end);
+        language[2] = get8(pp, desc_end);
+        language[3] = 0;
+        av_metadata_set2(&st->metadata, "language", language, 0);
+        break;
+    case 0x05: /* registration descriptor */
+        st->codec->codec_tag = bytestream_get_le32(pp);
+        dprintf(fc, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag);
+        if (st->codec->codec_id == CODEC_ID_NONE &&
+            stream_type == STREAM_TYPE_PRIVATE_DATA)
+            mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
+        break;
+    default:
+        break;
+    }
+    *pp = desc_end;
+    return 0;
+}
+
 static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
 {
     MpegTSContext *ts = filter->u.section_filter.opaque;
     SectionHeader h1, *h = &h1;
     PESContext *pes;
     AVStream *st;
 static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
 {
     MpegTSContext *ts = filter->u.section_filter.opaque;
     SectionHeader h1, *h = &h1;
     PESContext *pes;
     AVStream *st;
-    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
+    const uint8_t *p, *p_end, *desc_list_end;
     int program_info_length, pcr_pid, pid, stream_type;
     int program_info_length, pcr_pid, pid, stream_type;
-    int desc_list_len, desc_len, desc_tag;
-    char language[4];
+    int desc_list_len;
     uint32_t prog_reg_desc = 0; /* registration descriptor */
     uint8_t *mp4_dec_config_descr = NULL;
     int mp4_dec_config_descr_len = 0;
     uint32_t prog_reg_desc = 0; /* registration descriptor */
     uint8_t *mp4_dec_config_descr = NULL;
     int mp4_dec_config_descr_len = 0;
@@ -1005,81 +1090,9 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
         if (desc_list_end > p_end)
             break;
         for(;;) {
         if (desc_list_end > p_end)
             break;
         for(;;) {
-            desc_tag = get8(&p, desc_list_end);
-            if (desc_tag < 0)
+            if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end,
+                mp4_dec_config_descr_len, mp4_es_id, pid, mp4_dec_config_descr) < 0)
                 break;
                 break;
-            desc_len = get8(&p, desc_list_end);
-            if (desc_len < 0)
-                break;
-            desc_end = p + desc_len;
-            if (desc_end > desc_list_end)
-                break;
-
-            dprintf(ts->stream, "tag: 0x%02x len=%d\n",
-                   desc_tag, desc_len);
-
-            if (st->codec->codec_id == CODEC_ID_NONE &&
-                stream_type == STREAM_TYPE_PRIVATE_DATA)
-                mpegts_find_stream_type(st, desc_tag, DESC_types);
-
-            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 */
-                language[0] = get8(&p, desc_end);
-                language[1] = get8(&p, desc_end);
-                language[2] = get8(&p, desc_end);
-                language[3] = 0;
-                av_metadata_set2(&st->metadata, "language", language, 0);
-                break;
-            case 0x59: /* subtitling descriptor */
-                language[0] = get8(&p, desc_end);
-                language[1] = get8(&p, desc_end);
-                language[2] = get8(&p, desc_end);
-                language[3] = 0;
-                get8(&p, desc_end);
-                if (st->codec->extradata) {
-                    if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, p, 4))
-                        av_log_ask_for_sample(ts->stream, "DVB sub with multiple IDs\n");
-                } else {
-                    st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
-                    if (st->codec->extradata) {
-                        st->codec->extradata_size = 4;
-                        memcpy(st->codec->extradata, p, 4);
-                    }
-                }
-                p += 4;
-                av_metadata_set2(&st->metadata, "language", language, 0);
-                break;
-            case 0x0a: /* ISO 639 language descriptor */
-                language[0] = get8(&p, desc_end);
-                language[1] = get8(&p, desc_end);
-                language[2] = get8(&p, desc_end);
-                language[3] = 0;
-                av_metadata_set2(&st->metadata, "language", language, 0);
-                break;
-            case 0x05: /* registration descriptor */
-                st->codec->codec_tag = bytestream_get_le32(&p);
-                dprintf(ts->stream, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag);
-                if (st->codec->codec_id == CODEC_ID_NONE &&
-                    stream_type == STREAM_TYPE_PRIVATE_DATA)
-                    mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
-                break;
-            default:
-                break;
-            }
-            p = desc_end;
 
             if (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);
 
             if (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);
index 6be9b73..25f2107 100644 (file)
@@ -63,4 +63,22 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
                            const uint8_t *buf, int len);
 void ff_mpegts_parse_close(MpegTSContext *ts);
 
                            const uint8_t *buf, int len);
 void ff_mpegts_parse_close(MpegTSContext *ts);
 
+/**
+ * Parse an MPEG-2 descriptor
+ * @param[in] fc                    Format context (used for logging only)
+ * @param st                        Stream
+ * @param stream_type               STREAM_TYPE_xxx
+ * @param pp                        Descriptor buffer pointer
+ * @param desc_list_end             End of buffer
+ * @param mp4_dec_config_descr_len  Length of 'mp4_dec_config_descr', or zero if not present
+ * @param mp4_es_id
+ * @param pid
+ * @param mp4_dec_config_descr
+ * @return <0 to stop processing
+ */
+int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
+                              const uint8_t **pp, const uint8_t *desc_list_end,
+                              int mp4_dec_config_descr_len, int mp4_es_id, int pid,
+                              uint8_t *mp4_dec_config_descr);
+
 #endif /* AVFORMAT_MPEGTS_H */
 #endif /* AVFORMAT_MPEGTS_H */