Browse code

Pass the composition and ancillary ID for DVB subtitles via extradata instead of sub_id, this allows detecting when that information is not available and just decode everything. In addition extradata is required for many codecs and thus in contrast to sub_id generally already passed on by any programs using libav*. Also ask for a sample if we encounter a stream with multiple/changing IDs.

Originally committed as revision 24238 to svn://svn.ffmpeg.org/ffmpeg/trunk

Reimar Döffinger authored on 2010/07/15 02:28:40
Showing 2 changed files
... ...
@@ -358,8 +358,14 @@ static av_cold int dvbsub_init_decoder(AVCodecContext *avctx)
358 358
     int i, r, g, b, a = 0;
359 359
     DVBSubContext *ctx = avctx->priv_data;
360 360
 
361
-    ctx->composition_id = avctx->sub_id & 0xffff;
362
-    ctx->ancillary_id = avctx->sub_id >> 16;
361
+    if (!avctx->extradata || avctx->extradata_size != 4) {
362
+        av_log(avctx, AV_LOG_WARNING, "Invalid extradata, subtitle streams may be combined!\n");
363
+        ctx->composition_id = -1;
364
+        ctx->ancillary_id   = -1;
365
+    } else {
366
+        ctx->composition_id = AV_RB16(avctx->extradata);
367
+        ctx->ancillary_id   = AV_RB16(avctx->extradata + 2);
368
+    }
363 369
 
364 370
     default_clut.id = -1;
365 371
     default_clut.next = NULL;
... ...
@@ -1434,7 +1440,8 @@ static int dvbsub_decode(AVCodecContext *avctx,
1434 1434
         segment_length = AV_RB16(p);
1435 1435
         p += 2;
1436 1436
 
1437
-        if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) {
1437
+        if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
1438
+            ctx->composition_id == -1 || ctx->ancillary_id == -1) {
1438 1439
             switch (segment_type) {
1439 1440
             case DVBSUB_PAGE_SEGMENT:
1440 1441
                 dvbsub_parse_page_segment(avctx, p, segment_length);
... ...
@@ -860,7 +860,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
860 860
     const uint8_t *p, *p_end, *desc_list_end, *desc_end;
861 861
     int program_info_length, pcr_pid, pid, stream_type;
862 862
     int desc_list_len, desc_len, desc_tag;
863
-    int comp_page, anc_page;
864 863
     char language[4];
865 864
     uint32_t prog_reg_desc = 0; /* registration descriptor */
866 865
 
... ...
@@ -981,9 +980,17 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
981 981
                 language[2] = get8(&p, desc_end);
982 982
                 language[3] = 0;
983 983
                 get8(&p, desc_end);
984
-                comp_page = get16(&p, desc_end);
985
-                anc_page = get16(&p, desc_end);
986
-                st->codec->sub_id = (anc_page << 16) | comp_page;
984
+                if (st->codec->extradata) {
985
+                    if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, p, 4))
986
+                        av_log_ask_for_sample(ts->stream, "DVB sub with multiple IDs\n");
987
+                } else {
988
+                    st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
989
+                    if (st->codec->extradata) {
990
+                        st->codec->extradata_size = 4;
991
+                        memcpy(st->codec->extradata, p, 4);
992
+                    }
993
+                }
994
+                p += 4;
987 995
                 av_metadata_set2(&st->metadata, "language", language, 0);
988 996
                 break;
989 997
             case 0x0a: /* ISO 639 language descriptor */