]> git.sesse.net Git - ffmpeg/blob - libavformat/vocdec.c
85d304dff8773653f7f316e5d8e26afffc72cd18
[ffmpeg] / 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 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 St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "voc.h"
23
24
25
26
27 static int voc_probe(AVProbeData *p)
28 {
29     int version, check;
30
31     if (p->buf_size < 26)
32         return 0;
33     if (memcmp(p->buf, voc_magic, sizeof(voc_magic) - 1))
34         return 0;
35     version = p->buf[22] | (p->buf[23] << 8);
36     check = p->buf[24] | (p->buf[25] << 8);
37     if (~version + 0x1234 != check)
38         return 10;
39
40     return AVPROBE_SCORE_MAX;
41 }
42
43 static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap)
44 {
45     voc_dec_context_t *voc = s->priv_data;
46     ByteIOContext *pb = &s->pb;
47     int header_size;
48     AVStream *st;
49
50     url_fskip(pb, 20);
51     header_size = get_le16(pb) - 22;
52     if (header_size != 4) {
53         av_log(s, AV_LOG_ERROR, "unknown header size: %d\n", header_size);
54         return AVERROR_NOTSUPP;
55     }
56     url_fskip(pb, header_size);
57     st = av_new_stream(s, 0);
58     if (!st)
59         return AVERROR_NOMEM;
60     st->codec->codec_type = CODEC_TYPE_AUDIO;
61
62     voc->remaining_size = 0;
63     return 0;
64 }
65
66 int
67 voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
68 {
69     voc_dec_context_t *voc = s->priv_data;
70     AVCodecContext *dec = st->codec;
71     ByteIOContext *pb = &s->pb;
72     voc_type_t type;
73     int size;
74     int sample_rate = 0;
75     int channels = 1;
76
77     while (!voc->remaining_size) {
78         type = get_byte(pb);
79         if (type == VOC_TYPE_EOF)
80             return AVERROR_IO;
81         voc->remaining_size = get_le24(pb);
82         max_size -= 4;
83
84         switch (type) {
85         case VOC_TYPE_VOICE_DATA:
86             dec->sample_rate = 1000000 / (256 - get_byte(pb));
87             if (sample_rate)
88                 dec->sample_rate = sample_rate;
89             dec->channels = channels;
90             dec->codec_id = codec_get_id(voc_codec_tags, get_byte(pb));
91             dec->bits_per_sample = av_get_bits_per_sample(dec->codec_id);
92             voc->remaining_size -= 2;
93             max_size -= 2;
94             channels = 1;
95             break;
96
97         case VOC_TYPE_VOICE_DATA_CONT:
98             break;
99
100         case VOC_TYPE_EXTENDED:
101             sample_rate = get_le16(pb);
102             get_byte(pb);
103             channels = get_byte(pb) + 1;
104             sample_rate = 256000000 / (channels * (65536 - sample_rate));
105             voc->remaining_size = 0;
106             max_size -= 4;
107             break;
108
109         case VOC_TYPE_NEW_VOICE_DATA:
110             dec->sample_rate = get_le32(pb);
111             dec->bits_per_sample = get_byte(pb);
112             dec->channels = get_byte(pb);
113             dec->codec_id = codec_get_id(voc_codec_tags, get_le16(pb));
114             url_fskip(pb, 4);
115             voc->remaining_size -= 12;
116             max_size -= 12;
117             break;
118
119         default:
120             url_fskip(pb, voc->remaining_size);
121             max_size -= voc->remaining_size;
122             voc->remaining_size = 0;
123             break;
124         }
125     }
126
127     dec->bit_rate = dec->sample_rate * dec->bits_per_sample;
128
129     if (max_size <= 0)
130         max_size = 2048;
131     size = FFMIN(voc->remaining_size, max_size);
132     voc->remaining_size -= size;
133     return av_get_packet(pb, pkt, size);
134 }
135
136 static int voc_read_packet(AVFormatContext *s, AVPacket *pkt)
137 {
138     return voc_get_packet(s, pkt, s->streams[0], 0);
139 }
140
141 static int voc_read_close(AVFormatContext *s)
142 {
143     return 0;
144 }
145
146 AVInputFormat voc_demuxer = {
147     "voc",
148     "Creative Voice File format",
149     sizeof(voc_dec_context_t),
150     voc_probe,
151     voc_read_header,
152     voc_read_packet,
153     voc_read_close,
154     .codec_tag=(const AVCodecTag*[]){voc_codec_tags, 0},
155 };