/src/ffmpeg/libavformat/wavdec.c
Line | Count | Source |
1 | | /* |
2 | | * WAV demuxer |
3 | | * Copyright (c) 2001, 2002 Fabrice Bellard |
4 | | * |
5 | | * Sony Wave64 demuxer |
6 | | * RF64 demuxer |
7 | | * Copyright (c) 2009 Daniel Verkamp |
8 | | * |
9 | | * BW64 demuxer |
10 | | * |
11 | | * This file is part of FFmpeg. |
12 | | * |
13 | | * FFmpeg is free software; you can redistribute it and/or |
14 | | * modify it under the terms of the GNU Lesser General Public |
15 | | * License as published by the Free Software Foundation; either |
16 | | * version 2.1 of the License, or (at your option) any later version. |
17 | | * |
18 | | * FFmpeg is distributed in the hope that it will be useful, |
19 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
21 | | * Lesser General Public License for more details. |
22 | | * |
23 | | * You should have received a copy of the GNU Lesser General Public |
24 | | * License along with FFmpeg; if not, write to the Free Software |
25 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
26 | | */ |
27 | | |
28 | | #include <stdint.h> |
29 | | |
30 | | #include "config_components.h" |
31 | | #include "libavutil/avassert.h" |
32 | | #include "libavutil/dict.h" |
33 | | #include "libavutil/intreadwrite.h" |
34 | | #include "libavutil/log.h" |
35 | | #include "libavutil/mathematics.h" |
36 | | #include "libavutil/mem.h" |
37 | | #include "libavutil/opt.h" |
38 | | #include "libavcodec/internal.h" |
39 | | #include "avformat.h" |
40 | | #include "avio.h" |
41 | | #include "avio_internal.h" |
42 | | #include "demux.h" |
43 | | #include "id3v2.h" |
44 | | #include "internal.h" |
45 | | #include "metadata.h" |
46 | | #include "pcm.h" |
47 | | #include "riff.h" |
48 | | #include "w64.h" |
49 | | #include "spdif.h" |
50 | | |
51 | | typedef struct WAVDemuxContext { |
52 | | const AVClass *class; |
53 | | int64_t data_end; |
54 | | int w64; |
55 | | AVStream *vst; |
56 | | int64_t smv_data_ofs; |
57 | | int smv_block_size; |
58 | | int smv_frames_per_jpeg; |
59 | | int smv_block; |
60 | | int smv_last_stream; |
61 | | int smv_eof; |
62 | | int audio_eof; |
63 | | int ignore_length; |
64 | | int max_size; |
65 | | int spdif; |
66 | | int smv_given_first; |
67 | | int unaligned; // e.g. if an odd number of bytes ID3 tag was prepended |
68 | | int rifx; // RIFX: integer byte order for parameters is big endian |
69 | | } WAVDemuxContext; |
70 | | |
71 | | #define OFFSET(x) offsetof(WAVDemuxContext, x) |
72 | | #define DEC AV_OPT_FLAG_DECODING_PARAM |
73 | | static const AVOption demux_options[] = { |
74 | | #define W64_DEMUXER_OPTIONS_OFFSET (1 * CONFIG_WAV_DEMUXER) |
75 | | #if CONFIG_WAV_DEMUXER |
76 | | { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, |
77 | | #endif |
78 | | { "max_size", "max size of single packet", OFFSET(max_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1 << 22, DEC }, |
79 | | { NULL }, |
80 | | }; |
81 | | |
82 | | static void set_max_size(AVStream *st, WAVDemuxContext *wav) |
83 | 37.7k | { |
84 | 37.7k | if (wav->max_size <= 0) { |
85 | 37.7k | int max_size = ff_pcm_default_packet_size(st->codecpar); |
86 | 37.7k | wav->max_size = max_size < 0 ? 4096 : max_size; |
87 | 37.7k | } |
88 | 37.7k | } |
89 | | |
90 | | static void set_spdif(AVFormatContext *s, WAVDemuxContext *wav) |
91 | 37.7k | { |
92 | 37.7k | if (CONFIG_SPDIF_DEMUXER && s->streams[0]->codecpar->codec_tag == 1) { |
93 | 28.4k | enum AVCodecID codec; |
94 | 28.4k | int len = 1<<16; |
95 | 28.4k | int ret = ffio_ensure_seekback(s->pb, len); |
96 | | |
97 | 28.4k | if (ret >= 0) { |
98 | 28.4k | uint8_t *buf = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE); |
99 | 28.4k | if (!buf) { |
100 | 0 | ret = AVERROR(ENOMEM); |
101 | 28.4k | } else { |
102 | 28.4k | int64_t pos = avio_tell(s->pb); |
103 | 28.4k | len = ret = avio_read(s->pb, buf, len); |
104 | 28.4k | if (len >= 0) { |
105 | 28.1k | ret = ff_spdif_probe(buf, len, &codec); |
106 | 28.1k | if (ret > AVPROBE_SCORE_EXTENSION) { |
107 | 675 | s->streams[0]->codecpar->codec_id = codec; |
108 | 675 | wav->spdif = 1; |
109 | 675 | } |
110 | 28.1k | } |
111 | 28.4k | avio_seek(s->pb, pos, SEEK_SET); |
112 | 28.4k | av_free(buf); |
113 | 28.4k | } |
114 | 28.4k | } |
115 | | |
116 | 28.4k | if (ret < 0) |
117 | 282 | av_log(s, AV_LOG_WARNING, "Cannot check for SPDIF\n"); |
118 | 28.4k | } |
119 | 37.7k | } |
120 | | |
121 | | #if CONFIG_WAV_DEMUXER |
122 | | |
123 | | static int64_t next_tag(AVIOContext *pb, uint32_t *tag, int big_endian) |
124 | 707k | { |
125 | 707k | *tag = avio_rl32(pb); |
126 | 707k | if (!big_endian) { |
127 | 705k | return avio_rl32(pb); |
128 | 705k | } else { |
129 | 1.99k | return avio_rb32(pb); |
130 | 1.99k | } |
131 | 707k | } |
132 | | |
133 | | /* RIFF chunks are always at even offsets relative to where they start. */ |
134 | | static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset) |
135 | 493k | { |
136 | 493k | offset += offset < INT64_MAX && offset + wav->unaligned & 1; |
137 | | |
138 | 493k | return avio_seek(s, offset, SEEK_SET); |
139 | 493k | } |
140 | | |
141 | | /* return the size of the found tag */ |
142 | | static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1) |
143 | 3.65k | { |
144 | 3.65k | unsigned int tag; |
145 | 3.65k | int64_t size; |
146 | | |
147 | 3.65k | if (avio_tell(pb) + wav->unaligned & 1) |
148 | 408 | avio_skip(pb, 1); |
149 | | |
150 | 196k | for (;;) { |
151 | 196k | if (avio_feof(pb)) |
152 | 1.57k | return AVERROR_EOF; |
153 | 194k | size = next_tag(pb, &tag, wav->rifx); |
154 | 194k | if (tag == tag1) |
155 | 2.08k | break; |
156 | 192k | avio_skip(pb, size + (size & 1)); |
157 | 192k | } |
158 | 2.08k | return size; |
159 | 3.65k | } |
160 | | |
161 | | static int wav_probe(const AVProbeData *p) |
162 | 963k | { |
163 | | /* check file header */ |
164 | 963k | if (p->buf_size <= 32) |
165 | 200k | return 0; |
166 | 762k | if (!memcmp(p->buf + 8, "WAVE", 4)) { |
167 | 6.96k | if (!memcmp(p->buf, "RIFF", 4) || !memcmp(p->buf, "RIFX", 4)) |
168 | | /* Since the ACT demuxer has a standard WAV header at the top of |
169 | | * its own, the returned score is decreased to avoid a probe |
170 | | * conflict between ACT and WAV. */ |
171 | 3.32k | return AVPROBE_SCORE_MAX - 1; |
172 | 3.63k | else if ((!memcmp(p->buf, "RF64", 4) || |
173 | 3.37k | !memcmp(p->buf, "BW64", 4)) && |
174 | 631 | !memcmp(p->buf + 12, "ds64", 4)) |
175 | 215 | return AVPROBE_SCORE_MAX; |
176 | 6.96k | } |
177 | 759k | return 0; |
178 | 762k | } |
179 | | |
180 | | static void handle_stream_probing(AVStream *st) |
181 | 37.9k | { |
182 | 37.9k | if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE) { |
183 | 28.1k | FFStream *const sti = ffstream(st); |
184 | 28.1k | sti->request_probe = AVPROBE_SCORE_EXTENSION + 1; |
185 | 28.1k | sti->probe_packets = FFMIN(sti->probe_packets, 32); |
186 | 28.1k | } |
187 | 37.9k | } |
188 | | |
189 | | static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream *st) |
190 | 19.1k | { |
191 | 19.1k | AVIOContext *pb = s->pb; |
192 | 19.1k | WAVDemuxContext *wav = s->priv_data; |
193 | 19.1k | int ret; |
194 | | |
195 | | /* parse fmt header */ |
196 | 19.1k | ret = ff_get_wav_header(s, pb, st->codecpar, size, wav->rifx); |
197 | 19.1k | if (ret < 0) |
198 | 31 | return ret; |
199 | 19.1k | handle_stream_probing(st); |
200 | | |
201 | 19.1k | ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW; |
202 | | |
203 | 19.1k | avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); |
204 | | |
205 | 19.1k | return 0; |
206 | 19.1k | } |
207 | | |
208 | | static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream *st) |
209 | 38 | { |
210 | 38 | AVIOContext *pb = s->pb; |
211 | 38 | int version, num_streams, i, channels = 0, ret; |
212 | | |
213 | 38 | if (size < 36) |
214 | 1 | return AVERROR_INVALIDDATA; |
215 | | |
216 | 37 | st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; |
217 | 37 | st->codecpar->codec_id = AV_CODEC_ID_XMA2; |
218 | 37 | ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW; |
219 | | |
220 | 37 | version = avio_r8(pb); |
221 | 37 | if (version != 3 && version != 4) |
222 | 1 | return AVERROR_INVALIDDATA; |
223 | 36 | num_streams = avio_r8(pb); |
224 | 36 | if (size != (32 + ((version==3)?0:8) + 4*num_streams)) |
225 | 1 | return AVERROR_INVALIDDATA; |
226 | 35 | avio_skip(pb, 10); |
227 | 35 | st->codecpar->sample_rate = avio_rb32(pb); |
228 | 35 | if (version == 4) |
229 | 1 | avio_skip(pb, 8); |
230 | 35 | avio_skip(pb, 4); |
231 | 35 | st->duration = avio_rb32(pb); |
232 | 35 | avio_skip(pb, 8); |
233 | | |
234 | 331 | for (i = 0; i < num_streams; i++) { |
235 | 296 | channels += avio_r8(pb); |
236 | 296 | avio_skip(pb, 3); |
237 | 296 | } |
238 | 35 | av_channel_layout_uninit(&st->codecpar->ch_layout); |
239 | 35 | st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; |
240 | 35 | st->codecpar->ch_layout.nb_channels = channels; |
241 | | |
242 | 35 | if (st->codecpar->ch_layout.nb_channels <= 0 || st->codecpar->sample_rate <= 0) |
243 | 4 | return AVERROR_INVALIDDATA; |
244 | | |
245 | 31 | avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); |
246 | | |
247 | 31 | avio_seek(pb, -size, SEEK_CUR); |
248 | 31 | if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0) |
249 | 4 | return ret; |
250 | | |
251 | 27 | return 0; |
252 | 31 | } |
253 | | |
254 | | static inline int wav_parse_bext_string(AVFormatContext *s, const char *key, |
255 | | int length) |
256 | 16.6k | { |
257 | 16.6k | char temp[257]; |
258 | 16.6k | int ret; |
259 | | |
260 | 16.6k | av_assert0(length < sizeof(temp)); |
261 | 16.6k | if ((ret = ffio_read_size(s->pb, temp, length)) < 0) |
262 | 52 | return ret; |
263 | | |
264 | 16.5k | temp[length] = 0; |
265 | | |
266 | 16.5k | if (strlen(temp)) |
267 | 8.58k | return av_dict_set(&s->metadata, key, temp, 0); |
268 | | |
269 | 7.97k | return 0; |
270 | 16.5k | } |
271 | | |
272 | | static int wav_parse_bext_tag(AVFormatContext *s, int64_t size) |
273 | 3.33k | { |
274 | 3.33k | char temp[131], *coding_history; |
275 | 3.33k | int ret, x; |
276 | 3.33k | uint64_t time_reference; |
277 | 3.33k | int64_t umid_parts[8], umid_mask = 0; |
278 | | |
279 | 3.33k | if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 || |
280 | 3.32k | (ret = wav_parse_bext_string(s, "originator", 32)) < 0 || |
281 | 3.32k | (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 || |
282 | 3.31k | (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 || |
283 | 3.30k | (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0) |
284 | 52 | return ret; |
285 | | |
286 | 3.28k | time_reference = avio_rl64(s->pb); |
287 | 3.28k | snprintf(temp, sizeof(temp), "%"PRIu64, time_reference); |
288 | 3.28k | if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0) |
289 | 0 | return ret; |
290 | | |
291 | | /* check if version is >= 1, in which case an UMID may be present */ |
292 | 3.28k | if (avio_rl16(s->pb) >= 1) { |
293 | 16.6k | for (x = 0; x < 8; x++) |
294 | 14.8k | umid_mask |= umid_parts[x] = avio_rb64(s->pb); |
295 | | |
296 | 1.85k | if (umid_mask) { |
297 | | /* the string formatting below is per SMPTE 330M-2004 Annex C */ |
298 | 1.83k | if (umid_parts[4] == 0 && umid_parts[5] == 0 && |
299 | 371 | umid_parts[6] == 0 && umid_parts[7] == 0) { |
300 | | /* basic UMID */ |
301 | 154 | snprintf(temp, sizeof(temp), |
302 | 154 | "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64, |
303 | 154 | umid_parts[0], umid_parts[1], |
304 | 154 | umid_parts[2], umid_parts[3]); |
305 | 1.68k | } else { |
306 | | /* extended UMID */ |
307 | 1.68k | snprintf(temp, sizeof(temp), |
308 | 1.68k | "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64 |
309 | 1.68k | "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64, |
310 | 1.68k | umid_parts[0], umid_parts[1], |
311 | 1.68k | umid_parts[2], umid_parts[3], |
312 | 1.68k | umid_parts[4], umid_parts[5], |
313 | 1.68k | umid_parts[6], umid_parts[7]); |
314 | 1.68k | } |
315 | | |
316 | 1.83k | if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0) |
317 | 0 | return ret; |
318 | 1.83k | } |
319 | | |
320 | 1.85k | avio_skip(s->pb, 190); |
321 | 1.85k | } else |
322 | 1.42k | avio_skip(s->pb, 254); |
323 | | |
324 | 3.28k | if (size > 602) { |
325 | | /* CodingHistory present */ |
326 | 90 | int64_t coding_history_size = size - 602; |
327 | | |
328 | | /* Professional BEXT coding history rarely exceeds a few KB. |
329 | | * Cap to 1MB to prevent excessive allocation from crafted files |
330 | | * while remaining well within ffio_read_size's int range. */ |
331 | 90 | if (coding_history_size > 1024 * 1024) { |
332 | 64 | av_log(s, AV_LOG_ERROR, "BEXT coding history too large (%"PRId64")\n", coding_history_size); |
333 | 64 | return AVERROR_INVALIDDATA; |
334 | 64 | } |
335 | | |
336 | 26 | if (!(coding_history = av_malloc(coding_history_size + 1))) |
337 | 0 | return AVERROR(ENOMEM); |
338 | | |
339 | 26 | if ((ret = ffio_read_size(s->pb, coding_history, coding_history_size)) < 0) { |
340 | 13 | av_free(coding_history); |
341 | 13 | return ret; |
342 | 13 | } |
343 | | |
344 | 13 | coding_history[coding_history_size] = 0; |
345 | 13 | if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history, |
346 | 13 | AV_DICT_DONT_STRDUP_VAL)) < 0) |
347 | 0 | return ret; |
348 | 13 | } |
349 | | |
350 | 3.20k | return 0; |
351 | 3.28k | } |
352 | | |
353 | | static const AVMetadataConv wav_metadata_conv[] = { |
354 | | { "description", "comment" }, |
355 | | { "originator", "encoded_by" }, |
356 | | { "origination_date", "date" }, |
357 | | { "origination_time", "creation_time" }, |
358 | | { 0 }, |
359 | | }; |
360 | | |
361 | | /* wav input */ |
362 | | static int wav_read_header(AVFormatContext *s) |
363 | 20.8k | { |
364 | 20.8k | int64_t size, av_uninit(data_size); |
365 | 20.8k | int64_t sample_count = 0; |
366 | 20.8k | int rf64 = 0, bw64 = 0; |
367 | 20.8k | uint32_t tag; |
368 | 20.8k | AVIOContext *pb = s->pb; |
369 | 20.8k | AVStream *st = NULL; |
370 | 20.8k | WAVDemuxContext *wav = s->priv_data; |
371 | 20.8k | int ret, got_fmt = 0, got_xma2 = 0; |
372 | 20.8k | int64_t next_tag_ofs, data_ofs = -1; |
373 | 20.8k | int64_t filesize; |
374 | | |
375 | 20.8k | wav->unaligned = avio_tell(s->pb) & 1; |
376 | | |
377 | 20.8k | wav->smv_data_ofs = -1; |
378 | | |
379 | 20.8k | filesize = avio_size(pb); |
380 | | /* read chunk ID */ |
381 | 20.8k | tag = avio_rl32(pb); |
382 | 20.8k | switch (tag) { |
383 | 19.6k | case MKTAG('R', 'I', 'F', 'F'): |
384 | 19.6k | break; |
385 | 281 | case MKTAG('R', 'I', 'F', 'X'): |
386 | 281 | wav->rifx = 1; |
387 | 281 | break; |
388 | 127 | case MKTAG('R', 'F', '6', '4'): |
389 | 127 | rf64 = 1; |
390 | 127 | break; |
391 | 198 | case MKTAG('B', 'W', '6', '4'): |
392 | 198 | bw64 = 1; |
393 | 198 | break; |
394 | 657 | default: |
395 | 657 | av_log(s, AV_LOG_ERROR, "invalid start code %s in RIFF header\n", |
396 | 657 | av_fourcc2str(tag)); |
397 | 657 | return AVERROR_INVALIDDATA; |
398 | 20.8k | } |
399 | | |
400 | | /* read chunk size */ |
401 | 20.2k | avio_rl32(pb); |
402 | | |
403 | | /* read format */ |
404 | 20.2k | if (avio_rl32(pb) != MKTAG('W', 'A', 'V', 'E')) { |
405 | 1 | av_log(s, AV_LOG_ERROR, "invalid format in RIFF header\n"); |
406 | 1 | return AVERROR_INVALIDDATA; |
407 | 1 | } |
408 | | |
409 | 20.2k | if (rf64 || bw64) { |
410 | 325 | if (avio_rl32(pb) != MKTAG('d', 's', '6', '4')) |
411 | 0 | return AVERROR_INVALIDDATA; |
412 | 325 | size = avio_rl32(pb); |
413 | 325 | if (size < 24) |
414 | 2 | return AVERROR_INVALIDDATA; |
415 | 323 | avio_rl64(pb); /* RIFF size */ |
416 | | |
417 | 323 | data_size = avio_rl64(pb); |
418 | 323 | sample_count = avio_rl64(pb); |
419 | | |
420 | 323 | if (data_size < 0 || sample_count < 0) { |
421 | 59 | av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in " |
422 | 59 | "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n", |
423 | 59 | data_size, sample_count); |
424 | 59 | return AVERROR_INVALIDDATA; |
425 | 59 | } |
426 | 264 | avio_skip(pb, size - 24); /* skip rest of ds64 chunk */ |
427 | | |
428 | 264 | } |
429 | | |
430 | | /* Create the audio stream now so that its index is always zero */ |
431 | 20.1k | st = avformat_new_stream(s, NULL); |
432 | 20.1k | if (!st) |
433 | 0 | return AVERROR(ENOMEM); |
434 | | |
435 | 512k | for (;;) { |
436 | 512k | AVStream *vst; |
437 | 512k | size = next_tag(pb, &tag, wav->rifx); |
438 | 512k | next_tag_ofs = avio_tell(pb) + size + (size & 1); |
439 | | |
440 | 512k | if (avio_feof(pb)) |
441 | 226 | break; |
442 | | |
443 | 512k | switch (tag) { |
444 | 21.3k | case MKTAG('f', 'm', 't', ' '): |
445 | | /* only parse the first 'fmt ' tag found */ |
446 | 21.3k | if (!got_xma2 && !got_fmt && (ret = wav_parse_fmt_tag(s, size, st)) < 0) { |
447 | 31 | return ret; |
448 | 21.3k | } else if (got_fmt) |
449 | 2.20k | av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n"); |
450 | | |
451 | 21.3k | got_fmt = 1; |
452 | 21.3k | break; |
453 | 120 | case MKTAG('X', 'M', 'A', '2'): |
454 | | /* only parse the first 'XMA2' tag found */ |
455 | 120 | if (!got_fmt && !got_xma2 && (ret = wav_parse_xma2_tag(s, size, st)) < 0) { |
456 | 11 | return ret; |
457 | 109 | } else if (got_xma2) |
458 | 66 | av_log(s, AV_LOG_WARNING, "found more than one 'XMA2' tag\n"); |
459 | | |
460 | 109 | got_xma2 = 1; |
461 | 109 | break; |
462 | 19.7k | case MKTAG('d', 'a', 't', 'a'): |
463 | 19.7k | if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) && !got_fmt && !got_xma2) { |
464 | 1 | av_log(s, AV_LOG_ERROR, |
465 | 1 | "found no 'fmt ' tag before the 'data' tag\n"); |
466 | 1 | return AVERROR_INVALIDDATA; |
467 | 1 | } |
468 | | |
469 | 19.7k | if (rf64 || bw64) { |
470 | 488 | wav->data_end = av_sat_add64(avio_tell(pb), data_size); |
471 | 488 | next_tag_ofs = av_sat_add64(wav->data_end, data_size & 1); |
472 | 19.2k | } else if (size > 0 && size != 0xFFFFFFFF) { |
473 | 17.9k | data_size = size; |
474 | 17.9k | wav->data_end = avio_tell(pb) + size; |
475 | 17.9k | next_tag_ofs = wav->data_end + (size & 1); |
476 | 17.9k | } else { |
477 | 1.37k | av_log(s, AV_LOG_WARNING, "Ignoring maximum wav data size, " |
478 | 1.37k | "file may be invalid\n"); |
479 | 1.37k | data_size = 0; |
480 | 1.37k | next_tag_ofs = wav->data_end = INT64_MAX; |
481 | 1.37k | } |
482 | | |
483 | 19.7k | data_ofs = avio_tell(pb); |
484 | | |
485 | | /* don't look for footer metadata if we can't seek or if we don't |
486 | | * know where the data tag ends |
487 | | */ |
488 | 19.7k | if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || (!(rf64 && !bw64) && !size)) |
489 | 17.0k | goto break_loop; |
490 | 2.74k | break; |
491 | 2.74k | case MKTAG('f', 'a', 'c', 't'): |
492 | 237 | if (!sample_count) |
493 | 89 | sample_count = (!wav->rifx ? avio_rl32(pb) : avio_rb32(pb)); |
494 | 237 | break; |
495 | 3.33k | case MKTAG('b', 'e', 'x', 't'): |
496 | 3.33k | if ((ret = wav_parse_bext_tag(s, size)) < 0) |
497 | 129 | return ret; |
498 | 3.20k | break; |
499 | 3.20k | case MKTAG('S','M','V','0'): |
500 | 562 | if (!got_fmt) { |
501 | 2 | av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n"); |
502 | 2 | return AVERROR_INVALIDDATA; |
503 | 2 | } |
504 | | // SMV file, a wav file with video appended. |
505 | 560 | if (size != MKTAG('0','2','0','0')) { |
506 | 8 | av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n"); |
507 | 8 | goto break_loop; |
508 | 8 | } |
509 | 552 | av_log(s, AV_LOG_DEBUG, "Found SMV data\n"); |
510 | 552 | wav->smv_given_first = 0; |
511 | 552 | vst = avformat_new_stream(s, NULL); |
512 | 552 | if (!vst) |
513 | 0 | return AVERROR(ENOMEM); |
514 | 552 | wav->vst = vst; |
515 | 552 | avio_r8(pb); |
516 | 552 | vst->id = 1; |
517 | 552 | vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; |
518 | 552 | vst->codecpar->codec_id = AV_CODEC_ID_SMVJPEG; |
519 | 552 | vst->codecpar->width = avio_rl24(pb); |
520 | 552 | vst->codecpar->height = avio_rl24(pb); |
521 | 552 | if ((ret = ff_alloc_extradata(vst->codecpar, 4)) < 0) { |
522 | 0 | av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n"); |
523 | 0 | return ret; |
524 | 0 | } |
525 | 552 | size = avio_rl24(pb); |
526 | 552 | wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3; |
527 | 552 | avio_rl24(pb); |
528 | 552 | wav->smv_block_size = avio_rl24(pb); |
529 | 552 | if (!wav->smv_block_size) |
530 | 6 | return AVERROR_INVALIDDATA; |
531 | 546 | avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb)); |
532 | 546 | vst->duration = avio_rl24(pb); |
533 | 546 | avio_rl24(pb); |
534 | 546 | avio_rl24(pb); |
535 | 546 | wav->smv_frames_per_jpeg = avio_rl24(pb); |
536 | 546 | if (wav->smv_frames_per_jpeg > 65536) { |
537 | 3 | av_log(s, AV_LOG_ERROR, "too many frames per jpeg\n"); |
538 | 3 | return AVERROR_INVALIDDATA; |
539 | 3 | } |
540 | 543 | AV_WL32(vst->codecpar->extradata, wav->smv_frames_per_jpeg); |
541 | 543 | goto break_loop; |
542 | 6.92k | case MKTAG('L', 'I', 'S', 'T'): |
543 | 6.98k | case MKTAG('l', 'i', 's', 't'): |
544 | 6.98k | if (size < 4) { |
545 | 4 | av_log(s, AV_LOG_ERROR, "too short LIST tag\n"); |
546 | 4 | return AVERROR_INVALIDDATA; |
547 | 4 | } |
548 | 6.98k | switch (avio_rl32(pb)) { |
549 | 6.01k | case MKTAG('I', 'N', 'F', 'O'): |
550 | 6.01k | ff_read_riff_info(s, size - 4); |
551 | 6.01k | break; |
552 | 0 | case MKTAG('a', 'd', 't', 'l'): |
553 | 0 | if (s->nb_chapters > 0) { |
554 | 0 | while (avio_tell(pb) < next_tag_ofs && |
555 | 0 | !avio_feof(pb)) { |
556 | 0 | char cue_label[512]; |
557 | 0 | unsigned id, sub_size; |
558 | |
|
559 | 0 | if (avio_rl32(pb) != MKTAG('l', 'a', 'b', 'l')) |
560 | 0 | break; |
561 | | |
562 | 0 | sub_size = avio_rl32(pb); |
563 | 0 | if (sub_size < 5) |
564 | 0 | break; |
565 | 0 | id = avio_rl32(pb); |
566 | 0 | avio_get_str(pb, sub_size - 4, cue_label, sizeof(cue_label)); |
567 | 0 | avio_skip(pb, avio_tell(pb) & 1); |
568 | |
|
569 | 0 | for (int i = 0; i < s->nb_chapters; i++) { |
570 | 0 | if (s->chapters[i]->id == id) { |
571 | 0 | av_dict_set(&s->chapters[i]->metadata, "title", cue_label, 0); |
572 | 0 | break; |
573 | 0 | } |
574 | 0 | } |
575 | 0 | } |
576 | 0 | } |
577 | 0 | break; |
578 | 6.98k | } |
579 | 6.98k | break; |
580 | 6.98k | case MKTAG('I', 'D', '3', ' '): |
581 | 5.65k | case MKTAG('i', 'd', '3', ' '): { |
582 | 5.65k | ID3v2ExtraMeta *id3v2_extra_meta; |
583 | 5.65k | ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0); |
584 | 5.65k | if (id3v2_extra_meta) { |
585 | 270 | ff_id3v2_parse_apic(s, id3v2_extra_meta); |
586 | 270 | ff_id3v2_parse_chapters(s, id3v2_extra_meta); |
587 | 270 | ff_id3v2_parse_priv(s, id3v2_extra_meta); |
588 | 270 | } |
589 | 5.65k | ff_id3v2_free_extra_meta(&id3v2_extra_meta); |
590 | 5.65k | } |
591 | 5.65k | break; |
592 | 625 | case MKTAG('c', 'u', 'e', ' '): |
593 | 625 | if (size >= 4 && got_fmt && st->codecpar->sample_rate > 0) { |
594 | 346 | AVRational tb = {1, st->codecpar->sample_rate}; |
595 | 346 | unsigned nb_cues = avio_rl32(pb); |
596 | | |
597 | 346 | if (size >= nb_cues * 24LL + 4LL) { |
598 | 11.4k | for (int i = 0; i < nb_cues; i++) { |
599 | 11.1k | unsigned offset, id = avio_rl32(pb); |
600 | | |
601 | 11.1k | if (avio_feof(pb)) |
602 | 87 | return AVERROR_INVALIDDATA; |
603 | | |
604 | 11.0k | avio_skip(pb, 16); |
605 | 11.0k | offset = avio_rl32(pb); |
606 | | |
607 | 11.0k | if (!avpriv_new_chapter(s, id, tb, offset, AV_NOPTS_VALUE, NULL)) |
608 | 0 | return AVERROR(ENOMEM); |
609 | 11.0k | } |
610 | 323 | } |
611 | 346 | } |
612 | 538 | break; |
613 | 512k | } |
614 | | |
615 | | /* seek to next tag unless we know that we'll run into EOF */ |
616 | 494k | if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) || |
617 | 493k | wav_seek_tag(wav, pb, next_tag_ofs) < 0) { |
618 | 2.09k | break; |
619 | 2.09k | } |
620 | 494k | } |
621 | | |
622 | 19.8k | break_loop: |
623 | 19.8k | if (!got_fmt && !got_xma2) { |
624 | 853 | av_log(s, AV_LOG_ERROR, "no 'fmt ' or 'XMA2' tag found\n"); |
625 | 853 | return AVERROR_INVALIDDATA; |
626 | 853 | } |
627 | | |
628 | 19.0k | if (data_ofs < 0) { |
629 | 141 | av_log(s, AV_LOG_ERROR, "no 'data' tag found\n"); |
630 | 141 | return AVERROR_INVALIDDATA; |
631 | 141 | } |
632 | | |
633 | 18.9k | avio_seek(pb, data_ofs, SEEK_SET); |
634 | | |
635 | 18.9k | if (data_size > (INT64_MAX>>3)) { |
636 | 30 | av_log(s, AV_LOG_WARNING, "Data size %"PRId64" is too large\n", data_size); |
637 | 30 | data_size = 0; |
638 | 30 | } |
639 | | |
640 | 18.9k | if ( st->codecpar->bit_rate > 0 && data_size > 0 |
641 | 16.7k | && st->codecpar->sample_rate > 0 |
642 | 16.7k | && sample_count > 0 && st->codecpar->ch_layout.nb_channels > 1 |
643 | 199 | && sample_count % st->codecpar->ch_layout.nb_channels == 0) { |
644 | 43 | if (fabs(8.0 * data_size * st->codecpar->ch_layout.nb_channels * st->codecpar->sample_rate / |
645 | 43 | sample_count /st->codecpar->bit_rate - 1.0) < 0.3) |
646 | 7 | sample_count /= st->codecpar->ch_layout.nb_channels; |
647 | 43 | } |
648 | | |
649 | 18.9k | if (data_size > 0 && sample_count && st->codecpar->ch_layout.nb_channels && |
650 | 255 | (data_size << 3) / sample_count / st->codecpar->ch_layout.nb_channels > st->codecpar->bits_per_coded_sample + 1) { |
651 | 44 | av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count); |
652 | 44 | sample_count = 0; |
653 | 44 | } |
654 | | |
655 | | /* G.729 hack (for Ticket4577) |
656 | | * FIXME: Come up with cleaner, more general solution */ |
657 | 18.9k | if (st->codecpar->codec_id == AV_CODEC_ID_G729 && sample_count && (data_size << 3) > sample_count) { |
658 | 3 | av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count); |
659 | 3 | sample_count = 0; |
660 | 3 | } |
661 | | |
662 | 18.9k | if (!sample_count || av_get_exact_bits_per_sample(st->codecpar->codec_id) > 0) |
663 | 18.7k | if ( st->codecpar->ch_layout.nb_channels |
664 | 17.5k | && data_size |
665 | 16.4k | && av_get_bits_per_sample(st->codecpar->codec_id) |
666 | 13.5k | && wav->data_end <= filesize) |
667 | 599 | sample_count = (data_size << 3) |
668 | 599 | / |
669 | 599 | (st->codecpar->ch_layout.nb_channels * (uint64_t)av_get_bits_per_sample(st->codecpar->codec_id)); |
670 | | |
671 | 18.9k | if (sample_count) |
672 | 465 | st->duration = sample_count; |
673 | | |
674 | 18.9k | if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S32LE && |
675 | 42 | st->codecpar->block_align == st->codecpar->ch_layout.nb_channels * 4 && |
676 | 23 | st->codecpar->bits_per_coded_sample == 32 && |
677 | 22 | st->codecpar->extradata_size == 2 && |
678 | 19 | AV_RL16(st->codecpar->extradata) == 1) { |
679 | 16 | st->codecpar->codec_id = AV_CODEC_ID_PCM_F16LE; |
680 | 16 | st->codecpar->bits_per_coded_sample = 16; |
681 | 18.8k | } else if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE && |
682 | 35 | st->codecpar->block_align == st->codecpar->ch_layout.nb_channels * 4 && |
683 | 22 | st->codecpar->bits_per_coded_sample == 24) { |
684 | 20 | st->codecpar->codec_id = AV_CODEC_ID_PCM_F24LE; |
685 | 18.8k | } else if (st->codecpar->codec_id == AV_CODEC_ID_XMA1 || |
686 | 18.8k | st->codecpar->codec_id == AV_CODEC_ID_XMA2) { |
687 | 23 | st->codecpar->block_align = 2048; |
688 | 18.8k | } else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS && st->codecpar->ch_layout.nb_channels > 2 && |
689 | 73 | st->codecpar->block_align < INT_MAX / st->codecpar->ch_layout.nb_channels) { |
690 | 71 | st->codecpar->block_align *= st->codecpar->ch_layout.nb_channels; |
691 | 71 | } |
692 | | |
693 | 18.9k | ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); |
694 | 18.9k | ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); |
695 | | |
696 | 18.9k | set_spdif(s, wav); |
697 | 18.9k | set_max_size(st, wav); |
698 | | |
699 | 18.9k | return 0; |
700 | 19.0k | } |
701 | | |
702 | | /** |
703 | | * Find chunk with w64 GUID by skipping over other chunks. |
704 | | * @return the size of the found chunk |
705 | | */ |
706 | | static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16]) |
707 | 1.91k | { |
708 | 1.91k | uint8_t guid[16]; |
709 | 1.91k | int64_t size; |
710 | | |
711 | 3.34k | while (!avio_feof(pb)) { |
712 | 3.13k | if (avio_read(pb, guid, 16) != 16) |
713 | 134 | break; |
714 | 2.99k | size = avio_rl64(pb); |
715 | 2.99k | if (size <= 24 || size > INT64_MAX - 8) |
716 | 446 | return AVERROR_INVALIDDATA; |
717 | 2.55k | if (!memcmp(guid, guid1, 16)) |
718 | 1.11k | return size; |
719 | 1.43k | avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24); |
720 | 1.43k | } |
721 | 351 | return AVERROR_EOF; |
722 | 1.91k | } |
723 | | |
724 | | static int wav_read_packet(AVFormatContext *s, AVPacket *pkt) |
725 | 22.2M | { |
726 | 22.2M | int ret, size; |
727 | 22.2M | int64_t left; |
728 | 22.2M | WAVDemuxContext *wav = s->priv_data; |
729 | 22.2M | AVStream *st = s->streams[0]; |
730 | | |
731 | 22.2M | if (CONFIG_SPDIF_DEMUXER && wav->spdif == 1) |
732 | 24.7k | return ff_spdif_read_packet(s, pkt); |
733 | | |
734 | 22.1M | if (wav->smv_data_ofs > 0) { |
735 | 76.8k | int64_t audio_dts, video_dts; |
736 | 76.8k | AVStream *vst = wav->vst; |
737 | 77.5k | smv_retry: |
738 | 77.5k | audio_dts = (int32_t)ffstream( st)->cur_dts; |
739 | 77.5k | video_dts = (int32_t)ffstream(vst)->cur_dts; |
740 | | |
741 | 77.5k | if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) { |
742 | | /*We always return a video frame first to get the pixel format first*/ |
743 | 77.5k | wav->smv_last_stream = wav->smv_given_first ? |
744 | 76.9k | av_compare_ts(video_dts, vst->time_base, |
745 | 76.9k | audio_dts, st->time_base) > 0 : 0; |
746 | 77.5k | wav->smv_given_first = 1; |
747 | 77.5k | } |
748 | 77.5k | wav->smv_last_stream = !wav->smv_last_stream; |
749 | 77.5k | wav->smv_last_stream |= wav->audio_eof; |
750 | 77.5k | wav->smv_last_stream &= !wav->smv_eof; |
751 | 77.5k | if (wav->smv_last_stream) { |
752 | 16.3k | uint64_t old_pos = avio_tell(s->pb); |
753 | 16.3k | uint64_t new_pos = wav->smv_data_ofs + |
754 | 16.3k | wav->smv_block * (int64_t)wav->smv_block_size; |
755 | 16.3k | if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) { |
756 | 118 | ret = AVERROR_EOF; |
757 | 118 | goto smv_out; |
758 | 118 | } |
759 | 16.1k | size = avio_rl24(s->pb); |
760 | 16.1k | if (size > wav->smv_block_size) { |
761 | 290 | ret = AVERROR_EOF; |
762 | 290 | goto smv_out; |
763 | 290 | } |
764 | 15.9k | ret = av_get_packet(s->pb, pkt, size); |
765 | 15.9k | if (ret < 0) |
766 | 41 | goto smv_out; |
767 | 15.8k | pkt->pos -= 3; |
768 | 15.8k | pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg; |
769 | 15.8k | pkt->duration = wav->smv_frames_per_jpeg; |
770 | 15.8k | wav->smv_block++; |
771 | | |
772 | 15.8k | pkt->stream_index = vst->index; |
773 | 16.3k | smv_out: |
774 | 16.3k | avio_seek(s->pb, old_pos, SEEK_SET); |
775 | 16.3k | if (ret == AVERROR_EOF) { |
776 | 449 | wav->smv_eof = 1; |
777 | 449 | goto smv_retry; |
778 | 449 | } |
779 | 15.8k | return ret; |
780 | 16.3k | } |
781 | 77.5k | } |
782 | | |
783 | 22.1M | left = wav->data_end - avio_tell(s->pb); |
784 | 22.1M | if (wav->ignore_length) |
785 | 0 | left = INT_MAX; |
786 | 22.1M | if (left <= 0) { |
787 | 5.56k | if (CONFIG_W64_DEMUXER && wav->w64) |
788 | 1.91k | left = find_guid(s->pb, ff_w64_guid_data) - 24; |
789 | 3.65k | else |
790 | 3.65k | left = find_tag(wav, s->pb, MKTAG('d', 'a', 't', 'a')); |
791 | 5.56k | if (left < 0) { |
792 | 2.36k | wav->audio_eof = 1; |
793 | 2.36k | if (wav->smv_data_ofs > 0 && !wav->smv_eof) |
794 | 229 | goto smv_retry; |
795 | 2.14k | return AVERROR_EOF; |
796 | 2.36k | } |
797 | 3.19k | if (INT64_MAX - left < avio_tell(s->pb)) |
798 | 4 | return AVERROR_INVALIDDATA; |
799 | 3.19k | wav->data_end = avio_tell(s->pb) + left; |
800 | 3.19k | } |
801 | | |
802 | 22.1M | size = wav->max_size; |
803 | 22.1M | if (st->codecpar->block_align > 1) { |
804 | 2.60M | if (size < st->codecpar->block_align) |
805 | 0 | size = st->codecpar->block_align; |
806 | 2.60M | size = (size / st->codecpar->block_align) * st->codecpar->block_align; |
807 | 2.60M | } |
808 | 22.1M | size = FFMIN(size, left); |
809 | 22.1M | ret = av_get_packet(s->pb, pkt, size); |
810 | 22.1M | if (ret < 0) |
811 | 101k | return ret; |
812 | 22.0M | pkt->stream_index = 0; |
813 | | |
814 | 22.0M | return ret; |
815 | 22.1M | } |
816 | | |
817 | | static int wav_read_seek(AVFormatContext *s, |
818 | | int stream_index, int64_t timestamp, int flags) |
819 | 0 | { |
820 | 0 | WAVDemuxContext *wav = s->priv_data; |
821 | 0 | AVStream *ast = s->streams[0], *vst = wav->vst; |
822 | 0 | wav->smv_eof = 0; |
823 | 0 | wav->audio_eof = 0; |
824 | |
|
825 | 0 | if (stream_index != 0 && (!vst || stream_index != vst->index)) |
826 | 0 | return AVERROR(EINVAL); |
827 | 0 | if (wav->smv_data_ofs > 0) { |
828 | 0 | int64_t smv_timestamp = timestamp; |
829 | 0 | if (stream_index == 0) |
830 | 0 | smv_timestamp = av_rescale_q(timestamp, ast->time_base, vst->time_base); |
831 | 0 | else |
832 | 0 | timestamp = av_rescale_q(smv_timestamp, vst->time_base, ast->time_base); |
833 | 0 | if (wav->smv_frames_per_jpeg > 0) { |
834 | 0 | wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg; |
835 | 0 | } |
836 | 0 | } |
837 | |
|
838 | 0 | switch (ast->codecpar->codec_id) { |
839 | 0 | case AV_CODEC_ID_MP2: |
840 | 0 | case AV_CODEC_ID_MP3: |
841 | 0 | case AV_CODEC_ID_AC3: |
842 | 0 | case AV_CODEC_ID_DTS: |
843 | 0 | case AV_CODEC_ID_XMA2: |
844 | | /* use generic seeking with dynamically generated indexes */ |
845 | 0 | return -1; |
846 | 0 | default: |
847 | 0 | break; |
848 | 0 | } |
849 | 0 | return ff_pcm_read_seek(s, 0, timestamp, flags); |
850 | 0 | } |
851 | | |
852 | | static const AVClass wav_demuxer_class = { |
853 | | .class_name = "WAV demuxer", |
854 | | .item_name = av_default_item_name, |
855 | | .option = demux_options, |
856 | | .version = LIBAVUTIL_VERSION_INT, |
857 | | }; |
858 | | const FFInputFormat ff_wav_demuxer = { |
859 | | .p.name = "wav", |
860 | | .p.long_name = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"), |
861 | | .p.flags = AVFMT_GENERIC_INDEX, |
862 | | .p.codec_tag = ff_wav_codec_tags_list, |
863 | | .p.priv_class = &wav_demuxer_class, |
864 | | .priv_data_size = sizeof(WAVDemuxContext), |
865 | | .flags_internal = FF_INFMT_FLAG_ID3V2_AUTO, |
866 | | .read_probe = wav_probe, |
867 | | .read_header = wav_read_header, |
868 | | .read_packet = wav_read_packet, |
869 | | .read_seek = wav_read_seek, |
870 | | }; |
871 | | #endif /* CONFIG_WAV_DEMUXER */ |
872 | | |
873 | | #if CONFIG_W64_DEMUXER |
874 | | static int w64_probe(const AVProbeData *p) |
875 | 963k | { |
876 | 963k | if (p->buf_size <= 40) |
877 | 224k | return 0; |
878 | 738k | if (!memcmp(p->buf, ff_w64_guid_riff, 16) && |
879 | 2.82k | !memcmp(p->buf + 24, ff_w64_guid_wave, 16)) |
880 | 2.25k | return AVPROBE_SCORE_MAX; |
881 | 736k | else |
882 | 736k | return 0; |
883 | 738k | } |
884 | | |
885 | | static int w64_read_header(AVFormatContext *s) |
886 | 20.5k | { |
887 | 20.5k | int64_t size, data_ofs = 0; |
888 | 20.5k | AVIOContext *pb = s->pb; |
889 | 20.5k | WAVDemuxContext *wav = s->priv_data; |
890 | 20.5k | AVStream *st; |
891 | 20.5k | uint8_t guid[16]; |
892 | 20.5k | int ret = ffio_read_size(pb, guid, 16); |
893 | | |
894 | 20.5k | if (ret < 0) |
895 | 40 | return ret; |
896 | | |
897 | 20.4k | if (memcmp(guid, ff_w64_guid_riff, 16)) |
898 | 112 | return AVERROR_INVALIDDATA; |
899 | | |
900 | | /* riff + wave + fmt + sizes */ |
901 | 20.3k | if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) |
902 | 8 | return AVERROR_INVALIDDATA; |
903 | | |
904 | 20.3k | ret = ffio_read_size(pb, guid, 16); |
905 | 20.3k | if (ret < 0) |
906 | 77 | return ret; |
907 | 20.2k | if (memcmp(guid, ff_w64_guid_wave, 16)) { |
908 | 26 | av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); |
909 | 26 | return AVERROR_INVALIDDATA; |
910 | 26 | } |
911 | | |
912 | 20.2k | wav->w64 = 1; |
913 | | |
914 | 20.2k | st = avformat_new_stream(s, NULL); |
915 | 20.2k | if (!st) |
916 | 0 | return AVERROR(ENOMEM); |
917 | | |
918 | 49.5k | while (!avio_feof(pb)) { |
919 | 48.6k | if (avio_read(pb, guid, 16) != 16) |
920 | 290 | break; |
921 | 48.3k | size = avio_rl64(pb); |
922 | 48.3k | if (size <= 24 || INT64_MAX - size - 7 < avio_tell(pb)) { |
923 | 1.07k | if (data_ofs) |
924 | 983 | break; |
925 | 89 | return AVERROR_INVALIDDATA; |
926 | 1.07k | } |
927 | | |
928 | 47.3k | if (!memcmp(guid, ff_w64_guid_fmt, 16)) { |
929 | | /* subtract chunk header size - normal wav file doesn't count it */ |
930 | 21.7k | ret = ff_get_wav_header(s, pb, st->codecpar, size - 24, 0); |
931 | 21.7k | if (ret < 0) |
932 | 358 | return ret; |
933 | 21.3k | avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); |
934 | 21.3k | if (st->codecpar->block_align && |
935 | 20.4k | st->codecpar->ch_layout.nb_channels < FF_SANE_NB_CHANNELS && |
936 | 13.7k | st->codecpar->bits_per_coded_sample < 128) { |
937 | 12.9k | int64_t block_align = st->codecpar->block_align; |
938 | | |
939 | 12.9k | block_align = FFMAX(block_align, |
940 | 12.9k | ((st->codecpar->bits_per_coded_sample + 7LL) / 8) * |
941 | 12.9k | st->codecpar->ch_layout.nb_channels); |
942 | 12.9k | if (block_align > st->codecpar->block_align) { |
943 | 7.07k | av_log(s, AV_LOG_WARNING, "invalid block_align: %d, broken file.\n", |
944 | 7.07k | st->codecpar->block_align); |
945 | 7.07k | st->codecpar->block_align = block_align; |
946 | 7.07k | } |
947 | 12.9k | } |
948 | 21.3k | avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); |
949 | 25.5k | } else if (!memcmp(guid, ff_w64_guid_fact, 16)) { |
950 | 295 | int64_t samples; |
951 | | |
952 | 295 | samples = avio_rl64(pb); |
953 | 295 | if (samples > 0) |
954 | 233 | st->duration = samples; |
955 | 295 | avio_skip(pb, FFALIGN(size, INT64_C(8)) - 32); |
956 | 25.2k | } else if (!memcmp(guid, ff_w64_guid_data, 16)) { |
957 | 19.0k | wav->data_end = avio_tell(pb) + size - 24; |
958 | | |
959 | 19.0k | data_ofs = avio_tell(pb); |
960 | 19.0k | if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) |
961 | 17.5k | break; |
962 | | |
963 | 1.45k | avio_skip(pb, size - 24); |
964 | 6.25k | } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) { |
965 | 864 | int64_t start, end, cur; |
966 | 864 | uint32_t count, chunk_size, i; |
967 | 864 | int64_t filesize = avio_size(s->pb); |
968 | | |
969 | 864 | start = avio_tell(pb); |
970 | 864 | end = start + FFALIGN(size, INT64_C(8)) - 24; |
971 | 864 | count = avio_rl32(pb); |
972 | | |
973 | 4.28k | for (i = 0; i < count; i++) { |
974 | 4.22k | char chunk_key[5], *value; |
975 | | |
976 | 4.22k | if (avio_feof(pb) || (cur = avio_tell(pb)) < 0 || cur > end - 8 /* = tag + size */) |
977 | 710 | break; |
978 | | |
979 | 3.51k | chunk_key[4] = 0; |
980 | 3.51k | avio_read(pb, chunk_key, 4); |
981 | 3.51k | chunk_size = avio_rl32(pb); |
982 | 3.51k | if (chunk_size == UINT32_MAX || (filesize >= 0 && chunk_size > filesize)) |
983 | 7 | return AVERROR_INVALIDDATA; |
984 | | |
985 | 3.51k | value = av_malloc(chunk_size + 1); |
986 | 3.51k | if (!value) |
987 | 35 | return AVERROR(ENOMEM); |
988 | | |
989 | 3.47k | ret = avio_get_str16le(pb, chunk_size, value, chunk_size); |
990 | 3.47k | if (ret < 0) { |
991 | 60 | av_free(value); |
992 | 60 | return ret; |
993 | 60 | } |
994 | 3.41k | avio_skip(pb, chunk_size - ret); |
995 | | |
996 | 3.41k | av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL); |
997 | 3.41k | } |
998 | | |
999 | 762 | avio_skip(pb, end - avio_tell(pb)); |
1000 | 5.38k | } else { |
1001 | 5.38k | av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid)); |
1002 | 5.38k | avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24); |
1003 | 5.38k | } |
1004 | 47.3k | } |
1005 | | |
1006 | 19.7k | if (!data_ofs) |
1007 | 848 | return AVERROR_EOF; |
1008 | | |
1009 | 18.8k | ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); |
1010 | 18.8k | ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); |
1011 | | |
1012 | 18.8k | handle_stream_probing(st); |
1013 | 18.8k | ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW; |
1014 | | |
1015 | 18.8k | avio_seek(pb, data_ofs, SEEK_SET); |
1016 | | |
1017 | 18.8k | set_spdif(s, wav); |
1018 | 18.8k | set_max_size(st, wav); |
1019 | | |
1020 | 18.8k | return 0; |
1021 | 19.7k | } |
1022 | | |
1023 | | static const AVClass w64_demuxer_class = { |
1024 | | .class_name = "W64 demuxer", |
1025 | | .item_name = av_default_item_name, |
1026 | | .option = &demux_options[W64_DEMUXER_OPTIONS_OFFSET], |
1027 | | .version = LIBAVUTIL_VERSION_INT, |
1028 | | }; |
1029 | | |
1030 | | const FFInputFormat ff_w64_demuxer = { |
1031 | | .p.name = "w64", |
1032 | | .p.long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"), |
1033 | | .p.flags = AVFMT_GENERIC_INDEX, |
1034 | | .p.codec_tag = ff_wav_codec_tags_list, |
1035 | | .p.priv_class = &w64_demuxer_class, |
1036 | | .priv_data_size = sizeof(WAVDemuxContext), |
1037 | | .read_probe = w64_probe, |
1038 | | .read_header = w64_read_header, |
1039 | | .read_packet = wav_read_packet, |
1040 | | .read_seek = wav_read_seek, |
1041 | | }; |
1042 | | #endif /* CONFIG_W64_DEMUXER */ |