diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2015-08-14 04:37:08 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2015-08-14 04:40:00 +0200 |
commit | 856452cf63afad723230e02e069c79a18ac3814c (patch) | |
tree | 1ac01db57051022251a5484f4e1893b5f7f42ef1 | |
parent | 02fff499362daedcdcb0a9cdd517257843600563 (diff) | |
download | ffmpeg-856452cf63afad723230e02e069c79a18ac3814c.tar.gz |
avformat/rmdec: MLTI with multiple MDPR support
Fixes Ticket4496
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavformat/rmdec.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index e60b81d141..09889f6efa 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -501,6 +501,7 @@ static int rm_read_header(AVFormatContext *s) int flags = 0; int ret = -1; unsigned size, v; + int64_t codec_pos; tag = avio_rl32(pb); if (tag == MKTAG('.', 'r', 'a', 0xfd)) { @@ -573,6 +574,7 @@ static int rm_read_header(AVFormatContext *s) return AVERROR(ENOMEM); size = avio_rb32(pb); + codec_pos = avio_tell(pb); ffio_ensure_seekback(pb, 4); v = avio_rb32(pb); @@ -580,20 +582,45 @@ static int rm_read_header(AVFormatContext *s) int number_of_streams = avio_rb16(pb); int number_of_mdpr; int i; + unsigned size2; for (i = 0; i<number_of_streams; i++) avio_rb16(pb); number_of_mdpr = avio_rb16(pb); if (number_of_mdpr != 1) { avpriv_request_sample(s, "MLTI with multiple (%d) MDPR", number_of_mdpr); } - avio_rb32(pb); - size -= 4+2+2*number_of_streams+2+4; - } else + for (i = 0; i < number_of_mdpr; i++) { + AVStream *st2; + if (i > 0) { + st2 = avformat_new_stream(s, NULL); + if (!st2) { + ret = AVERROR(ENOMEM); + goto fail; + } + st2->id = st->id + (i<<16); + st2->codec->bit_rate = st->codec->bit_rate; + st2->start_time = st->start_time; + st2->duration = st->duration; + st2->codec->codec_type = AVMEDIA_TYPE_DATA; + st2->priv_data = ff_rm_alloc_rmstream(); + if (!st2->priv_data) + return AVERROR(ENOMEM); + } else + st2 = st; + + size2 = avio_rb32(pb); + if (ff_rm_read_mdpr_codecdata(s, s->pb, st2, st2->priv_data, + size2, mime) < 0) + goto fail; + } + avio_seek(pb, codec_pos + size, SEEK_SET); + } else { avio_skip(pb, -4); + if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, + size, mime) < 0) + goto fail; + } - if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, - size, mime) < 0) - goto fail; break; case MKTAG('D', 'A', 'T', 'A'): goto header_end; @@ -651,9 +678,11 @@ static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stre while(!avio_feof(pb)){ int len, num, i; + int mlti_id; *pos= avio_tell(pb) - 3; if(rm->remaining_len > 0){ num= rm->current_stream; + mlti_id = 0; len= rm->remaining_len; *timestamp = AV_NOPTS_VALUE; *flags= 0; @@ -689,12 +718,13 @@ static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stre num = avio_rb16(pb); *timestamp = avio_rb32(pb); - avio_r8(pb); /* reserved */ + mlti_id = (avio_r8(pb)>>1)-1<<16; + mlti_id = FFMAX(mlti_id, 0); *flags = avio_r8(pb); /* flags */ } for(i=0;i<s->nb_streams;i++) { st = s->streams[i]; - if (num == st->id) + if (mlti_id + num == st->id) break; } if (i == s->nb_streams) { |