#define BVID_HEADER_SIZE 16
#define MASK_HEADER_SIZE 12
#define BRP_MIN_BUFFER_SIZE FFMAX3(FFMAX3(BRP_FILE_HEADER_SIZE, \
- BRP_BLOCK_HEADER_SIZE, \
- BRP_STREAM_HEADER_SIZE), \
+ BRP_BLOCK_HEADER_SIZE, \
+ BRP_STREAM_HEADER_SIZE), \
BVID_HEADER_SIZE, \
MASK_HEADER_SIZE)
ArgoBVIDHeader *bvid = &hdr->extradata.bvid;
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
-
- /* No decoder for this yet. */
- st->codecpar->codec_id = AV_CODEC_ID_NONE;
+ st->codecpar->codec_id = AV_CODEC_ID_ARGO;
bvid->num_frames = AV_RL32(buf + 0);
bvid->width = AV_RL32(buf + 4);
bvid->height = AV_RL32(buf + 8);
bvid->depth = AV_RL32(buf + 12);
+ if (bvid->num_frames == 0)
+ return AVERROR_INVALIDDATA;
+
/* These are from 1990's games, sanity check this. */
if (bvid->width >= 65536 || bvid->height >= 65536 ||
bvid->depth > 24 || bvid->depth % 8 != 0) {
st->codecpar->width = bvid->width;
st->codecpar->height = bvid->height;
-
- if (bvid->depth == 8) {
- st->codecpar->format = AV_PIX_FMT_PAL8;
- } else if (bvid->depth == 24) {
- st->codecpar->format = AV_PIX_FMT_RGB24;
- } else {
- avpriv_request_sample(s, "depth == %u", bvid->depth);
- return AVERROR_PATCHWELCOME;
- }
+ st->nb_frames = bvid->num_frames;
+ st->codecpar->bits_per_raw_sample = bvid->depth;
} else if (hdr->codec_id == BRP_CODEC_ID_BASF) {
/*
* It would make the demuxer significantly more complicated
if ((ret = ff_argo_asf_validate_file_header(s, &hdr->extradata.basf)) < 0)
return ret;
+
+ st->nb_frames = hdr->extradata.basf.num_chunks;
} else if (hdr->codec_id == BRP_CODEC_ID_MASK) {
ArgoMASKHeader *mask = &hdr->extradata.mask;
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)
- return AVERROR(EIO);
+ if ((ret = avio_read(pb, buf, BRP_BLOCK_HEADER_SIZE)) < 0)
+ return ret;
+ else if (ret != BRP_BLOCK_HEADER_SIZE)
+ return AVERROR(EIO);
- blk.stream_id = AV_RL32(buf + 0);
- blk.start_ms = AV_RL32(buf + 4);
- blk.size = AV_RL32(buf + 8);
+ blk.stream_id = AV_RL32(buf + 0);
+ blk.start_ms = AV_RL32(buf + 4);
+ blk.size = AV_RL32(buf + 8);
if (blk.stream_id == brp->basf.index || blk.stream_id == -1)
break;
ff_argo_asf_parse_chunk_header(&brp->basf.ckhdr, buf);
+ /*
+ * Special Case Hack. It seems that in files where the BASF block isn't first,
+ * v1.1 streams are allowed to be non-22050...
+ * Bump the version to 1.2 so ff_argo_asf_fill_stream() doesn't "correct" it.
+ *
+ * Found in Alien Odyssey games files in:
+ * ./GRAPHICS/COMMBUNK/{{COMADD1,COMM2_{1,2,3E},COMM3_{2,3,4,5,6}},FADE{1,2}}.BRP
+ *
+ * Either this format really inconsistent, or FX Fighter and Croc just ignored the
+ * sample rate field...
+ */
+ if (i != 0 && hdr->extradata.basf.version_major == 1 && hdr->extradata.basf.version_minor == 1)
+ hdr->extradata.basf.version_minor = 2;
+
if ((ret = ff_argo_asf_fill_stream(s, st, &hdr->extradata.basf, &brp->basf.ckhdr)) < 0)
return ret;
return AVERROR_INVALIDDATA;
blk.size -= ASF_CHUNK_HEADER_SIZE;
-
- if (blk.size % st->codecpar->block_align != 0)
- return AVERROR_INVALIDDATA;
}
if ((ret = av_get_packet(s->pb, pkt, blk.size)) < 0)
return 0;
}
-AVInputFormat ff_argo_brp_demuxer = {
+const AVInputFormat ff_argo_brp_demuxer = {
.name = "argo_brp",
.long_name = NULL_IF_CONFIG_SMALL("Argonaut Games BRP"),
.priv_data_size = sizeof(ArgoBRPDemuxContext),