* 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>
... | ... |
@@ -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, \ |