summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorZane van Iperen <zane@zanevaniperen.com>2020-09-25 12:49:58 +1000
committerZane van Iperen <zane@zanevaniperen.com>2020-09-27 09:11:35 +1000
commitda5ab5a0b638d214f7efcf4b22bae8a87d9e565b (patch)
tree0fbe8dc2e82fd3d14e837c40c3fbb1107d8af05d /libavformat
parent2e7752affff242030edd016946289dc55eb0d617 (diff)
avformat/argo_brp: handle the case where the BASF block isn't the first
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/argo_brp.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/libavformat/argo_brp.c b/libavformat/argo_brp.c
index 613f04aef2..d3aab92af0 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;
}