yading@11
|
1 /*
|
yading@11
|
2 * WAV demuxer
|
yading@11
|
3 * Copyright (c) 2001, 2002 Fabrice Bellard
|
yading@11
|
4 *
|
yading@11
|
5 * Sony Wave64 demuxer
|
yading@11
|
6 * RF64 demuxer
|
yading@11
|
7 * Copyright (c) 2009 Daniel Verkamp
|
yading@11
|
8 *
|
yading@11
|
9 * This file is part of FFmpeg.
|
yading@11
|
10 *
|
yading@11
|
11 * FFmpeg is free software; you can redistribute it and/or
|
yading@11
|
12 * modify it under the terms of the GNU Lesser General Public
|
yading@11
|
13 * License as published by the Free Software Foundation; either
|
yading@11
|
14 * version 2.1 of the License, or (at your option) any later version.
|
yading@11
|
15 *
|
yading@11
|
16 * FFmpeg is distributed in the hope that it will be useful,
|
yading@11
|
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@11
|
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@11
|
19 * Lesser General Public License for more details.
|
yading@11
|
20 *
|
yading@11
|
21 * You should have received a copy of the GNU Lesser General Public
|
yading@11
|
22 * License along with FFmpeg; if not, write to the Free Software
|
yading@11
|
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@11
|
24 */
|
yading@11
|
25
|
yading@11
|
26 #include "libavutil/avassert.h"
|
yading@11
|
27 #include "libavutil/dict.h"
|
yading@11
|
28 #include "libavutil/log.h"
|
yading@11
|
29 #include "libavutil/mathematics.h"
|
yading@11
|
30 #include "libavutil/opt.h"
|
yading@11
|
31 #include "avformat.h"
|
yading@11
|
32 #include "internal.h"
|
yading@11
|
33 #include "avio_internal.h"
|
yading@11
|
34 #include "pcm.h"
|
yading@11
|
35 #include "riff.h"
|
yading@11
|
36 #include "w64.h"
|
yading@11
|
37 #include "avio.h"
|
yading@11
|
38 #include "metadata.h"
|
yading@11
|
39 #include "spdif.h"
|
yading@11
|
40
|
yading@11
|
41 typedef struct WAVDemuxContext {
|
yading@11
|
42 const AVClass *class;
|
yading@11
|
43 int64_t data_end;
|
yading@11
|
44 int w64;
|
yading@11
|
45 int64_t smv_data_ofs;
|
yading@11
|
46 int smv_block_size;
|
yading@11
|
47 int smv_frames_per_jpeg;
|
yading@11
|
48 int smv_block;
|
yading@11
|
49 int smv_last_stream;
|
yading@11
|
50 int smv_eof;
|
yading@11
|
51 int audio_eof;
|
yading@11
|
52 int ignore_length;
|
yading@11
|
53 int spdif;
|
yading@11
|
54 } WAVDemuxContext;
|
yading@11
|
55
|
yading@11
|
56
|
yading@11
|
57 #if CONFIG_WAV_DEMUXER
|
yading@11
|
58
|
yading@11
|
59 static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
|
yading@11
|
60 {
|
yading@11
|
61 *tag = avio_rl32(pb);
|
yading@11
|
62 return avio_rl32(pb);
|
yading@11
|
63 }
|
yading@11
|
64
|
yading@11
|
65 /* return the size of the found tag */
|
yading@11
|
66 static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
|
yading@11
|
67 {
|
yading@11
|
68 unsigned int tag;
|
yading@11
|
69 int64_t size;
|
yading@11
|
70
|
yading@11
|
71 for (;;) {
|
yading@11
|
72 if (url_feof(pb))
|
yading@11
|
73 return -1;
|
yading@11
|
74 size = next_tag(pb, &tag);
|
yading@11
|
75 if (tag == tag1)
|
yading@11
|
76 break;
|
yading@11
|
77 avio_skip(pb, size + (size & 1));
|
yading@11
|
78 }
|
yading@11
|
79 return size;
|
yading@11
|
80 }
|
yading@11
|
81
|
yading@11
|
82 static int wav_probe(AVProbeData *p)
|
yading@11
|
83 {
|
yading@11
|
84 /* check file header */
|
yading@11
|
85 if (p->buf_size <= 32)
|
yading@11
|
86 return 0;
|
yading@11
|
87 if (!memcmp(p->buf + 8, "WAVE", 4)) {
|
yading@11
|
88 if (!memcmp(p->buf, "RIFF", 4))
|
yading@11
|
89 /*
|
yading@11
|
90 Since ACT demuxer has standard WAV header at top of it's own,
|
yading@11
|
91 returning score is decreased to avoid probe conflict
|
yading@11
|
92 between ACT and WAV.
|
yading@11
|
93 */
|
yading@11
|
94 return AVPROBE_SCORE_MAX - 1;
|
yading@11
|
95 else if (!memcmp(p->buf, "RF64", 4) &&
|
yading@11
|
96 !memcmp(p->buf + 12, "ds64", 4))
|
yading@11
|
97 return AVPROBE_SCORE_MAX;
|
yading@11
|
98 }
|
yading@11
|
99 return 0;
|
yading@11
|
100 }
|
yading@11
|
101
|
yading@11
|
102 static void handle_stream_probing(AVStream *st)
|
yading@11
|
103 {
|
yading@11
|
104 if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
|
yading@11
|
105 st->request_probe = AVPROBE_SCORE_MAX/2;
|
yading@11
|
106 st->probe_packets = FFMIN(st->probe_packets, 4);
|
yading@11
|
107 }
|
yading@11
|
108 }
|
yading@11
|
109
|
yading@11
|
110 static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
|
yading@11
|
111 {
|
yading@11
|
112 AVIOContext *pb = s->pb;
|
yading@11
|
113 int ret;
|
yading@11
|
114
|
yading@11
|
115 /* parse fmt header */
|
yading@11
|
116 *st = avformat_new_stream(s, NULL);
|
yading@11
|
117 if (!*st)
|
yading@11
|
118 return AVERROR(ENOMEM);
|
yading@11
|
119
|
yading@11
|
120 ret = ff_get_wav_header(pb, (*st)->codec, size);
|
yading@11
|
121 if (ret < 0)
|
yading@11
|
122 return ret;
|
yading@11
|
123 handle_stream_probing(*st);
|
yading@11
|
124
|
yading@11
|
125 (*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
|
yading@11
|
126
|
yading@11
|
127 avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
|
yading@11
|
128
|
yading@11
|
129 return 0;
|
yading@11
|
130 }
|
yading@11
|
131
|
yading@11
|
132 static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
|
yading@11
|
133 int length)
|
yading@11
|
134 {
|
yading@11
|
135 char temp[257];
|
yading@11
|
136 int ret;
|
yading@11
|
137
|
yading@11
|
138 av_assert0(length <= sizeof(temp));
|
yading@11
|
139 if ((ret = avio_read(s->pb, temp, length)) < 0)
|
yading@11
|
140 return ret;
|
yading@11
|
141
|
yading@11
|
142 temp[length] = 0;
|
yading@11
|
143
|
yading@11
|
144 if (strlen(temp))
|
yading@11
|
145 return av_dict_set(&s->metadata, key, temp, 0);
|
yading@11
|
146
|
yading@11
|
147 return 0;
|
yading@11
|
148 }
|
yading@11
|
149
|
yading@11
|
150 static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
|
yading@11
|
151 {
|
yading@11
|
152 char temp[131], *coding_history;
|
yading@11
|
153 int ret, x;
|
yading@11
|
154 uint64_t time_reference;
|
yading@11
|
155 int64_t umid_parts[8], umid_mask = 0;
|
yading@11
|
156
|
yading@11
|
157 if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 ||
|
yading@11
|
158 (ret = wav_parse_bext_string(s, "originator", 32)) < 0 ||
|
yading@11
|
159 (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 ||
|
yading@11
|
160 (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 ||
|
yading@11
|
161 (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0)
|
yading@11
|
162 return ret;
|
yading@11
|
163
|
yading@11
|
164 time_reference = avio_rl64(s->pb);
|
yading@11
|
165 snprintf(temp, sizeof(temp), "%"PRIu64, time_reference);
|
yading@11
|
166 if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0)
|
yading@11
|
167 return ret;
|
yading@11
|
168
|
yading@11
|
169 /* check if version is >= 1, in which case an UMID may be present */
|
yading@11
|
170 if (avio_rl16(s->pb) >= 1) {
|
yading@11
|
171 for (x = 0; x < 8; x++)
|
yading@11
|
172 umid_mask |= umid_parts[x] = avio_rb64(s->pb);
|
yading@11
|
173
|
yading@11
|
174 if (umid_mask) {
|
yading@11
|
175 /* the string formatting below is per SMPTE 330M-2004 Annex C */
|
yading@11
|
176 if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) {
|
yading@11
|
177 /* basic UMID */
|
yading@11
|
178 snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
|
yading@11
|
179 umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]);
|
yading@11
|
180 } else {
|
yading@11
|
181 /* extended UMID */
|
yading@11
|
182 snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
|
yading@11
|
183 "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
|
yading@11
|
184 umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
|
yading@11
|
185 umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
|
yading@11
|
186 }
|
yading@11
|
187
|
yading@11
|
188 if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
|
yading@11
|
189 return ret;
|
yading@11
|
190 }
|
yading@11
|
191
|
yading@11
|
192 avio_skip(s->pb, 190);
|
yading@11
|
193 } else
|
yading@11
|
194 avio_skip(s->pb, 254);
|
yading@11
|
195
|
yading@11
|
196 if (size > 602) {
|
yading@11
|
197 /* CodingHistory present */
|
yading@11
|
198 size -= 602;
|
yading@11
|
199
|
yading@11
|
200 if (!(coding_history = av_malloc(size+1)))
|
yading@11
|
201 return AVERROR(ENOMEM);
|
yading@11
|
202
|
yading@11
|
203 if ((ret = avio_read(s->pb, coding_history, size)) < 0)
|
yading@11
|
204 return ret;
|
yading@11
|
205
|
yading@11
|
206 coding_history[size] = 0;
|
yading@11
|
207 if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history,
|
yading@11
|
208 AV_DICT_DONT_STRDUP_VAL)) < 0)
|
yading@11
|
209 return ret;
|
yading@11
|
210 }
|
yading@11
|
211
|
yading@11
|
212 return 0;
|
yading@11
|
213 }
|
yading@11
|
214
|
yading@11
|
215 static const AVMetadataConv wav_metadata_conv[] = {
|
yading@11
|
216 {"description", "comment" },
|
yading@11
|
217 {"originator", "encoded_by" },
|
yading@11
|
218 {"origination_date", "date" },
|
yading@11
|
219 {"origination_time", "creation_time"},
|
yading@11
|
220 {0},
|
yading@11
|
221 };
|
yading@11
|
222
|
yading@11
|
223 /* wav input */
|
yading@11
|
224 static int wav_read_header(AVFormatContext *s)
|
yading@11
|
225 {
|
yading@11
|
226 int64_t size, av_uninit(data_size);
|
yading@11
|
227 int64_t sample_count=0;
|
yading@11
|
228 int rf64;
|
yading@11
|
229 uint32_t tag;
|
yading@11
|
230 AVIOContext *pb = s->pb;
|
yading@11
|
231 AVStream *st = NULL;
|
yading@11
|
232 WAVDemuxContext *wav = s->priv_data;
|
yading@11
|
233 int ret, got_fmt = 0;
|
yading@11
|
234 int64_t next_tag_ofs, data_ofs = -1;
|
yading@11
|
235
|
yading@11
|
236 wav->smv_data_ofs = -1;
|
yading@11
|
237
|
yading@11
|
238 /* check RIFF header */
|
yading@11
|
239 tag = avio_rl32(pb);
|
yading@11
|
240
|
yading@11
|
241 rf64 = tag == MKTAG('R', 'F', '6', '4');
|
yading@11
|
242 if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
|
yading@11
|
243 return -1;
|
yading@11
|
244 avio_rl32(pb); /* file size */
|
yading@11
|
245 tag = avio_rl32(pb);
|
yading@11
|
246 if (tag != MKTAG('W', 'A', 'V', 'E'))
|
yading@11
|
247 return -1;
|
yading@11
|
248
|
yading@11
|
249 if (rf64) {
|
yading@11
|
250 if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
|
yading@11
|
251 return -1;
|
yading@11
|
252 size = avio_rl32(pb);
|
yading@11
|
253 if (size < 24)
|
yading@11
|
254 return -1;
|
yading@11
|
255 avio_rl64(pb); /* RIFF size */
|
yading@11
|
256 data_size = avio_rl64(pb);
|
yading@11
|
257 sample_count = avio_rl64(pb);
|
yading@11
|
258 if (data_size < 0 || sample_count < 0) {
|
yading@11
|
259 av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
|
yading@11
|
260 "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
|
yading@11
|
261 data_size, sample_count);
|
yading@11
|
262 return AVERROR_INVALIDDATA;
|
yading@11
|
263 }
|
yading@11
|
264 avio_skip(pb, size - 24); /* skip rest of ds64 chunk */
|
yading@11
|
265
|
yading@11
|
266 }
|
yading@11
|
267
|
yading@11
|
268 for (;;) {
|
yading@11
|
269 AVStream *vst;
|
yading@11
|
270 size = next_tag(pb, &tag);
|
yading@11
|
271 next_tag_ofs = avio_tell(pb) + size;
|
yading@11
|
272
|
yading@11
|
273 if (url_feof(pb))
|
yading@11
|
274 break;
|
yading@11
|
275
|
yading@11
|
276 switch (tag) {
|
yading@11
|
277 case MKTAG('f', 'm', 't', ' '):
|
yading@11
|
278 /* only parse the first 'fmt ' tag found */
|
yading@11
|
279 if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) {
|
yading@11
|
280 return ret;
|
yading@11
|
281 } else if (got_fmt)
|
yading@11
|
282 av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");
|
yading@11
|
283
|
yading@11
|
284 got_fmt = 1;
|
yading@11
|
285 break;
|
yading@11
|
286 case MKTAG('d', 'a', 't', 'a'):
|
yading@11
|
287 if (!got_fmt) {
|
yading@11
|
288 av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n");
|
yading@11
|
289 return AVERROR_INVALIDDATA;
|
yading@11
|
290 }
|
yading@11
|
291
|
yading@11
|
292 if (rf64) {
|
yading@11
|
293 next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
|
yading@11
|
294 } else {
|
yading@11
|
295 data_size = size;
|
yading@11
|
296 next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
|
yading@11
|
297 }
|
yading@11
|
298
|
yading@11
|
299 data_ofs = avio_tell(pb);
|
yading@11
|
300
|
yading@11
|
301 /* don't look for footer metadata if we can't seek or if we don't
|
yading@11
|
302 * know where the data tag ends
|
yading@11
|
303 */
|
yading@11
|
304 if (!pb->seekable || (!rf64 && !size))
|
yading@11
|
305 goto break_loop;
|
yading@11
|
306 break;
|
yading@11
|
307 case MKTAG('f','a','c','t'):
|
yading@11
|
308 if (!sample_count)
|
yading@11
|
309 sample_count = avio_rl32(pb);
|
yading@11
|
310 break;
|
yading@11
|
311 case MKTAG('b','e','x','t'):
|
yading@11
|
312 if ((ret = wav_parse_bext_tag(s, size)) < 0)
|
yading@11
|
313 return ret;
|
yading@11
|
314 break;
|
yading@11
|
315 case MKTAG('S','M','V','0'):
|
yading@11
|
316 if (!got_fmt) {
|
yading@11
|
317 av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n");
|
yading@11
|
318 return AVERROR_INVALIDDATA;
|
yading@11
|
319 }
|
yading@11
|
320 // SMV file, a wav file with video appended.
|
yading@11
|
321 if (size != MKTAG('0','2','0','0')) {
|
yading@11
|
322 av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n");
|
yading@11
|
323 goto break_loop;
|
yading@11
|
324 }
|
yading@11
|
325 av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
|
yading@11
|
326 vst = avformat_new_stream(s, NULL);
|
yading@11
|
327 if (!vst)
|
yading@11
|
328 return AVERROR(ENOMEM);
|
yading@11
|
329 avio_r8(pb);
|
yading@11
|
330 vst->id = 1;
|
yading@11
|
331 vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
yading@11
|
332 vst->codec->codec_id = AV_CODEC_ID_MJPEG;
|
yading@11
|
333 vst->codec->width = avio_rl24(pb);
|
yading@11
|
334 vst->codec->height = avio_rl24(pb);
|
yading@11
|
335 size = avio_rl24(pb);
|
yading@11
|
336 wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
|
yading@11
|
337 avio_rl24(pb);
|
yading@11
|
338 wav->smv_block_size = avio_rl24(pb);
|
yading@11
|
339 avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb));
|
yading@11
|
340 vst->duration = avio_rl24(pb);
|
yading@11
|
341 avio_rl24(pb);
|
yading@11
|
342 avio_rl24(pb);
|
yading@11
|
343 wav->smv_frames_per_jpeg = avio_rl24(pb);
|
yading@11
|
344 goto break_loop;
|
yading@11
|
345 case MKTAG('L', 'I', 'S', 'T'):
|
yading@11
|
346 if (size < 4) {
|
yading@11
|
347 av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
|
yading@11
|
348 return AVERROR_INVALIDDATA;
|
yading@11
|
349 }
|
yading@11
|
350 switch (avio_rl32(pb)) {
|
yading@11
|
351 case MKTAG('I', 'N', 'F', 'O'):
|
yading@11
|
352 ff_read_riff_info(s, size - 4);
|
yading@11
|
353 }
|
yading@11
|
354 break;
|
yading@11
|
355 }
|
yading@11
|
356
|
yading@11
|
357 /* skip padding byte */
|
yading@11
|
358 next_tag_ofs += (next_tag_ofs < INT64_MAX && next_tag_ofs & 1);
|
yading@11
|
359
|
yading@11
|
360 /* seek to next tag unless we know that we'll run into EOF */
|
yading@11
|
361 if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
|
yading@11
|
362 avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
|
yading@11
|
363 break;
|
yading@11
|
364 }
|
yading@11
|
365 }
|
yading@11
|
366 break_loop:
|
yading@11
|
367 if (data_ofs < 0) {
|
yading@11
|
368 av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
|
yading@11
|
369 return AVERROR_INVALIDDATA;
|
yading@11
|
370 }
|
yading@11
|
371
|
yading@11
|
372 avio_seek(pb, data_ofs, SEEK_SET);
|
yading@11
|
373
|
yading@11
|
374 if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb))
|
yading@11
|
375 sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
|
yading@11
|
376 if (sample_count)
|
yading@11
|
377 st->duration = sample_count;
|
yading@11
|
378
|
yading@11
|
379 ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
|
yading@11
|
380 ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
|
yading@11
|
381
|
yading@11
|
382 return 0;
|
yading@11
|
383 }
|
yading@11
|
384
|
yading@11
|
385 /** Find chunk with w64 GUID by skipping over other chunks
|
yading@11
|
386 * @return the size of the found chunk
|
yading@11
|
387 */
|
yading@11
|
388 static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
|
yading@11
|
389 {
|
yading@11
|
390 uint8_t guid[16];
|
yading@11
|
391 int64_t size;
|
yading@11
|
392
|
yading@11
|
393 while (!url_feof(pb)) {
|
yading@11
|
394 avio_read(pb, guid, 16);
|
yading@11
|
395 size = avio_rl64(pb);
|
yading@11
|
396 if (size <= 24)
|
yading@11
|
397 return -1;
|
yading@11
|
398 if (!memcmp(guid, guid1, 16))
|
yading@11
|
399 return size;
|
yading@11
|
400 avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
|
yading@11
|
401 }
|
yading@11
|
402 return -1;
|
yading@11
|
403 }
|
yading@11
|
404
|
yading@11
|
405 #define MAX_SIZE 4096
|
yading@11
|
406
|
yading@11
|
407 static int wav_read_packet(AVFormatContext *s,
|
yading@11
|
408 AVPacket *pkt)
|
yading@11
|
409 {
|
yading@11
|
410 int ret, size;
|
yading@11
|
411 int64_t left;
|
yading@11
|
412 AVStream *st;
|
yading@11
|
413 WAVDemuxContext *wav = s->priv_data;
|
yading@11
|
414
|
yading@11
|
415 if (CONFIG_SPDIF_DEMUXER && wav->spdif == 0 &&
|
yading@11
|
416 s->streams[0]->codec->codec_tag == 1) {
|
yading@11
|
417 enum AVCodecID codec;
|
yading@11
|
418 ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer,
|
yading@11
|
419 &codec);
|
yading@11
|
420 if (ret > AVPROBE_SCORE_MAX / 2) {
|
yading@11
|
421 s->streams[0]->codec->codec_id = codec;
|
yading@11
|
422 wav->spdif = 1;
|
yading@11
|
423 } else {
|
yading@11
|
424 wav->spdif = -1;
|
yading@11
|
425 }
|
yading@11
|
426 }
|
yading@11
|
427 if (CONFIG_SPDIF_DEMUXER && wav->spdif == 1)
|
yading@11
|
428 return ff_spdif_read_packet(s, pkt);
|
yading@11
|
429
|
yading@11
|
430 if (wav->smv_data_ofs > 0) {
|
yading@11
|
431 int64_t audio_dts, video_dts;
|
yading@11
|
432 smv_retry:
|
yading@11
|
433 audio_dts = s->streams[0]->cur_dts;
|
yading@11
|
434 video_dts = s->streams[1]->cur_dts;
|
yading@11
|
435 if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
|
yading@11
|
436 audio_dts = av_rescale_q(audio_dts, s->streams[0]->time_base, AV_TIME_BASE_Q);
|
yading@11
|
437 video_dts = av_rescale_q(video_dts, s->streams[1]->time_base, AV_TIME_BASE_Q);
|
yading@11
|
438 wav->smv_last_stream = video_dts >= audio_dts;
|
yading@11
|
439 }
|
yading@11
|
440 wav->smv_last_stream = !wav->smv_last_stream;
|
yading@11
|
441 wav->smv_last_stream |= wav->audio_eof;
|
yading@11
|
442 wav->smv_last_stream &= !wav->smv_eof;
|
yading@11
|
443 if (wav->smv_last_stream) {
|
yading@11
|
444 uint64_t old_pos = avio_tell(s->pb);
|
yading@11
|
445 uint64_t new_pos = wav->smv_data_ofs +
|
yading@11
|
446 wav->smv_block * wav->smv_block_size;
|
yading@11
|
447 if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) {
|
yading@11
|
448 ret = AVERROR_EOF;
|
yading@11
|
449 goto smv_out;
|
yading@11
|
450 }
|
yading@11
|
451 size = avio_rl24(s->pb);
|
yading@11
|
452 ret = av_get_packet(s->pb, pkt, size);
|
yading@11
|
453 if (ret < 0)
|
yading@11
|
454 goto smv_out;
|
yading@11
|
455 pkt->pos -= 3;
|
yading@11
|
456 pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg;
|
yading@11
|
457 wav->smv_block++;
|
yading@11
|
458 pkt->stream_index = 1;
|
yading@11
|
459 smv_out:
|
yading@11
|
460 avio_seek(s->pb, old_pos, SEEK_SET);
|
yading@11
|
461 if (ret == AVERROR_EOF) {
|
yading@11
|
462 wav->smv_eof = 1;
|
yading@11
|
463 goto smv_retry;
|
yading@11
|
464 }
|
yading@11
|
465 return ret;
|
yading@11
|
466 }
|
yading@11
|
467 }
|
yading@11
|
468
|
yading@11
|
469 st = s->streams[0];
|
yading@11
|
470
|
yading@11
|
471 left = wav->data_end - avio_tell(s->pb);
|
yading@11
|
472 if (wav->ignore_length)
|
yading@11
|
473 left= INT_MAX;
|
yading@11
|
474 if (left <= 0){
|
yading@11
|
475 if (CONFIG_W64_DEMUXER && wav->w64)
|
yading@11
|
476 left = find_guid(s->pb, ff_w64_guid_data) - 24;
|
yading@11
|
477 else
|
yading@11
|
478 left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
|
yading@11
|
479 if (left < 0) {
|
yading@11
|
480 wav->audio_eof = 1;
|
yading@11
|
481 if (wav->smv_data_ofs > 0 && !wav->smv_eof)
|
yading@11
|
482 goto smv_retry;
|
yading@11
|
483 return AVERROR_EOF;
|
yading@11
|
484 }
|
yading@11
|
485 wav->data_end= avio_tell(s->pb) + left;
|
yading@11
|
486 }
|
yading@11
|
487
|
yading@11
|
488 size = MAX_SIZE;
|
yading@11
|
489 if (st->codec->block_align > 1) {
|
yading@11
|
490 if (size < st->codec->block_align)
|
yading@11
|
491 size = st->codec->block_align;
|
yading@11
|
492 size = (size / st->codec->block_align) * st->codec->block_align;
|
yading@11
|
493 }
|
yading@11
|
494 size = FFMIN(size, left);
|
yading@11
|
495 ret = av_get_packet(s->pb, pkt, size);
|
yading@11
|
496 if (ret < 0)
|
yading@11
|
497 return ret;
|
yading@11
|
498 pkt->stream_index = 0;
|
yading@11
|
499
|
yading@11
|
500 return ret;
|
yading@11
|
501 }
|
yading@11
|
502
|
yading@11
|
503 static int wav_read_seek(AVFormatContext *s,
|
yading@11
|
504 int stream_index, int64_t timestamp, int flags)
|
yading@11
|
505 {
|
yading@11
|
506 WAVDemuxContext *wav = s->priv_data;
|
yading@11
|
507 AVStream *st;
|
yading@11
|
508 wav->smv_eof = 0;
|
yading@11
|
509 wav->audio_eof = 0;
|
yading@11
|
510 if (wav->smv_data_ofs > 0) {
|
yading@11
|
511 int64_t smv_timestamp = timestamp;
|
yading@11
|
512 if (stream_index == 0)
|
yading@11
|
513 smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
|
yading@11
|
514 else
|
yading@11
|
515 timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base);
|
yading@11
|
516 wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
|
yading@11
|
517 }
|
yading@11
|
518
|
yading@11
|
519 st = s->streams[0];
|
yading@11
|
520 switch (st->codec->codec_id) {
|
yading@11
|
521 case AV_CODEC_ID_MP2:
|
yading@11
|
522 case AV_CODEC_ID_MP3:
|
yading@11
|
523 case AV_CODEC_ID_AC3:
|
yading@11
|
524 case AV_CODEC_ID_DTS:
|
yading@11
|
525 /* use generic seeking with dynamically generated indexes */
|
yading@11
|
526 return -1;
|
yading@11
|
527 default:
|
yading@11
|
528 break;
|
yading@11
|
529 }
|
yading@11
|
530 return ff_pcm_read_seek(s, stream_index, timestamp, flags);
|
yading@11
|
531 }
|
yading@11
|
532
|
yading@11
|
533 #define OFFSET(x) offsetof(WAVDemuxContext, x)
|
yading@11
|
534 #define DEC AV_OPT_FLAG_DECODING_PARAM
|
yading@11
|
535 static const AVOption demux_options[] = {
|
yading@11
|
536 { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC },
|
yading@11
|
537 { NULL },
|
yading@11
|
538 };
|
yading@11
|
539
|
yading@11
|
540 static const AVClass wav_demuxer_class = {
|
yading@11
|
541 .class_name = "WAV demuxer",
|
yading@11
|
542 .item_name = av_default_item_name,
|
yading@11
|
543 .option = demux_options,
|
yading@11
|
544 .version = LIBAVUTIL_VERSION_INT,
|
yading@11
|
545 };
|
yading@11
|
546 AVInputFormat ff_wav_demuxer = {
|
yading@11
|
547 .name = "wav",
|
yading@11
|
548 .long_name = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
|
yading@11
|
549 .priv_data_size = sizeof(WAVDemuxContext),
|
yading@11
|
550 .read_probe = wav_probe,
|
yading@11
|
551 .read_header = wav_read_header,
|
yading@11
|
552 .read_packet = wav_read_packet,
|
yading@11
|
553 .read_seek = wav_read_seek,
|
yading@11
|
554 .flags = AVFMT_GENERIC_INDEX,
|
yading@11
|
555 .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
|
yading@11
|
556 .priv_class = &wav_demuxer_class,
|
yading@11
|
557 };
|
yading@11
|
558 #endif /* CONFIG_WAV_DEMUXER */
|
yading@11
|
559
|
yading@11
|
560
|
yading@11
|
561 #if CONFIG_W64_DEMUXER
|
yading@11
|
562 static int w64_probe(AVProbeData *p)
|
yading@11
|
563 {
|
yading@11
|
564 if (p->buf_size <= 40)
|
yading@11
|
565 return 0;
|
yading@11
|
566 if (!memcmp(p->buf, ff_w64_guid_riff, 16) &&
|
yading@11
|
567 !memcmp(p->buf + 24, ff_w64_guid_wave, 16))
|
yading@11
|
568 return AVPROBE_SCORE_MAX;
|
yading@11
|
569 else
|
yading@11
|
570 return 0;
|
yading@11
|
571 }
|
yading@11
|
572
|
yading@11
|
573 static int w64_read_header(AVFormatContext *s)
|
yading@11
|
574 {
|
yading@11
|
575 int64_t size, data_ofs = 0;
|
yading@11
|
576 AVIOContext *pb = s->pb;
|
yading@11
|
577 WAVDemuxContext *wav = s->priv_data;
|
yading@11
|
578 AVStream *st;
|
yading@11
|
579 uint8_t guid[16];
|
yading@11
|
580 int ret;
|
yading@11
|
581
|
yading@11
|
582 avio_read(pb, guid, 16);
|
yading@11
|
583 if (memcmp(guid, ff_w64_guid_riff, 16))
|
yading@11
|
584 return -1;
|
yading@11
|
585
|
yading@11
|
586 if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */
|
yading@11
|
587 return -1;
|
yading@11
|
588
|
yading@11
|
589 avio_read(pb, guid, 16);
|
yading@11
|
590 if (memcmp(guid, ff_w64_guid_wave, 16)) {
|
yading@11
|
591 av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
|
yading@11
|
592 return -1;
|
yading@11
|
593 }
|
yading@11
|
594
|
yading@11
|
595 wav->w64 = 1;
|
yading@11
|
596
|
yading@11
|
597 st = avformat_new_stream(s, NULL);
|
yading@11
|
598 if (!st)
|
yading@11
|
599 return AVERROR(ENOMEM);
|
yading@11
|
600
|
yading@11
|
601 while (!url_feof(pb)) {
|
yading@11
|
602 if (avio_read(pb, guid, 16) != 16)
|
yading@11
|
603 break;
|
yading@11
|
604 size = avio_rl64(pb);
|
yading@11
|
605 if (size <= 24 || INT64_MAX - size < avio_tell(pb))
|
yading@11
|
606 return AVERROR_INVALIDDATA;
|
yading@11
|
607
|
yading@11
|
608 if (!memcmp(guid, ff_w64_guid_fmt, 16)) {
|
yading@11
|
609 /* subtract chunk header size - normal wav file doesn't count it */
|
yading@11
|
610 ret = ff_get_wav_header(pb, st->codec, size - 24);
|
yading@11
|
611 if (ret < 0)
|
yading@11
|
612 return ret;
|
yading@11
|
613 avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
|
yading@11
|
614
|
yading@11
|
615 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
|
yading@11
|
616 } else if (!memcmp(guid, ff_w64_guid_fact, 16)) {
|
yading@11
|
617 int64_t samples;
|
yading@11
|
618
|
yading@11
|
619 samples = avio_rl64(pb);
|
yading@11
|
620 if (samples > 0)
|
yading@11
|
621 st->duration = samples;
|
yading@11
|
622 } else if (!memcmp(guid, ff_w64_guid_data, 16)) {
|
yading@11
|
623 wav->data_end = avio_tell(pb) + size - 24;
|
yading@11
|
624
|
yading@11
|
625 data_ofs = avio_tell(pb);
|
yading@11
|
626 if (!pb->seekable)
|
yading@11
|
627 break;
|
yading@11
|
628
|
yading@11
|
629 avio_skip(pb, size - 24);
|
yading@11
|
630 } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) {
|
yading@11
|
631 int64_t start, end, cur;
|
yading@11
|
632 uint32_t count, chunk_size, i;
|
yading@11
|
633
|
yading@11
|
634 start = avio_tell(pb);
|
yading@11
|
635 end = start + size;
|
yading@11
|
636 count = avio_rl32(pb);
|
yading@11
|
637
|
yading@11
|
638 for (i = 0; i < count; i++) {
|
yading@11
|
639 char chunk_key[5], *value;
|
yading@11
|
640
|
yading@11
|
641 if (url_feof(pb) || (cur = avio_tell(pb)) < 0 || cur > end - 8 /* = tag + size */)
|
yading@11
|
642 break;
|
yading@11
|
643
|
yading@11
|
644 chunk_key[4] = 0;
|
yading@11
|
645 avio_read(pb, chunk_key, 4);
|
yading@11
|
646 chunk_size = avio_rl32(pb);
|
yading@11
|
647
|
yading@11
|
648 value = av_mallocz(chunk_size + 1);
|
yading@11
|
649 if (!value)
|
yading@11
|
650 return AVERROR(ENOMEM);
|
yading@11
|
651
|
yading@11
|
652 ret = avio_get_str16le(pb, chunk_size, value, chunk_size);
|
yading@11
|
653 avio_skip(pb, chunk_size - ret);
|
yading@11
|
654
|
yading@11
|
655 av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL);
|
yading@11
|
656 }
|
yading@11
|
657
|
yading@11
|
658 avio_skip(pb, end - avio_tell(pb));
|
yading@11
|
659 } else {
|
yading@11
|
660 av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid));
|
yading@11
|
661 avio_skip(pb, size - 24);
|
yading@11
|
662 }
|
yading@11
|
663 }
|
yading@11
|
664
|
yading@11
|
665 if (!data_ofs)
|
yading@11
|
666 return AVERROR_EOF;
|
yading@11
|
667
|
yading@11
|
668 ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
|
yading@11
|
669 ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
|
yading@11
|
670
|
yading@11
|
671 handle_stream_probing(st);
|
yading@11
|
672 st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
|
yading@11
|
673
|
yading@11
|
674 avio_seek(pb, data_ofs, SEEK_SET);
|
yading@11
|
675
|
yading@11
|
676 return 0;
|
yading@11
|
677 }
|
yading@11
|
678
|
yading@11
|
679 AVInputFormat ff_w64_demuxer = {
|
yading@11
|
680 .name = "w64",
|
yading@11
|
681 .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"),
|
yading@11
|
682 .priv_data_size = sizeof(WAVDemuxContext),
|
yading@11
|
683 .read_probe = w64_probe,
|
yading@11
|
684 .read_header = w64_read_header,
|
yading@11
|
685 .read_packet = wav_read_packet,
|
yading@11
|
686 .read_seek = wav_read_seek,
|
yading@11
|
687 .flags = AVFMT_GENERIC_INDEX,
|
yading@11
|
688 .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
|
yading@11
|
689 };
|
yading@11
|
690 #endif /* CONFIG_W64_DEMUXER */
|