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