From: Zane van Iperen Date: Fri, 25 Sep 2020 02:49:58 +0000 (+1000) Subject: avformat/argo_brp: handle the case where the BASF block isn't the first X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=da5ab5a0b638d214f7efcf4b22bae8a87d9e565b;hp=2e7752affff242030edd016946289dc55eb0d617;p=ffmpeg avformat/argo_brp: handle the case where the BASF block isn't the first Signed-off-by: Zane van Iperen --- diff --git a/libavformat/argo_brp.c b/libavformat/argo_brp.c index 613f04aef27..d3aab92af08 100644 --- a/libavformat/argo_brp.c +++ b/libavformat/argo_brp.c @@ -32,6 +32,7 @@ #define BRP_BLOCK_HEADER_SIZE 12 #define BRP_STREAM_HEADER_SIZE 20 #define BRP_MAX_STREAMS 32 /* Soft cap, but even this is overkill. */ +#define BRP_BASF_LOOKAHEAD 10 /* How many blocks to search for the first BASF one. */ #define BVID_HEADER_SIZE 16 #define MASK_HEADER_SIZE 12 #define BRP_MIN_BUFFER_SIZE FFMAX3(FFMAX3(BRP_FILE_HEADER_SIZE, \ @@ -269,16 +270,13 @@ static int argo_brp_read_header(AVFormatContext *s) } } - /* - * This is nasty. BASF streams have their chunk header in each block, - * so the first one needs to be read to get the stream info. It should - * always be the first one. - */ + /* Try to find the first BASF chunk. */ if (brp->basf.index >= 0) { AVStream *st = s->streams[brp->basf.index]; ArgoBRPStreamHeader *hdr = brp->streams + brp->basf.index; ArgoBRPBlockHeader blk; int64_t offset; + int i; av_assert0(st->codecpar->codec_id == AV_CODEC_ID_ADPCM_ARGO); av_assert0(brp->streams[brp->basf.index].extradata_size == ASF_FILE_HEADER_SIZE); @@ -288,6 +286,9 @@ static int argo_brp_read_header(AVFormatContext *s) offset = ret; + av_log(s, AV_LOG_TRACE, "Searching %d blocks for BASF...", BRP_BASF_LOOKAHEAD); + + for (i = 0; i < BRP_BASF_LOOKAHEAD; i++) { if ((ret = avio_read(pb, buf, BRP_BLOCK_HEADER_SIZE)) < 0) return ret; else if (ret != BRP_BLOCK_HEADER_SIZE) @@ -297,11 +298,21 @@ static int argo_brp_read_header(AVFormatContext *s) blk.start_ms = AV_RL32(buf + 4); blk.size = AV_RL32(buf + 8); - if (blk.stream_id != brp->basf.index) { - avpriv_request_sample(s, "first block not BASF"); - return AVERROR_PATCHWELCOME; + if (blk.stream_id == brp->basf.index || blk.stream_id == -1) + break; + + if ((ret = avio_skip(pb, blk.size)) < 0) + return ret; + } + + if (i == BRP_BASF_LOOKAHEAD || blk.stream_id == -1) { + /* Don't error here, as there may still be a valid video stream. */ + av_log(s, AV_LOG_TRACE, "not found\n"); + goto done; } + av_log(s, AV_LOG_TRACE, "found at index %d\n", i); + if (blk.size < ASF_CHUNK_HEADER_SIZE) return AVERROR_INVALIDDATA; @@ -319,6 +330,7 @@ static int argo_brp_read_header(AVFormatContext *s) st->start_time = av_rescale_rnd(blk.start_ms, st->codecpar->sample_rate, 1000, AV_ROUND_UP); st->duration = av_rescale_rnd(hdr->duration_ms, st->codecpar->sample_rate, 1000, AV_ROUND_UP); +done: if ((ret = avio_seek(s->pb, offset, SEEK_SET)) < 0) return ret; }