Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Eugen Hoyos <cehoyos@ag.or.at>2016-04-15 22:22:10 +0300
committerCarl Eugen Hoyos <cehoyos@ag.or.at>2016-04-15 22:22:10 +0300
commit6d39132fd4af51dfaa86d66bd3e8be59714d2647 (patch)
treede9830eb2d9eddb00833c6a30e7cdf5580475d46 /libavformat/bink.c
parent139cbeb75e0f5e3176b2b09660d2570b1bcc2408 (diff)
lavf/bink: Support Monkey Island 4 (SMUSH) files.
Fixes ticket #5410.
Diffstat (limited to 'libavformat/bink.c')
-rw-r--r--libavformat/bink.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/libavformat/bink.c b/libavformat/bink.c
index b95c83d97d..646d874461 100644
--- a/libavformat/bink.c
+++ b/libavformat/bink.c
@@ -45,6 +45,7 @@ enum BinkAudFlags {
#define BINK_MAX_AUDIO_TRACKS 256
#define BINK_MAX_WIDTH 7680
#define BINK_MAX_HEIGHT 4800
+#define SMUSH_BLOCK_SIZE 512
typedef struct BinkDemuxContext {
uint32_t file_size;
@@ -55,12 +56,15 @@ typedef struct BinkDemuxContext {
int64_t audio_pts[BINK_MAX_AUDIO_TRACKS];
uint32_t remain_packet_size;
+ int smush_size;
} BinkDemuxContext;
static int probe(AVProbeData *p)
{
const uint8_t *b = p->buf;
+ int smush = AV_RN32(p->buf) == AV_RN32("SMUS");
+ do {
if (((b[0] == 'B' && b[1] == 'I' && b[2] == 'K' &&
(b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i')) ||
(b[0] == 'K' && b[1] == 'B' && b[2] == '2' && /* Bink 2 */
@@ -70,6 +74,8 @@ static int probe(AVProbeData *p)
AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT &&
AV_RL32(b+28) > 0 && AV_RL32(b+32) > 0) // fps num,den
return AVPROBE_SCORE_MAX;
+ b += SMUSH_BLOCK_SIZE;
+ } while (smush && b < p->buf + p->buf_size - 32);
return 0;
}
@@ -90,6 +96,17 @@ static int read_header(AVFormatContext *s)
return AVERROR(ENOMEM);
vst->codecpar->codec_tag = avio_rl32(pb);
+ if (vst->codecpar->codec_tag == AV_RL32("SMUS")) {
+ do {
+ bink->smush_size += SMUSH_BLOCK_SIZE;
+ avio_skip(pb, SMUSH_BLOCK_SIZE - 4);
+ vst->codecpar->codec_tag = avio_rl32(pb);
+ } while (!avio_feof(pb) && (vst->codecpar->codec_tag & 0xFFFFFF) != AV_RL32("BIK"));
+ if (avio_feof(pb)) {
+ av_log(s, AV_LOG_ERROR, "invalid SMUSH header: BIK not found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
bink->file_size = avio_rl32(pb) + 8;
vst->duration = avio_rl32(pb);
@@ -195,7 +212,7 @@ static int read_header(AVFormatContext *s)
}
if (vst->index_entries)
- avio_seek(pb, vst->index_entries[0].pos, SEEK_SET);
+ avio_seek(pb, vst->index_entries[0].pos + bink->smush_size, SEEK_SET);
else
avio_skip(pb, 4);
@@ -279,7 +296,7 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
return -1;
/* seek to the first frame */
- if (avio_seek(s->pb, vst->index_entries[0].pos, SEEK_SET) < 0)
+ if (avio_seek(s->pb, vst->index_entries[0].pos + bink->smush_size, SEEK_SET) < 0)
return -1;
bink->video_pts = 0;