[FFmpeg-devel] [PATCH]lavf/bink: Support SMUSH files

Carl Eugen Hoyos cehoyos at ag.or.at
Thu Apr 7 02:49:34 CEST 2016


On Wednesday 06 April 2016 11:18:20 pm Carl Eugen Hoyos wrote:
> Hi!
>
> Attached patch fixes ticket #5410 for me.

New patch for Monkey Island 4 files attached.

Please comment, Carl Eugen
-------------- next part --------------
diff --git a/libavformat/bink.c b/libavformat/bink.c
index 332edbb..3f273bc 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,14 @@ 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;
 
+    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 +73,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 (b < p->buf + p->buf_size - 32);
     return 0;
 }
 
@@ -90,6 +95,17 @@ static int read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
 
     vst->codec->codec_tag = avio_rl32(pb);
+    if (vst->codec->codec_tag == AV_RL32("SMUS")) {
+        do {
+            bink->smush_size += SMUSH_BLOCK_SIZE;
+            avio_skip(pb, SMUSH_BLOCK_SIZE - 4);
+            vst->codec->codec_tag = avio_rl32(pb);
+        } while (!avio_feof(pb) && (vst->codec->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 +211,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 +295,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;


More information about the ffmpeg-devel mailing list