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