]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/smush.c
Merge commit '32d05934abc7427bb90380a4c1ab20a15fd7d821'
[ffmpeg] / libavformat / smush.c
index e9c1937398df8ad2949ec4cfaf1da10ca84025a8..a33d50915a7f5da2a8fa23f3bee7642fc93db058 100644 (file)
  */
 
 #include "libavutil/intreadwrite.h"
+
 #include "avformat.h"
-#include "internal.h"
 #include "avio.h"
+#include "internal.h"
 
-typedef struct {
+typedef struct SMUSHContext {
     int version;
     int audio_stream_index;
     int video_stream_index;
@@ -32,9 +33,9 @@ typedef struct {
 
 static int smush_read_probe(AVProbeData *p)
 {
-    if (((AV_RL32(p->buf) == MKTAG('S', 'A', 'N', 'M') &&
+    if (((AV_RL32(p->buf)     == MKTAG('S', 'A', 'N', 'M') &&
           AV_RL32(p->buf + 8) == MKTAG('S', 'H', 'D', 'R')) ||
-         (AV_RL32(p->buf) == MKTAG('A', 'N', 'I', 'M') &&
+         (AV_RL32(p->buf)     == MKTAG('A', 'N', 'I', 'M') &&
           AV_RL32(p->buf + 8) == MKTAG('A', 'H', 'D', 'R')))) {
         return AVPROBE_SCORE_MAX;
     }
@@ -65,6 +66,8 @@ static int smush_read_header(AVFormatContext *ctx)
         smush->version = 0;
         subversion     = avio_rl16(pb);
         nframes        = avio_rl16(pb);
+        if (!nframes)
+            return AVERROR_INVALIDDATA;
 
         avio_skip(pb, 2); // skip pad
 
@@ -72,7 +75,7 @@ static int smush_read_header(AVFormatContext *ctx)
             palette[i] = avio_rb24(pb);
 
         avio_skip(pb, size - (3 * 256 + 6));
-    } else if (magic == MKBETAG('S', 'A', 'N', 'M') ) {
+    } else if (magic == MKBETAG('S', 'A', 'N', 'M')) {
         if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R'))
             return AVERROR_INVALIDDATA;
 
@@ -81,8 +84,11 @@ static int smush_read_header(AVFormatContext *ctx)
             return AVERROR_INVALIDDATA;
 
         smush->version = 1;
-        subversion     = avio_rl16(pb);
+        subversion = avio_rl16(pb);
         nframes = avio_rl32(pb);
+        if (!nframes)
+            return AVERROR_INVALIDDATA;
+
         avio_skip(pb, 2); // skip pad
         width  = avio_rl16(pb);
         height = avio_rl16(pb);
@@ -101,12 +107,18 @@ static int smush_read_header(AVFormatContext *ctx)
 
             sig        = avio_rb32(pb);
             chunk_size = avio_rb32(pb);
-            read += 8;
+            read      += 8;
             switch (sig) {
             case MKBETAG('W', 'a', 'v', 'e'):
                 got_audio = 1;
                 sample_rate = avio_rl32(pb);
-                channels    = avio_rl32(pb);
+                if (!sample_rate)
+                    return AVERROR_INVALIDDATA;
+
+                channels = avio_rl32(pb);
+                if (!channels)
+                    return AVERROR_INVALIDDATA;
+
                 avio_skip(pb, chunk_size - 8);
                 read += chunk_size;
                 break;
@@ -133,17 +145,18 @@ static int smush_read_header(AVFormatContext *ctx)
 
     smush->video_stream_index = vst->index;
 
+    avpriv_set_pts_info(vst, 64, 1, 15);
+
     vst->start_time        = 0;
     vst->duration          =
     vst->nb_frames         = nframes;
+    vst->avg_frame_rate    = av_inv_q(vst->time_base);
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     vst->codec->codec_id   = AV_CODEC_ID_SANM;
     vst->codec->codec_tag  = 0;
     vst->codec->width      = width;
     vst->codec->height     = height;
 
-    avpriv_set_pts_info(vst, 64, 66667, 1000000);
-
     if (!smush->version) {
         if (ff_alloc_extradata(vst->codec, 1024 + 2))
             return AVERROR(ENOMEM);
@@ -162,7 +175,7 @@ static int smush_read_header(AVFormatContext *ctx)
 
         ast->start_time         = 0;
         ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
-        ast->codec->codec_id    = AV_CODEC_ID_VIMA;
+        ast->codec->codec_id    = AV_CODEC_ID_ADPCM_VIMA;
         ast->codec->codec_tag   = 0;
         ast->codec->sample_rate = sample_rate;
         ast->codec->channels    = channels;
@@ -178,6 +191,7 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
     SMUSHContext *smush = ctx->priv_data;
     AVIOContext *pb = ctx->pb;
     int done = 0;
+    int ret;
 
     while (!done) {
         uint32_t sig, size;
@@ -185,22 +199,22 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
         if (url_feof(pb))
             return AVERROR_EOF;
 
-        sig    = avio_rb32(pb);
-        size   = avio_rb32(pb);
+        sig  = avio_rb32(pb);
+        size = avio_rb32(pb);
 
         switch (sig) {
         case MKBETAG('F', 'R', 'M', 'E'):
             if (smush->version)
                 break;
-            if (av_get_packet(pb, pkt, size) < 0)
-                return AVERROR(EIO);
+            if ((ret = av_get_packet(pb, pkt, size)) < 0)
+                return ret;
 
             pkt->stream_index = smush->video_stream_index;
             done = 1;
             break;
         case MKBETAG('B', 'l', '1', '6'):
-            if (av_get_packet(pb, pkt, size) < 0)
-                return AVERROR(EIO);
+            if ((ret = av_get_packet(pb, pkt, size)) < 0)
+                return ret;
 
             pkt->stream_index = smush->video_stream_index;
             pkt->duration = 1;
@@ -214,7 +228,7 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
 
             pkt->stream_index = smush->audio_stream_index;
             pkt->flags       |= AV_PKT_FLAG_KEY;
-            pkt->duration = AV_RB32(pkt->data);
+            pkt->duration     = AV_RB32(pkt->data);
             if (pkt->duration == 0xFFFFFFFFu)
                 pkt->duration = AV_RB32(pkt->data + 8);
             done = 1;