Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * IRCAM demuxer | |
3 | * Copyright (c) 2012 Paul B Mahol | |
4 | * | |
5 | * This file is part of FFmpeg. | |
6 | * | |
7 | * FFmpeg is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU Lesser General Public | |
9 | * License as published by the Free Software Foundation; either | |
10 | * version 2.1 of the License, or (at your option) any later version. | |
11 | * | |
12 | * FFmpeg is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * Lesser General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public | |
18 | * License along with FFmpeg; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | */ | |
21 | ||
22 | #include "libavutil/intreadwrite.h" | |
23 | #include "avformat.h" | |
24 | #include "internal.h" | |
25 | #include "pcm.h" | |
26 | #include "ircam.h" | |
27 | ||
28 | static int ircam_probe(AVProbeData *p) | |
29 | { | |
30 | if ((p->buf[0] == 0x64 && p->buf[1] == 0xA3 && p->buf[3] == 0x00 && | |
31 | p->buf[2] >= 1 && p->buf[2] <= 4) || | |
32 | (p->buf[3] == 0x64 && p->buf[2] == 0xA3 && p->buf[0] == 0x00 && | |
33 | p->buf[1] >= 1 && p->buf[1] <= 3) && | |
34 | AV_RN32(p->buf + 4) && AV_RN32(p->buf + 8)) | |
35 | return AVPROBE_SCORE_MAX / 4 * 3; | |
36 | return 0; | |
37 | } | |
38 | ||
39 | static const struct endianess { | |
40 | uint32_t magic; | |
41 | int is_le; | |
42 | } table[] = { | |
43 | { 0x64A30100, 0 }, | |
44 | { 0x64A30200, 1 }, | |
45 | { 0x64A30300, 0 }, | |
46 | { 0x64A30400, 1 }, | |
47 | { 0x0001A364, 1 }, | |
48 | { 0x0002A364, 0 }, | |
49 | { 0x0003A364, 1 }, | |
50 | }; | |
51 | ||
52 | static int ircam_read_header(AVFormatContext *s) | |
53 | { | |
54 | uint32_t magic, sample_rate, channels, tag; | |
55 | const AVCodecTag *tags; | |
56 | int le = -1, i; | |
57 | AVStream *st; | |
58 | ||
59 | magic = avio_rl32(s->pb); | |
60 | for (i = 0; i < 7; i++) { | |
61 | if (magic == table[i].magic) { | |
62 | le = table[i].is_le; | |
63 | break; | |
64 | } | |
65 | } | |
66 | ||
67 | if (le == 1) { | |
68 | sample_rate = av_int2float(avio_rl32(s->pb)); | |
69 | channels = avio_rl32(s->pb); | |
70 | tag = avio_rl32(s->pb); | |
71 | tags = ff_codec_ircam_le_tags; | |
72 | } else if (le == 0) { | |
73 | sample_rate = av_int2float(avio_rb32(s->pb)); | |
74 | channels = avio_rb32(s->pb); | |
75 | tag = avio_rb32(s->pb); | |
76 | tags = ff_codec_ircam_be_tags; | |
77 | } else { | |
78 | return AVERROR_INVALIDDATA; | |
79 | } | |
80 | ||
81 | if (!channels || !sample_rate) | |
82 | return AVERROR_INVALIDDATA; | |
83 | ||
84 | st = avformat_new_stream(s, NULL); | |
85 | if (!st) | |
86 | return AVERROR(ENOMEM); | |
87 | ||
88 | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | |
89 | st->codec->channels = channels; | |
90 | st->codec->sample_rate = sample_rate; | |
91 | ||
92 | st->codec->codec_id = ff_codec_get_id(tags, tag); | |
93 | if (st->codec->codec_id == AV_CODEC_ID_NONE) { | |
94 | av_log(s, AV_LOG_ERROR, "unknown tag %X\n", tag); | |
95 | return AVERROR_INVALIDDATA; | |
96 | } | |
97 | ||
98 | st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); | |
99 | st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; | |
100 | avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); | |
101 | avio_skip(s->pb, 1008); | |
102 | ||
103 | return 0; | |
104 | } | |
105 | ||
106 | AVInputFormat ff_ircam_demuxer = { | |
107 | .name = "ircam", | |
108 | .long_name = NULL_IF_CONFIG_SMALL("Berkeley/IRCAM/CARL Sound Format"), | |
109 | .read_probe = ircam_probe, | |
110 | .read_header = ircam_read_header, | |
111 | .read_packet = ff_pcm_read_packet, | |
112 | .read_seek = ff_pcm_read_seek, | |
113 | .extensions = "sf,ircam", | |
114 | .flags = AVFMT_GENERIC_INDEX, | |
115 | }; |