Browse code

Merge commit 'eeadcdfd1a6f3089b6bf6e194d6ece8d3f113123'

* commit 'eeadcdfd1a6f3089b6bf6e194d6ece8d3f113123':
LucasArts SMUSH demuxer

Conflicts:
Changelog
doc/general.texi
libavformat/smush.c
libavformat/version.h

See: bef8fd7099edfac9c487e6eb75d7e6116ad80465
Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2014/04/07 06:24:21
Showing 4 changed files
... ...
@@ -279,6 +279,7 @@ version 1.0:
279 279
 - showwaves and showspectrum filter
280 280
 - LucasArts SMUSH SANM playback support
281 281
 - LucasArts SMUSH VIMA audio decoder (ADPCM)
282
+- LucasArts SMUSH demuxer
282 283
 - SAMI, RealText and SubViewer demuxers and decoders
283 284
 - Heart Of Darkness PAF playback support
284 285
 - iec61883 device
... ...
@@ -20,11 +20,12 @@
20 20
  */
21 21
 
22 22
 #include "libavutil/intreadwrite.h"
23
+
23 24
 #include "avformat.h"
24
-#include "internal.h"
25 25
 #include "avio.h"
26
+#include "internal.h"
26 27
 
27
-typedef struct {
28
+typedef struct SMUSHContext {
28 29
     int version;
29 30
     int audio_stream_index;
30 31
     int video_stream_index;
... ...
@@ -32,9 +33,9 @@ typedef struct {
32 32
 
33 33
 static int smush_read_probe(AVProbeData *p)
34 34
 {
35
-    if (((AV_RL32(p->buf) == MKTAG('S', 'A', 'N', 'M') &&
35
+    if (((AV_RL32(p->buf)     == MKTAG('S', 'A', 'N', 'M') &&
36 36
           AV_RL32(p->buf + 8) == MKTAG('S', 'H', 'D', 'R')) ||
37
-         (AV_RL32(p->buf) == MKTAG('A', 'N', 'I', 'M') &&
37
+         (AV_RL32(p->buf)     == MKTAG('A', 'N', 'I', 'M') &&
38 38
           AV_RL32(p->buf + 8) == MKTAG('A', 'H', 'D', 'R')))) {
39 39
         return AVPROBE_SCORE_MAX;
40 40
     }
... ...
@@ -65,6 +66,8 @@ static int smush_read_header(AVFormatContext *ctx)
65 65
         smush->version = 0;
66 66
         subversion     = avio_rl16(pb);
67 67
         nframes        = avio_rl16(pb);
68
+        if (!nframes)
69
+            return AVERROR_INVALIDDATA;
68 70
 
69 71
         avio_skip(pb, 2); // skip pad
70 72
 
... ...
@@ -72,7 +75,7 @@ static int smush_read_header(AVFormatContext *ctx)
72 72
             palette[i] = avio_rb24(pb);
73 73
 
74 74
         avio_skip(pb, size - (3 * 256 + 6));
75
-    } else if (magic == MKBETAG('S', 'A', 'N', 'M') ) {
75
+    } else if (magic == MKBETAG('S', 'A', 'N', 'M')) {
76 76
         if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R'))
77 77
             return AVERROR_INVALIDDATA;
78 78
 
... ...
@@ -81,8 +84,11 @@ static int smush_read_header(AVFormatContext *ctx)
81 81
             return AVERROR_INVALIDDATA;
82 82
 
83 83
         smush->version = 1;
84
-        subversion     = avio_rl16(pb);
84
+        subversion = avio_rl16(pb);
85 85
         nframes = avio_rl32(pb);
86
+        if (!nframes)
87
+            return AVERROR_INVALIDDATA;
88
+
86 89
         avio_skip(pb, 2); // skip pad
87 90
         width  = avio_rl16(pb);
88 91
         height = avio_rl16(pb);
... ...
@@ -101,12 +107,18 @@ static int smush_read_header(AVFormatContext *ctx)
101 101
 
102 102
             sig        = avio_rb32(pb);
103 103
             chunk_size = avio_rb32(pb);
104
-            read += 8;
104
+            read      += 8;
105 105
             switch (sig) {
106 106
             case MKBETAG('W', 'a', 'v', 'e'):
107 107
                 got_audio = 1;
108 108
                 sample_rate = avio_rl32(pb);
109
-                channels    = avio_rl32(pb);
109
+                if (!sample_rate)
110
+                    return AVERROR_INVALIDDATA;
111
+
112
+                channels = avio_rl32(pb);
113
+                if (!channels)
114
+                    return AVERROR_INVALIDDATA;
115
+
110 116
                 avio_skip(pb, chunk_size - 8);
111 117
                 read += chunk_size;
112 118
                 break;
... ...
@@ -133,17 +145,18 @@ static int smush_read_header(AVFormatContext *ctx)
133 133
 
134 134
     smush->video_stream_index = vst->index;
135 135
 
136
+    avpriv_set_pts_info(vst, 64, 1, 15);
137
+
136 138
     vst->start_time        = 0;
137 139
     vst->duration          =
138 140
     vst->nb_frames         = nframes;
141
+    vst->avg_frame_rate    = av_inv_q(vst->time_base);
139 142
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
140 143
     vst->codec->codec_id   = AV_CODEC_ID_SANM;
141 144
     vst->codec->codec_tag  = 0;
142 145
     vst->codec->width      = width;
143 146
     vst->codec->height     = height;
144 147
 
145
-    avpriv_set_pts_info(vst, 64, 66667, 1000000);
146
-
147 148
     if (!smush->version) {
148 149
         if (ff_alloc_extradata(vst->codec, 1024 + 2))
149 150
             return AVERROR(ENOMEM);
... ...
@@ -162,7 +175,7 @@ static int smush_read_header(AVFormatContext *ctx)
162 162
 
163 163
         ast->start_time         = 0;
164 164
         ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
165
-        ast->codec->codec_id    = AV_CODEC_ID_VIMA;
165
+        ast->codec->codec_id    = AV_CODEC_ID_ADPCM_VIMA;
166 166
         ast->codec->codec_tag   = 0;
167 167
         ast->codec->sample_rate = sample_rate;
168 168
         ast->codec->channels    = channels;
... ...
@@ -178,6 +191,7 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
178 178
     SMUSHContext *smush = ctx->priv_data;
179 179
     AVIOContext *pb = ctx->pb;
180 180
     int done = 0;
181
+    int ret;
181 182
 
182 183
     while (!done) {
183 184
         uint32_t sig, size;
... ...
@@ -185,22 +199,22 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
185 185
         if (url_feof(pb))
186 186
             return AVERROR_EOF;
187 187
 
188
-        sig    = avio_rb32(pb);
189
-        size   = avio_rb32(pb);
188
+        sig  = avio_rb32(pb);
189
+        size = avio_rb32(pb);
190 190
 
191 191
         switch (sig) {
192 192
         case MKBETAG('F', 'R', 'M', 'E'):
193 193
             if (smush->version)
194 194
                 break;
195
-            if (av_get_packet(pb, pkt, size) < 0)
196
-                return AVERROR(EIO);
195
+            if ((ret = av_get_packet(pb, pkt, size)) < 0)
196
+                return ret;
197 197
 
198 198
             pkt->stream_index = smush->video_stream_index;
199 199
             done = 1;
200 200
             break;
201 201
         case MKBETAG('B', 'l', '1', '6'):
202
-            if (av_get_packet(pb, pkt, size) < 0)
203
-                return AVERROR(EIO);
202
+            if ((ret = av_get_packet(pb, pkt, size)) < 0)
203
+                return ret;
204 204
 
205 205
             pkt->stream_index = smush->video_stream_index;
206 206
             pkt->duration = 1;
... ...
@@ -214,7 +228,7 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
214 214
 
215 215
             pkt->stream_index = smush->audio_stream_index;
216 216
             pkt->flags       |= AV_PKT_FLAG_KEY;
217
-            pkt->duration = AV_RB32(pkt->data);
217
+            pkt->duration     = AV_RB32(pkt->data);
218 218
             if (pkt->duration == 0xFFFFFFFFu)
219 219
                 pkt->duration = AV_RB32(pkt->data + 8);
220 220
             done = 1;
... ...
@@ -31,7 +31,7 @@
31 31
 
32 32
 #define LIBAVFORMAT_VERSION_MAJOR 55
33 33
 #define LIBAVFORMAT_VERSION_MINOR 36
34
-#define LIBAVFORMAT_VERSION_MICRO 101
34
+#define LIBAVFORMAT_VERSION_MICRO 102
35 35
 
36 36
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
37 37
                                                LIBAVFORMAT_VERSION_MINOR, \
... ...
@@ -1,4 +1,4 @@
1
-#tb 0: 66667/1000000
1
+#tb 0: 1/15
2 2
 0,          0,          0,        1,   921600, 0x00000000
3 3
 0,          1,          1,        1,   921600, 0x00000000
4 4
 0,          2,          2,        1,   921600, 0x00000000