3 * Copyright (c) 2001, 2002 Fabrice Bellard
7 * Copyright (c) 2009 Daniel Verkamp
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "libavutil/avassert.h"
29 #include "libavutil/dict.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/log.h"
32 #include "libavutil/mathematics.h"
33 #include "libavutil/opt.h"
36 #include "avio_internal.h"
44 typedef struct WAVDemuxContext
{
50 int smv_frames_per_jpeg
;
59 int unaligned
; // e.g. if an odd number of bytes ID3 tag was prepended
62 #if CONFIG_WAV_DEMUXER
64 static int64_t next_tag(AVIOContext
*pb
, uint32_t *tag
)
70 /* RIFF chunks are always at even offsets relative to where they start. */
71 static int64_t wav_seek_tag(WAVDemuxContext
* wav
, AVIOContext
*s
, int64_t offset
, int whence
)
73 offset
+= offset
< INT64_MAX
&& offset
+ wav
->unaligned
& 1;
75 return avio_seek(s
, offset
, whence
);
78 /* return the size of the found tag */
79 static int64_t find_tag(WAVDemuxContext
* wav
, AVIOContext
*pb
, uint32_t tag1
)
87 size
= next_tag(pb
, &tag
);
90 wav_seek_tag(wav
, pb
, size
, SEEK_CUR
);
95 static int wav_probe(AVProbeData
*p
)
97 /* check file header */
98 if (p
->buf_size
<= 32)
100 if (!memcmp(p
->buf
+ 8, "WAVE", 4)) {
101 if (!memcmp(p
->buf
, "RIFF", 4))
102 /* Since the ACT demuxer has a standard WAV header at the top of
103 * its own, the returned score is decreased to avoid a probe
104 * conflict between ACT and WAV. */
105 return AVPROBE_SCORE_MAX
- 1;
106 else if (!memcmp(p
->buf
, "RF64", 4) &&
107 !memcmp(p
->buf
+ 12, "ds64", 4))
108 return AVPROBE_SCORE_MAX
;
113 static void handle_stream_probing(AVStream
*st
)
115 if (st
->codec
->codec_id
== AV_CODEC_ID_PCM_S16LE
) {
116 st
->request_probe
= AVPROBE_SCORE_EXTENSION
;
117 st
->probe_packets
= FFMIN(st
->probe_packets
, 14);
121 static int wav_parse_fmt_tag(AVFormatContext
*s
, int64_t size
, AVStream
**st
)
123 AVIOContext
*pb
= s
->pb
;
126 /* parse fmt header */
127 *st
= avformat_new_stream(s
, NULL
);
129 return AVERROR(ENOMEM
);
131 ret
= ff_get_wav_header(pb
, (*st
)->codec
, size
);
134 handle_stream_probing(*st
);
136 (*st
)->need_parsing
= AVSTREAM_PARSE_FULL_RAW
;
138 avpriv_set_pts_info(*st
, 64, 1, (*st
)->codec
->sample_rate
);
143 static inline int wav_parse_bext_string(AVFormatContext
*s
, const char *key
,
149 av_assert0(length
<= sizeof(temp
));
150 if ((ret
= avio_read(s
->pb
, temp
, length
)) < 0)
156 return av_dict_set(&s
->metadata
, key
, temp
, 0);
161 static int wav_parse_bext_tag(AVFormatContext
*s
, int64_t size
)
163 char temp
[131], *coding_history
;
165 uint64_t time_reference
;
166 int64_t umid_parts
[8], umid_mask
= 0;
168 if ((ret
= wav_parse_bext_string(s
, "description", 256)) < 0 ||
169 (ret
= wav_parse_bext_string(s
, "originator", 32)) < 0 ||
170 (ret
= wav_parse_bext_string(s
, "originator_reference", 32)) < 0 ||
171 (ret
= wav_parse_bext_string(s
, "origination_date", 10)) < 0 ||
172 (ret
= wav_parse_bext_string(s
, "origination_time", 8)) < 0)
175 time_reference
= avio_rl64(s
->pb
);
176 snprintf(temp
, sizeof(temp
), "%"PRIu64
, time_reference
);
177 if ((ret
= av_dict_set(&s
->metadata
, "time_reference", temp
, 0)) < 0)
180 /* check if version is >= 1, in which case an UMID may be present */
181 if (avio_rl16(s
->pb
) >= 1) {
182 for (x
= 0; x
< 8; x
++)
183 umid_mask
|= umid_parts
[x
] = avio_rb64(s
->pb
);
186 /* the string formatting below is per SMPTE 330M-2004 Annex C */
187 if (umid_parts
[4] == 0 && umid_parts
[5] == 0 &&
188 umid_parts
[6] == 0 && umid_parts
[7] == 0) {
190 snprintf(temp
, sizeof(temp
),
191 "0x%016"PRIX64
"%016"PRIX64
"%016"PRIX64
"%016"PRIX64
,
192 umid_parts
[0], umid_parts
[1],
193 umid_parts
[2], umid_parts
[3]);
196 snprintf(temp
, sizeof(temp
),
197 "0x%016"PRIX64
"%016"PRIX64
"%016"PRIX64
"%016"PRIX64
198 "%016"PRIX64
"%016"PRIX64
"%016"PRIX64
"%016"PRIX64
,
199 umid_parts
[0], umid_parts
[1],
200 umid_parts
[2], umid_parts
[3],
201 umid_parts
[4], umid_parts
[5],
202 umid_parts
[6], umid_parts
[7]);
205 if ((ret
= av_dict_set(&s
->metadata
, "umid", temp
, 0)) < 0)
209 avio_skip(s
->pb
, 190);
211 avio_skip(s
->pb
, 254);
214 /* CodingHistory present */
217 if (!(coding_history
= av_malloc(size
+ 1)))
218 return AVERROR(ENOMEM
);
220 if ((ret
= avio_read(s
->pb
, coding_history
, size
)) < 0)
223 coding_history
[size
] = 0;
224 if ((ret
= av_dict_set(&s
->metadata
, "coding_history", coding_history
,
225 AV_DICT_DONT_STRDUP_VAL
)) < 0)
232 static const AVMetadataConv wav_metadata_conv
[] = {
233 { "description", "comment" },
234 { "originator", "encoded_by" },
235 { "origination_date", "date" },
236 { "origination_time", "creation_time" },
241 static int wav_read_header(AVFormatContext
*s
)
243 int64_t size
, av_uninit(data_size
);
244 int64_t sample_count
= 0;
247 AVIOContext
*pb
= s
->pb
;
249 WAVDemuxContext
*wav
= s
->priv_data
;
250 int ret
, got_fmt
= 0;
251 int64_t next_tag_ofs
, data_ofs
= -1;
253 wav
->unaligned
= avio_tell(s
->pb
) & 1;
255 wav
->smv_data_ofs
= -1;
257 /* check RIFF header */
260 rf64
= tag
== MKTAG('R', 'F', '6', '4');
261 if (!rf64
&& tag
!= MKTAG('R', 'I', 'F', 'F'))
262 return AVERROR_INVALIDDATA
;
263 avio_rl32(pb
); /* file size */
265 if (tag
!= MKTAG('W', 'A', 'V', 'E'))
266 return AVERROR_INVALIDDATA
;
269 if (avio_rl32(pb
) != MKTAG('d', 's', '6', '4'))
270 return AVERROR_INVALIDDATA
;
271 size
= avio_rl32(pb
);
273 return AVERROR_INVALIDDATA
;
274 avio_rl64(pb
); /* RIFF size */
276 data_size
= avio_rl64(pb
);
277 sample_count
= avio_rl64(pb
);
279 if (data_size
< 0 || sample_count
< 0) {
280 av_log(s
, AV_LOG_ERROR
, "negative data_size and/or sample_count in "
281 "ds64: data_size = %"PRId64
", sample_count = %"PRId64
"\n",
282 data_size
, sample_count
);
283 return AVERROR_INVALIDDATA
;
285 avio_skip(pb
, size
- 24); /* skip rest of ds64 chunk */
291 size
= next_tag(pb
, &tag
);
292 next_tag_ofs
= avio_tell(pb
) + size
;
298 case MKTAG('f', 'm', 't', ' '):
299 /* only parse the first 'fmt ' tag found */
300 if (!got_fmt
&& (ret
= wav_parse_fmt_tag(s
, size
, &st
)) < 0) {
303 av_log(s
, AV_LOG_WARNING
, "found more than one 'fmt ' tag\n");
307 case MKTAG('d', 'a', 't', 'a'):
309 av_log(s
, AV_LOG_ERROR
,
310 "found no 'fmt ' tag before the 'data' tag\n");
311 return AVERROR_INVALIDDATA
;
315 next_tag_ofs
= wav
->data_end
= avio_tell(pb
) + data_size
;
318 next_tag_ofs
= wav
->data_end
= size
? next_tag_ofs
: INT64_MAX
;
321 data_ofs
= avio_tell(pb
);
323 /* don't look for footer metadata if we can't seek or if we don't
324 * know where the data tag ends
326 if (!pb
->seekable
|| (!rf64
&& !size
))
329 case MKTAG('f', 'a', 'c', 't'):
331 sample_count
= avio_rl32(pb
);
333 case MKTAG('b', 'e', 'x', 't'):
334 if ((ret
= wav_parse_bext_tag(s
, size
)) < 0)
337 case MKTAG('S','M','V','0'):
339 av_log(s
, AV_LOG_ERROR
, "found no 'fmt ' tag before the 'SMV0' tag\n");
340 return AVERROR_INVALIDDATA
;
342 // SMV file, a wav file with video appended.
343 if (size
!= MKTAG('0','2','0','0')) {
344 av_log(s
, AV_LOG_ERROR
, "Unknown SMV version found\n");
347 av_log(s
, AV_LOG_DEBUG
, "Found SMV data\n");
348 wav
->smv_given_first
= 0;
349 vst
= avformat_new_stream(s
, NULL
);
351 return AVERROR(ENOMEM
);
354 vst
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
355 vst
->codec
->codec_id
= AV_CODEC_ID_SMVJPEG
;
356 vst
->codec
->width
= avio_rl24(pb
);
357 vst
->codec
->height
= avio_rl24(pb
);
358 if (ff_alloc_extradata(vst
->codec
, 4)) {
359 av_log(s
, AV_LOG_ERROR
, "Could not allocate extradata.\n");
360 return AVERROR(ENOMEM
);
362 size
= avio_rl24(pb
);
363 wav
->smv_data_ofs
= avio_tell(pb
) + (size
- 5) * 3;
365 wav
->smv_block_size
= avio_rl24(pb
);
366 avpriv_set_pts_info(vst
, 32, 1, avio_rl24(pb
));
367 vst
->duration
= avio_rl24(pb
);
370 wav
->smv_frames_per_jpeg
= avio_rl24(pb
);
371 if (wav
->smv_frames_per_jpeg
> 65536) {
372 av_log(s
, AV_LOG_ERROR
, "too many frames per jpeg\n");
373 return AVERROR_INVALIDDATA
;
375 AV_WL32(vst
->codec
->extradata
, wav
->smv_frames_per_jpeg
);
378 case MKTAG('L', 'I', 'S', 'T'):
380 av_log(s
, AV_LOG_ERROR
, "too short LIST tag\n");
381 return AVERROR_INVALIDDATA
;
383 switch (avio_rl32(pb
)) {
384 case MKTAG('I', 'N', 'F', 'O'):
385 ff_read_riff_info(s
, size
- 4);
390 /* seek to next tag unless we know that we'll run into EOF */
391 if ((avio_size(pb
) > 0 && next_tag_ofs
>= avio_size(pb
)) ||
392 wav_seek_tag(wav
, pb
, next_tag_ofs
, SEEK_SET
) < 0) {
399 av_log(s
, AV_LOG_ERROR
, "no 'data' tag found\n");
400 return AVERROR_INVALIDDATA
;
403 avio_seek(pb
, data_ofs
, SEEK_SET
);
405 if ( data_size
> 0 && sample_count
&& st
->codec
->channels
406 && data_size
/ sample_count
/ st
->codec
->channels
> 8) {
407 av_log(s
, AV_LOG_WARNING
, "ignoring wrong sample_count %"PRId64
"\n", sample_count
);
411 if (!sample_count
|| av_get_exact_bits_per_sample(st
->codec
->codec_id
) > 0)
412 if ( st
->codec
->channels
414 && av_get_bits_per_sample(st
->codec
->codec_id
)
415 && wav
->data_end
<= avio_size(pb
))
416 sample_count
= (data_size
<< 3)
418 (st
->codec
->channels
* (uint64_t)av_get_bits_per_sample(st
->codec
->codec_id
));
421 st
->duration
= sample_count
;
423 ff_metadata_conv_ctx(s
, NULL
, wav_metadata_conv
);
424 ff_metadata_conv_ctx(s
, NULL
, ff_riff_info_conv
);
430 * Find chunk with w64 GUID by skipping over other chunks.
431 * @return the size of the found chunk
433 static int64_t find_guid(AVIOContext
*pb
, const uint8_t guid1
[16])
438 while (!avio_feof(pb
)) {
439 avio_read(pb
, guid
, 16);
440 size
= avio_rl64(pb
);
442 return AVERROR_INVALIDDATA
;
443 if (!memcmp(guid
, guid1
, 16))
445 avio_skip(pb
, FFALIGN(size
, INT64_C(8)) - 24);
450 #define MAX_SIZE 4096
452 static int wav_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
457 WAVDemuxContext
*wav
= s
->priv_data
;
459 if (CONFIG_SPDIF_DEMUXER
&& wav
->spdif
== 0 &&
460 s
->streams
[0]->codec
->codec_tag
== 1) {
461 enum AVCodecID codec
;
462 ret
= ff_spdif_probe(s
->pb
->buffer
, s
->pb
->buf_end
- s
->pb
->buffer
,
464 if (ret
> AVPROBE_SCORE_EXTENSION
) {
465 s
->streams
[0]->codec
->codec_id
= codec
;
471 if (CONFIG_SPDIF_DEMUXER
&& wav
->spdif
== 1)
472 return ff_spdif_read_packet(s
, pkt
);
474 if (wav
->smv_data_ofs
> 0) {
475 int64_t audio_dts
, video_dts
;
477 audio_dts
= (int32_t)s
->streams
[0]->cur_dts
;
478 video_dts
= (int32_t)s
->streams
[1]->cur_dts
;
480 if (audio_dts
!= AV_NOPTS_VALUE
&& video_dts
!= AV_NOPTS_VALUE
) {
481 /*We always return a video frame first to get the pixel format first*/
482 wav
->smv_last_stream
= wav
->smv_given_first
?
483 av_compare_ts(video_dts
, s
->streams
[1]->time_base
,
484 audio_dts
, s
->streams
[0]->time_base
) > 0 : 0;
485 wav
->smv_given_first
= 1;
487 wav
->smv_last_stream
= !wav
->smv_last_stream
;
488 wav
->smv_last_stream
|= wav
->audio_eof
;
489 wav
->smv_last_stream
&= !wav
->smv_eof
;
490 if (wav
->smv_last_stream
) {
491 uint64_t old_pos
= avio_tell(s
->pb
);
492 uint64_t new_pos
= wav
->smv_data_ofs
+
493 wav
->smv_block
* wav
->smv_block_size
;
494 if (avio_seek(s
->pb
, new_pos
, SEEK_SET
) < 0) {
498 size
= avio_rl24(s
->pb
);
499 ret
= av_get_packet(s
->pb
, pkt
, size
);
503 pkt
->pts
= wav
->smv_block
* wav
->smv_frames_per_jpeg
+ wav
->smv_cur_pt
;
505 if (wav
->smv_frames_per_jpeg
> 0)
506 wav
->smv_cur_pt
%= wav
->smv_frames_per_jpeg
;
507 if (!wav
->smv_cur_pt
)
510 pkt
->stream_index
= 1;
512 avio_seek(s
->pb
, old_pos
, SEEK_SET
);
513 if (ret
== AVERROR_EOF
) {
523 left
= wav
->data_end
- avio_tell(s
->pb
);
524 if (wav
->ignore_length
)
527 if (CONFIG_W64_DEMUXER
&& wav
->w64
)
528 left
= find_guid(s
->pb
, ff_w64_guid_data
) - 24;
530 left
= find_tag(wav
, s
->pb
, MKTAG('d', 'a', 't', 'a'));
533 if (wav
->smv_data_ofs
> 0 && !wav
->smv_eof
)
537 wav
->data_end
= avio_tell(s
->pb
) + left
;
541 if (st
->codec
->block_align
> 1) {
542 if (size
< st
->codec
->block_align
)
543 size
= st
->codec
->block_align
;
544 size
= (size
/ st
->codec
->block_align
) * st
->codec
->block_align
;
546 size
= FFMIN(size
, left
);
547 ret
= av_get_packet(s
->pb
, pkt
, size
);
550 pkt
->stream_index
= 0;
555 static int wav_read_seek(AVFormatContext
*s
,
556 int stream_index
, int64_t timestamp
, int flags
)
558 WAVDemuxContext
*wav
= s
->priv_data
;
562 if (wav
->smv_data_ofs
> 0) {
563 int64_t smv_timestamp
= timestamp
;
564 if (stream_index
== 0)
565 smv_timestamp
= av_rescale_q(timestamp
, s
->streams
[0]->time_base
, s
->streams
[1]->time_base
);
567 timestamp
= av_rescale_q(smv_timestamp
, s
->streams
[1]->time_base
, s
->streams
[0]->time_base
);
568 if (wav
->smv_frames_per_jpeg
> 0) {
569 wav
->smv_block
= smv_timestamp
/ wav
->smv_frames_per_jpeg
;
570 wav
->smv_cur_pt
= smv_timestamp
% wav
->smv_frames_per_jpeg
;
575 switch (st
->codec
->codec_id
) {
576 case AV_CODEC_ID_MP2
:
577 case AV_CODEC_ID_MP3
:
578 case AV_CODEC_ID_AC3
:
579 case AV_CODEC_ID_DTS
:
580 /* use generic seeking with dynamically generated indexes */
585 return ff_pcm_read_seek(s
, stream_index
, timestamp
, flags
);
588 #define OFFSET(x) offsetof(WAVDemuxContext, x)
589 #define DEC AV_OPT_FLAG_DECODING_PARAM
590 static const AVOption demux_options
[] = {
591 { "ignore_length", "Ignore length", OFFSET(ignore_length
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, DEC
},
595 static const AVClass wav_demuxer_class
= {
596 .class_name
= "WAV demuxer",
597 .item_name
= av_default_item_name
,
598 .option
= demux_options
,
599 .version
= LIBAVUTIL_VERSION_INT
,
601 AVInputFormat ff_wav_demuxer
= {
603 .long_name
= NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
604 .priv_data_size
= sizeof(WAVDemuxContext
),
605 .read_probe
= wav_probe
,
606 .read_header
= wav_read_header
,
607 .read_packet
= wav_read_packet
,
608 .read_seek
= wav_read_seek
,
609 .flags
= AVFMT_GENERIC_INDEX
,
610 .codec_tag
= (const AVCodecTag
* const []) { ff_codec_wav_tags
, 0 },
611 .priv_class
= &wav_demuxer_class
,
613 #endif /* CONFIG_WAV_DEMUXER */
615 #if CONFIG_W64_DEMUXER
616 static int w64_probe(AVProbeData
*p
)
618 if (p
->buf_size
<= 40)
620 if (!memcmp(p
->buf
, ff_w64_guid_riff
, 16) &&
621 !memcmp(p
->buf
+ 24, ff_w64_guid_wave
, 16))
622 return AVPROBE_SCORE_MAX
;
627 static int w64_read_header(AVFormatContext
*s
)
629 int64_t size
, data_ofs
= 0;
630 AVIOContext
*pb
= s
->pb
;
631 WAVDemuxContext
*wav
= s
->priv_data
;
636 avio_read(pb
, guid
, 16);
637 if (memcmp(guid
, ff_w64_guid_riff
, 16))
638 return AVERROR_INVALIDDATA
;
640 /* riff + wave + fmt + sizes */
641 if (avio_rl64(pb
) < 16 + 8 + 16 + 8 + 16 + 8)
642 return AVERROR_INVALIDDATA
;
644 avio_read(pb
, guid
, 16);
645 if (memcmp(guid
, ff_w64_guid_wave
, 16)) {
646 av_log(s
, AV_LOG_ERROR
, "could not find wave guid\n");
647 return AVERROR_INVALIDDATA
;
652 st
= avformat_new_stream(s
, NULL
);
654 return AVERROR(ENOMEM
);
656 while (!avio_feof(pb
)) {
657 if (avio_read(pb
, guid
, 16) != 16)
659 size
= avio_rl64(pb
);
660 if (size
<= 24 || INT64_MAX
- size
< avio_tell(pb
))
661 return AVERROR_INVALIDDATA
;
663 if (!memcmp(guid
, ff_w64_guid_fmt
, 16)) {
664 /* subtract chunk header size - normal wav file doesn't count it */
665 ret
= ff_get_wav_header(pb
, st
->codec
, size
- 24);
668 avio_skip(pb
, FFALIGN(size
, INT64_C(8)) - size
);
670 avpriv_set_pts_info(st
, 64, 1, st
->codec
->sample_rate
);
671 } else if (!memcmp(guid
, ff_w64_guid_fact
, 16)) {
674 samples
= avio_rl64(pb
);
676 st
->duration
= samples
;
677 } else if (!memcmp(guid
, ff_w64_guid_data
, 16)) {
678 wav
->data_end
= avio_tell(pb
) + size
- 24;
680 data_ofs
= avio_tell(pb
);
684 avio_skip(pb
, size
- 24);
685 } else if (!memcmp(guid
, ff_w64_guid_summarylist
, 16)) {
686 int64_t start
, end
, cur
;
687 uint32_t count
, chunk_size
, i
;
689 start
= avio_tell(pb
);
690 end
= start
+ FFALIGN(size
, INT64_C(8)) - 24;
691 count
= avio_rl32(pb
);
693 for (i
= 0; i
< count
; i
++) {
694 char chunk_key
[5], *value
;
696 if (avio_feof(pb
) || (cur
= avio_tell(pb
)) < 0 || cur
> end
- 8 /* = tag + size */)
700 avio_read(pb
, chunk_key
, 4);
701 chunk_size
= avio_rl32(pb
);
703 value
= av_mallocz(chunk_size
+ 1);
705 return AVERROR(ENOMEM
);
707 ret
= avio_get_str16le(pb
, chunk_size
, value
, chunk_size
);
708 avio_skip(pb
, chunk_size
- ret
);
710 av_dict_set(&s
->metadata
, chunk_key
, value
, AV_DICT_DONT_STRDUP_VAL
);
713 avio_skip(pb
, end
- avio_tell(pb
));
715 av_log(s
, AV_LOG_DEBUG
, "unknown guid: "FF_PRI_GUID
"\n", FF_ARG_GUID(guid
));
716 avio_skip(pb
, FFALIGN(size
, INT64_C(8)) - 24);
723 ff_metadata_conv_ctx(s
, NULL
, wav_metadata_conv
);
724 ff_metadata_conv_ctx(s
, NULL
, ff_riff_info_conv
);
726 handle_stream_probing(st
);
727 st
->need_parsing
= AVSTREAM_PARSE_FULL_RAW
;
729 avio_seek(pb
, data_ofs
, SEEK_SET
);
734 AVInputFormat ff_w64_demuxer
= {
736 .long_name
= NULL_IF_CONFIG_SMALL("Sony Wave64"),
737 .priv_data_size
= sizeof(WAVDemuxContext
),
738 .read_probe
= w64_probe
,
739 .read_header
= w64_read_header
,
740 .read_packet
= wav_read_packet
,
741 .read_seek
= wav_read_seek
,
742 .flags
= AVFMT_GENERIC_INDEX
,
743 .codec_tag
= (const AVCodecTag
* const []) { ff_codec_wav_tags
, 0 },
745 #endif /* CONFIG_W64_DEMUXER */