35ced25fe1e39a6a9461b7a53d9ba59ebdcb64cf
[libav.git] / libavformat / vocdec.c
1 /*
2 * Creative Voice File demuxer.
3 * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
4 *
5 * This file is part of Libav.
6 *
7 * Libav 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 * Libav 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 Libav; 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 "voc.h"
24 #include "internal.h"
25
26 int
27 ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
28 {
29 VocDecContext *voc = s->priv_data;
30 AVCodecContext *dec = st->codec;
31 AVIOContext *pb = s->pb;
32 VocType type;
33 int size, tmp_codec=-1;
34 int sample_rate = 0;
35 int channels = 1;
36
37 while (!voc->remaining_size) {
38 type = avio_r8(pb);
39 if (type == VOC_TYPE_EOF)
40 return AVERROR(EIO);
41 voc->remaining_size = avio_rl24(pb);
42 if (!voc->remaining_size) {
43 if (!s->pb->seekable)
44 return AVERROR(EIO);
45 voc->remaining_size = avio_size(pb) - avio_tell(pb);
46 }
47 max_size -= 4;
48
49 switch (type) {
50 case VOC_TYPE_VOICE_DATA:
51 if (!dec->sample_rate) {
52 dec->sample_rate = 1000000 / (256 - avio_r8(pb));
53 if (sample_rate)
54 dec->sample_rate = sample_rate;
55 avpriv_set_pts_info(st, 64, 1, dec->sample_rate);
56 dec->channels = channels;
57 dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id);
58 } else
59 avio_skip(pb, 1);
60 tmp_codec = avio_r8(pb);
61 voc->remaining_size -= 2;
62 max_size -= 2;
63 channels = 1;
64 break;
65
66 case VOC_TYPE_VOICE_DATA_CONT:
67 break;
68
69 case VOC_TYPE_EXTENDED:
70 sample_rate = avio_rl16(pb);
71 avio_r8(pb);
72 channels = avio_r8(pb) + 1;
73 sample_rate = 256000000 / (channels * (65536 - sample_rate));
74 voc->remaining_size = 0;
75 max_size -= 4;
76 break;
77
78 case VOC_TYPE_NEW_VOICE_DATA:
79 if (!dec->sample_rate) {
80 dec->sample_rate = avio_rl32(pb);
81 avpriv_set_pts_info(st, 64, 1, dec->sample_rate);
82 dec->bits_per_coded_sample = avio_r8(pb);
83 dec->channels = avio_r8(pb);
84 } else
85 avio_skip(pb, 6);
86 tmp_codec = avio_rl16(pb);
87 avio_skip(pb, 4);
88 voc->remaining_size -= 12;
89 max_size -= 12;
90 break;
91
92 default:
93 avio_skip(pb, voc->remaining_size);
94 max_size -= voc->remaining_size;
95 voc->remaining_size = 0;
96 break;
97 }
98 }
99
100 if (tmp_codec >= 0) {
101 tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec);
102 if (dec->codec_id == AV_CODEC_ID_NONE)
103 dec->codec_id = tmp_codec;
104 else if (dec->codec_id != tmp_codec)
105 av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n");
106 if (dec->codec_id == AV_CODEC_ID_NONE) {
107 if (s->audio_codec_id == AV_CODEC_ID_NONE) {
108 av_log(s, AV_LOG_ERROR, "unknown codec tag\n");
109 return AVERROR(EINVAL);
110 }
111 av_log(s, AV_LOG_WARNING, "unknown codec tag\n");
112 }
113 }
114
115 dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample;
116
117 if (max_size <= 0)
118 max_size = 2048;
119 size = FFMIN(voc->remaining_size, max_size);
120 voc->remaining_size -= size;
121 return av_get_packet(pb, pkt, size);
122 }
123
124 #if CONFIG_VOC_DEMUXER
125 static int voc_probe(AVProbeData *p)
126 {
127 int version, check;
128
129 if (memcmp(p->buf, ff_voc_magic, sizeof(ff_voc_magic) - 1))
130 return 0;
131 version = AV_RL16(p->buf + 22);
132 check = AV_RL16(p->buf + 24);
133 if (~version + 0x1234 != check)
134 return 10;
135
136 return AVPROBE_SCORE_MAX;
137 }
138
139 static int voc_read_header(AVFormatContext *s)
140 {
141 VocDecContext *voc = s->priv_data;
142 AVIOContext *pb = s->pb;
143 int header_size;
144 AVStream *st;
145
146 avio_skip(pb, 20);
147 header_size = avio_rl16(pb) - 22;
148 if (header_size != 4) {
149 av_log(s, AV_LOG_ERROR, "unknown header size: %d\n", header_size);
150 return AVERROR(ENOSYS);
151 }
152 avio_skip(pb, header_size);
153 st = avformat_new_stream(s, NULL);
154 if (!st)
155 return AVERROR(ENOMEM);
156 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
157
158 voc->remaining_size = 0;
159 return 0;
160 }
161
162 static int voc_read_packet(AVFormatContext *s, AVPacket *pkt)
163 {
164 return ff_voc_get_packet(s, pkt, s->streams[0], 0);
165 }
166
167 AVInputFormat ff_voc_demuxer = {
168 .name = "voc",
169 .long_name = NULL_IF_CONFIG_SMALL("Creative Voice"),
170 .priv_data_size = sizeof(VocDecContext),
171 .read_probe = voc_probe,
172 .read_header = voc_read_header,
173 .read_packet = voc_read_packet,
174 .codec_tag = (const AVCodecTag* const []){ ff_voc_codec_tags, 0 },
175 };
176 #endif /* CONFIG_VOC_DEMUXER */