wavdec.c 15.3 KB
Newer Older
1
/*
2
 * WAV demuxer
3
 * Copyright (c) 2001, 2002 Fabrice Bellard
Fabrice Bellard's avatar
Fabrice Bellard committed
4
 *
Daniel Verkamp's avatar
Daniel Verkamp committed
5
 * Sony Wave64 demuxer
6
 * RF64 demuxer
Daniel Verkamp's avatar
Daniel Verkamp committed
7 8
 * Copyright (c) 2009 Daniel Verkamp
 *
9
 * This file is part of Libav.
10
 *
11
 * Libav is free software; you can redistribute it and/or
12 13
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
14
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
15
 *
16
 * Libav is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
Fabrice Bellard committed
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
Fabrice Bellard's avatar
Fabrice Bellard committed
24
 */
25

26 27
#include <stdint.h>

28 29
#include "libavutil/avassert.h"
#include "libavutil/dict.h"
30
#include "libavutil/log.h"
31
#include "libavutil/mathematics.h"
32
#include "libavutil/opt.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
33
#include "avformat.h"
34
#include "avio.h"
35
#include "avio_internal.h"
36 37
#include "internal.h"
#include "metadata.h"
38
#include "pcm.h"
39
#include "riff.h"
40

41
typedef struct WAVDemuxContext {
42
    int64_t data_end;
Daniel Verkamp's avatar
Daniel Verkamp committed
43
    int w64;
44
} WAVDemuxContext;
Fabrice Bellard's avatar
Fabrice Bellard committed
45

46
#if CONFIG_WAV_DEMUXER
47

48
static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
49
{
50 51
    *tag = avio_rl32(pb);
    return avio_rl32(pb);
52 53
}

54 55 56 57 58 59
/* RIFF chunks are always on a even offset. */
static int64_t wav_seek_tag(AVIOContext *s, int64_t offset, int whence)
{
    return avio_seek(s, offset + (offset & 1), whence);
}

Fabrice Bellard's avatar
Fabrice Bellard committed
60
/* return the size of the found tag */
61
static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
Fabrice Bellard's avatar
Fabrice Bellard committed
62 63
{
    unsigned int tag;
64
    int64_t size;
Fabrice Bellard's avatar
Fabrice Bellard committed
65

66
    for (;;) {
Anton Khirnov's avatar
Anton Khirnov committed
67
        if (pb->eof_reached)
Fabrice Bellard's avatar
Fabrice Bellard committed
68
            return -1;
69
        size = next_tag(pb, &tag);
Fabrice Bellard's avatar
Fabrice Bellard committed
70 71
        if (tag == tag1)
            break;
72
        wav_seek_tag(pb, size, SEEK_CUR);
Fabrice Bellard's avatar
Fabrice Bellard committed
73 74 75 76
    }
    return size;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
77 78 79 80 81
static int wav_probe(AVProbeData *p)
{
    /* check file header */
    if (p->buf_size <= 32)
        return 0;
82 83
    if (!memcmp(p->buf + 8, "WAVE", 4)) {
        if (!memcmp(p->buf, "RIFF", 4))
Diego Biurrun's avatar
Diego Biurrun committed
84 85 86
            /* Since the ACT demuxer has a standard WAV header at the top of
             * its own, the returned score is decreased to avoid a probe
             * conflict between ACT and WAV. */
Daniel Verkamp's avatar
Daniel Verkamp committed
87
            return AVPROBE_SCORE_MAX - 1;
88 89 90 91
        else if (!memcmp(p->buf,      "RF64", 4) &&
                 !memcmp(p->buf + 12, "ds64", 4))
            return AVPROBE_SCORE_MAX;
    }
Daniel Verkamp's avatar
Daniel Verkamp committed
92
    return 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
93 94
}

95 96 97 98 99 100
static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
{
    AVIOContext *pb = s->pb;
    int ret;

    /* parse fmt header */
101
    *st = avformat_new_stream(s, NULL);
102 103 104
    if (!*st)
        return AVERROR(ENOMEM);

105
    ret = ff_get_wav_header(s, pb, (*st)->codecpar, size);
106 107 108 109
    if (ret < 0)
        return ret;
    (*st)->need_parsing = AVSTREAM_PARSE_FULL;

110
    avpriv_set_pts_info(*st, 64, 1, (*st)->codecpar->sample_rate);
111 112 113 114

    return 0;
}

115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
                                        int length)
{
    char temp[257];
    int ret;

    av_assert0(length <= sizeof(temp));
    if ((ret = avio_read(s->pb, temp, length)) < 0)
        return ret;

    temp[length] = 0;

    if (strlen(temp))
        return av_dict_set(&s->metadata, key, temp, 0);

    return 0;
}

static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
{
    char temp[131], *coding_history;
    int ret, x;
    uint64_t time_reference;
    int64_t umid_parts[8], umid_mask = 0;

    if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 ||
        (ret = wav_parse_bext_string(s, "originator", 32)) < 0 ||
        (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 ||
        (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 ||
        (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0)
        return ret;

    time_reference = avio_rl64(s->pb);
    snprintf(temp, sizeof(temp), "%"PRIu64, time_reference);
    if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0)
        return ret;

    /* check if version is >= 1, in which case an UMID may be present */
    if (avio_rl16(s->pb) >= 1) {
        for (x = 0; x < 8; x++)
            umid_mask |= umid_parts[x] = avio_rb64(s->pb);

        if (umid_mask) {
            /* the string formatting below is per SMPTE 330M-2004 Annex C */
159 160
            if (umid_parts[4] == 0 && umid_parts[5] == 0 &&
                umid_parts[6] == 0 && umid_parts[7] == 0) {
161
                /* basic UMID */
162 163 164 165
                snprintf(temp, sizeof(temp),
                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
                         umid_parts[0], umid_parts[1],
                         umid_parts[2], umid_parts[3]);
166 167
            } else {
                /* extended UMID */
168 169 170 171 172 173 174
                snprintf(temp, sizeof(temp),
                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
                         umid_parts[0], umid_parts[1],
                         umid_parts[2], umid_parts[3],
                         umid_parts[4], umid_parts[5],
                         umid_parts[6], umid_parts[7]);
175 176 177 178 179 180 181 182 183 184 185 186 187 188
            }

            if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
                return ret;
        }

        avio_skip(s->pb, 190);
    } else
        avio_skip(s->pb, 254);

    if (size > 602) {
        /* CodingHistory present */
        size -= 602;

189
        if (!(coding_history = av_malloc(size + 1)))
190 191 192 193 194 195 196
            return AVERROR(ENOMEM);

        if ((ret = avio_read(s->pb, coding_history, size)) < 0)
            return ret;

        coding_history[size] = 0;
        if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history,
197
                               AV_DICT_DONT_STRDUP_VAL)) < 0)
198 199 200 201 202 203 204
            return ret;
    }

    return 0;
}

static const AVMetadataConv wav_metadata_conv[] = {
205 206 207 208 209
    { "description",      "comment"       },
    { "originator",       "encoded_by"    },
    { "origination_date", "date"          },
    { "origination_time", "creation_time" },
    { 0 },
210 211
};

Fabrice Bellard's avatar
Fabrice Bellard committed
212
/* wav input */
213
static int wav_read_header(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
214
{
215
    int64_t size, av_uninit(data_size);
216
    int64_t sample_count = 0;
217
    int rf64;
218
    uint32_t tag;
219 220
    AVIOContext *pb      = s->pb;
    AVStream *st         = NULL;
221
    WAVDemuxContext *wav = s->priv_data;
222
    int ret, got_fmt = 0;
223
    int64_t next_tag_ofs, data_ofs = -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
224 225

    /* check RIFF header */
226
    tag = avio_rl32(pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
227

228 229
    rf64 = tag == MKTAG('R', 'F', '6', '4');
    if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
230
        return AVERROR_INVALIDDATA;
231 232
    avio_rl32(pb); /* file size */
    tag = avio_rl32(pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
233
    if (tag != MKTAG('W', 'A', 'V', 'E'))
234
        return AVERROR_INVALIDDATA;
235

236
    if (rf64) {
237
        if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
238
            return AVERROR_INVALIDDATA;
239
        size = avio_rl32(pb);
240
        if (size < 16)
241
            return AVERROR_INVALIDDATA;
242
        avio_rl64(pb); /* RIFF size */
243 244

        data_size    = avio_rl64(pb);
245
        sample_count = avio_rl64(pb);
246

247 248 249 250 251 252
        if (data_size < 0 || sample_count < 0) {
            av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
                   "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
                   data_size, sample_count);
            return AVERROR_INVALIDDATA;
        }
253
        avio_skip(pb, size - 16); /* skip rest of ds64 chunk */
254 255
    }

256
    for (;;) {
257
        size         = next_tag(pb, &tag);
258 259
        next_tag_ofs = avio_tell(pb) + size;

260 261 262
        if (pb->eof_reached)
            break;

263 264
        switch (tag) {
        case MKTAG('f', 'm', 't', ' '):
265 266 267 268 269 270 271
            /* only parse the first 'fmt ' tag found */
            if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st) < 0)) {
                return ret;
            } else if (got_fmt)
                av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");

            got_fmt = 1;
272 273
            break;
        case MKTAG('d', 'a', 't', 'a'):
274
            if (!got_fmt) {
275 276
                av_log(s, AV_LOG_ERROR,
                       "found no 'fmt ' tag before the 'data' tag\n");
277 278 279
                return AVERROR_INVALIDDATA;
            }

280 281 282
            if (rf64) {
                next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
            } else {
283
                data_size    = size;
284 285 286 287 288 289 290 291
                next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
            }

            data_ofs = avio_tell(pb);

            /* don't look for footer metadata if we can't seek or if we don't
             * know where the data tag ends
             */
292
            if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || (!rf64 && !size))
293 294
                goto break_loop;
            break;
295
        case MKTAG('f', 'a', 'c', 't'):
296 297
            if (!sample_count)
                sample_count = avio_rl32(pb);
298
            break;
299
        case MKTAG('b', 'e', 'x', 't'):
300 301 302
            if ((ret = wav_parse_bext_tag(s, size)) < 0)
                return ret;
            break;
303
        case MKTAG('L', 'I', 'S', 'T'):
304
            if (size < 4) {
305 306 307
                av_log(s, AV_LOG_ERROR, "too short LIST");
                return AVERROR_INVALIDDATA;
            }
308
            switch (avio_rl32(pb)) {
309 310 311 312 313
            case MKTAG('I', 'N', 'F', 'O'):
                if ((ret = ff_read_riff_info(s, size - 4)) < 0)
                    return ret;
            }
            break;
314
        }
315 316 317

        /* seek to next tag unless we know that we'll run into EOF */
        if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
318
            wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) {
319 320
            break;
        }
321
    }
322

323
break_loop:
324 325 326 327 328 329
    if (data_ofs < 0) {
        av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
        return AVERROR_INVALIDDATA;
    }

    avio_seek(pb, data_ofs, SEEK_SET);
330

331 332
    if (!sample_count && st->codecpar->channels &&
        av_get_bits_per_sample(st->codecpar->codec_id))
333
        sample_count = (data_size << 3) /
334 335
                       (st->codecpar->channels *
                        (uint64_t)av_get_bits_per_sample(st->codecpar->codec_id));
336 337
    if (sample_count)
        st->duration = sample_count;
338 339

    ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
340
    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
341

Fabrice Bellard's avatar
Fabrice Bellard committed
342 343 344
    return 0;
}

345 346
/**
 * Find chunk with w64 GUID by skipping over other chunks.
347 348
 * @return the size of the found chunk
 */
349
static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
350 351 352 353
{
    uint8_t guid[16];
    int64_t size;

Anton Khirnov's avatar
Anton Khirnov committed
354
    while (!pb->eof_reached) {
355 356
        avio_read(pb, guid, 16);
        size = avio_rl64(pb);
357 358 359 360
        if (size <= 24)
            return -1;
        if (!memcmp(guid, guid1, 16))
            return size;
361
        avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
362 363 364 365
    }
    return -1;
}

366 367 368 369
static const uint8_t guid_data[16] = {
    'd',  'a',  't',  'a',
    0xF3, 0xAC, 0xD3, 0x11,0x8C,  0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
};
370

Fabrice Bellard's avatar
Fabrice Bellard committed
371 372
#define MAX_SIZE 4096

373
static int wav_read_packet(AVFormatContext *s, AVPacket *pkt)
Fabrice Bellard's avatar
Fabrice Bellard committed
374
{
Daniel Verkamp's avatar
Daniel Verkamp committed
375 376
    int ret, size;
    int64_t left;
377
    AVStream *st;
378
    WAVDemuxContext *wav = s->priv_data;
Fabrice Bellard's avatar
Fabrice Bellard committed
379

380 381
    st = s->streams[0];

382
    left = wav->data_end - avio_tell(s->pb);
383
    if (left <= 0) {
384
        if (CONFIG_W64_DEMUXER && wav->w64)
Daniel Verkamp's avatar
Daniel Verkamp committed
385
            left = find_guid(s->pb, guid_data) - 24;
386 387 388
        else
            left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
        if (left < 0)
389
            return AVERROR_EOF;
390
        wav->data_end = avio_tell(s->pb) + left;
391 392
    }

393
    size = MAX_SIZE;
394 395 396 397
    if (st->codecpar->block_align > 1) {
        if (size < st->codecpar->block_align)
            size = st->codecpar->block_align;
        size = (size / st->codecpar->block_align) * st->codecpar->block_align;
398
    }
399 400
    size = FFMIN(size, left);
    ret  = av_get_packet(s->pb, pkt, size);
401 402
    if (ret < 0)
        return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
403 404 405 406 407
    pkt->stream_index = 0;

    return ret;
}

408
static int wav_read_seek(AVFormatContext *s,
409
                         int stream_index, int64_t timestamp, int flags)
410 411 412 413
{
    AVStream *st;

    st = s->streams[0];
414
    switch (st->codecpar->codec_id) {
415 416 417 418
    case AV_CODEC_ID_MP2:
    case AV_CODEC_ID_MP3:
    case AV_CODEC_ID_AC3:
    case AV_CODEC_ID_DTS:
419 420 421 422 423
        /* use generic seeking with dynamically generated indexes */
        return -1;
    default:
        break;
    }
424
    return ff_pcm_read_seek(s, stream_index, timestamp, flags);
425 426
}

427
AVInputFormat ff_wav_demuxer = {
428
    .name           = "wav",
429
    .long_name      = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
430
    .priv_data_size = sizeof(WAVDemuxContext),
431 432 433 434
    .read_probe     = wav_probe,
    .read_header    = wav_read_header,
    .read_packet    = wav_read_packet,
    .read_seek      = wav_read_seek,
435
    .flags          = AVFMT_GENERIC_INDEX,
436
    .codec_tag      = (const AVCodecTag * const []) { ff_codec_wav_tags,  0 },
Fabrice Bellard's avatar
Fabrice Bellard committed
437
};
438
#endif /* CONFIG_WAV_DEMUXER */
439

Daniel Verkamp's avatar
Daniel Verkamp committed
440
#if CONFIG_W64_DEMUXER
441 442 443 444
static const uint8_t guid_riff[16] = {
    'r',  'i',  'f',  'f',
    0x2E, 0x91, 0xCF, 0x11,0xA5,  0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
};
445

446 447 448 449
static const uint8_t guid_wave[16] = {
    'w',  'a',  'v',  'e',
    0xF3, 0xAC, 0xD3, 0x11,0x8C,  0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
};
450

451 452 453 454
static const uint8_t guid_fmt[16] = {
    'f',  'm',  't',  ' ',
    0xF3, 0xAC, 0xD3, 0x11,0x8C,  0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
};
455 456 457 458 459 460 461 462 463 464 465 466

static int w64_probe(AVProbeData *p)
{
    if (p->buf_size <= 40)
        return 0;
    if (!memcmp(p->buf,      guid_riff, 16) &&
        !memcmp(p->buf + 24, guid_wave, 16))
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

467
static int w64_read_header(AVFormatContext *s)
468 469
{
    int64_t size;
470 471
    AVIOContext *pb      = s->pb;
    WAVDemuxContext *wav = s->priv_data;
472 473
    AVStream *st;
    uint8_t guid[16];
474
    int ret;
475

476
    avio_read(pb, guid, 16);
477
    if (memcmp(guid, guid_riff, 16))
478
        return AVERROR_INVALIDDATA;
479

480 481
    /* riff + wave + fmt + sizes */
    if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
482
        return AVERROR_INVALIDDATA;
483

484
    avio_read(pb, guid, 16);
485 486
    if (memcmp(guid, guid_wave, 16)) {
        av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
487
        return AVERROR_INVALIDDATA;
488 489 490 491 492
    }

    size = find_guid(pb, guid_fmt);
    if (size < 0) {
        av_log(s, AV_LOG_ERROR, "could not find fmt guid\n");
493
        return AVERROR_INVALIDDATA;
494 495
    }

496
    st = avformat_new_stream(s, NULL);
497 498 499 500
    if (!st)
        return AVERROR(ENOMEM);

    /* subtract chunk header size - normal wav file doesn't count it */
501
    ret = ff_get_wav_header(s, pb, st->codecpar, size - 24);
502 503
    if (ret < 0)
        return ret;
504
    avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
505 506 507

    st->need_parsing = AVSTREAM_PARSE_FULL;

508
    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
509 510 511 512

    size = find_guid(pb, guid_data);
    if (size < 0) {
        av_log(s, AV_LOG_ERROR, "could not find data guid\n");
513
        return AVERROR_INVALIDDATA;
514
    }
515
    wav->data_end = avio_tell(pb) + size - 24;
516 517 518 519 520
    wav->w64      = 1;

    return 0;
}

521
AVInputFormat ff_w64_demuxer = {
522
    .name           = "w64",
523
    .long_name      = NULL_IF_CONFIG_SMALL("Sony Wave64"),
524
    .priv_data_size = sizeof(WAVDemuxContext),
525 526 527 528
    .read_probe     = w64_probe,
    .read_header    = w64_read_header,
    .read_packet    = wav_read_packet,
    .read_seek      = wav_read_seek,
529
    .flags          = AVFMT_GENERIC_INDEX,
530
    .codec_tag      = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
Daniel Verkamp's avatar
Daniel Verkamp committed
531
};
532
#endif /* CONFIG_W64_DEMUXER */