From b834becdaed1019d926a957628ecd54a69694cb4 Mon Sep 17 00:00:00 2001 From: Reimar Döffinger Date: Wed, 14 Jul 2010 17:28:40 +0000 Subject: 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 --- libavcodec/dvbsubdec.c | 13 ++++++++++--- libavformat/mpegts.c | 15 +++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index d1d01fd13d..3e06260398 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -358,8 +358,14 @@ static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) int i, r, g, b, a = 0; DVBSubContext *ctx = avctx->priv_data; - ctx->composition_id = avctx->sub_id & 0xffff; - ctx->ancillary_id = avctx->sub_id >> 16; + if (!avctx->extradata || avctx->extradata_size != 4) { + av_log(avctx, AV_LOG_WARNING, "Invalid extradata, subtitle streams may be combined!\n"); + ctx->composition_id = -1; + ctx->ancillary_id = -1; + } else { + ctx->composition_id = AV_RB16(avctx->extradata); + ctx->ancillary_id = AV_RB16(avctx->extradata + 2); + } default_clut.id = -1; default_clut.next = NULL; @@ -1434,7 +1440,8 @@ static int dvbsub_decode(AVCodecContext *avctx, segment_length = AV_RB16(p); p += 2; - if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) { + if (page_id == ctx->composition_id || page_id == ctx->ancillary_id || + ctx->composition_id == -1 || ctx->ancillary_id == -1) { switch (segment_type) { case DVBSUB_PAGE_SEGMENT: dvbsub_parse_page_segment(avctx, p, segment_length); diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index d9ee987e1d..b1600901e2 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -860,7 +860,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len const uint8_t *p, *p_end, *desc_list_end, *desc_end; int program_info_length, pcr_pid, pid, stream_type; int desc_list_len, desc_len, desc_tag; - int comp_page, anc_page; char language[4]; uint32_t prog_reg_desc = 0; /* registration descriptor */ @@ -981,9 +980,17 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len language[2] = get8(&p, desc_end); language[3] = 0; get8(&p, desc_end); - comp_page = get16(&p, desc_end); - anc_page = get16(&p, desc_end); - st->codec->sub_id = (anc_page << 16) | comp_page; + 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 */ -- cgit v1.2.3