annotate vocdec.c @ 5504:e15a959963f1 libavformat

handler can be NULL if we did not support this dynamic format (codec). Fixes issue 1658 (the crasher), although the format itself is obviously still unsupported.
author rbultje
date Thu, 07 Jan 2010 23:05:19 +0000
parents 3528d151a57e
children 536e5527c1e0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
1 /*
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
2 * Creative Voice File demuxer.
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
3 * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
4 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
5 * This file is part of FFmpeg.
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
6 *
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
11 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
15 * Lesser General Public License for more details.
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
16 *
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1172
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
2217
06083249909c license header consistency cosmetics
diego
parents: 2187
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
20 */
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
21
4201
7d2f3f1b68d8 Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents: 4081
diff changeset
22 #include "libavutil/intreadwrite.h"
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
23 #include "voc.h"
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
24
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
25
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
26 static int voc_probe(AVProbeData *p)
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
27 {
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
28 int version, check;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
29
3764
9cff515fd4c6 voc: add ff_ prefix to some global const data
aurel
parents: 3424
diff changeset
30 if (memcmp(p->buf, ff_voc_magic, sizeof(ff_voc_magic) - 1))
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
31 return 0;
2184
38dd9318e1a6 use intreadwrite functions in vocdec
aurel
parents: 2001
diff changeset
32 version = AV_RL16(p->buf + 22);
38dd9318e1a6 use intreadwrite functions in vocdec
aurel
parents: 2001
diff changeset
33 check = AV_RL16(p->buf + 24);
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
34 if (~version + 0x1234 != check)
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
35 return 10;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
36
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
37 return AVPROBE_SCORE_MAX;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
38 }
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
39
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
40 static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap)
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
41 {
4081
3d6e7901bf05 avoid POSIX reserved _t suffix
aurel
parents: 3908
diff changeset
42 VocDecContext *voc = s->priv_data;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2276
diff changeset
43 ByteIOContext *pb = s->pb;
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
44 int header_size;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
45 AVStream *st;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
46
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
47 url_fskip(pb, 20);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
48 header_size = get_le16(pb) - 22;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
49 if (header_size != 4) {
1883
a6cf9ee93fbb typo: unkown->unknown
alex
parents: 1679
diff changeset
50 av_log(s, AV_LOG_ERROR, "unknown header size: %d\n", header_size);
2276
3c1e2d519277 Replace all occurrences of AVERROR_NOTSUPP with AVERROR(ENOSYS).
takis
parents: 2274
diff changeset
51 return AVERROR(ENOSYS);
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
52 }
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
53 url_fskip(pb, header_size);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
54 st = av_new_stream(s, 0);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
55 if (!st)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2217
diff changeset
56 return AVERROR(ENOMEM);
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
57 st->codec->codec_type = CODEC_TYPE_AUDIO;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
58
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
59 voc->remaining_size = 0;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
60 return 0;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
61 }
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
62
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
63 int
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
64 voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
65 {
4081
3d6e7901bf05 avoid POSIX reserved _t suffix
aurel
parents: 3908
diff changeset
66 VocDecContext *voc = s->priv_data;
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
67 AVCodecContext *dec = st->codec;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2276
diff changeset
68 ByteIOContext *pb = s->pb;
4081
3d6e7901bf05 avoid POSIX reserved _t suffix
aurel
parents: 3908
diff changeset
69 VocType type;
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
70 int size;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
71 int sample_rate = 0;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
72 int channels = 1;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
73
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
74 while (!voc->remaining_size) {
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
75 type = get_byte(pb);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
76 if (type == VOC_TYPE_EOF)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
77 return AVERROR(EIO);
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
78 voc->remaining_size = get_le24(pb);
5384
3528d151a57e Determine VOC block length when length field is zero, fixes issue1538.
pross
parents: 5058
diff changeset
79 if (!voc->remaining_size) {
3528d151a57e Determine VOC block length when length field is zero, fixes issue1538.
pross
parents: 5058
diff changeset
80 if (url_is_streamed(s->pb))
3528d151a57e Determine VOC block length when length field is zero, fixes issue1538.
pross
parents: 5058
diff changeset
81 return AVERROR(EIO);
3528d151a57e Determine VOC block length when length field is zero, fixes issue1538.
pross
parents: 5058
diff changeset
82 voc->remaining_size = url_fsize(pb) - url_ftell(pb);
3528d151a57e Determine VOC block length when length field is zero, fixes issue1538.
pross
parents: 5058
diff changeset
83 }
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
84 max_size -= 4;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
85
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
86 switch (type) {
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
87 case VOC_TYPE_VOICE_DATA:
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
88 dec->sample_rate = 1000000 / (256 - get_byte(pb));
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
89 if (sample_rate)
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
90 dec->sample_rate = sample_rate;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
91 dec->channels = channels;
5058
33a244b7ca65 Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents: 4201
diff changeset
92 dec->codec_id = ff_codec_get_id(ff_voc_codec_tags, get_byte(pb));
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3766
diff changeset
93 dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id);
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
94 voc->remaining_size -= 2;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
95 max_size -= 2;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
96 channels = 1;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
97 break;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
98
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
99 case VOC_TYPE_VOICE_DATA_CONT:
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
100 break;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
101
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
102 case VOC_TYPE_EXTENDED:
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
103 sample_rate = get_le16(pb);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
104 get_byte(pb);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
105 channels = get_byte(pb) + 1;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
106 sample_rate = 256000000 / (channels * (65536 - sample_rate));
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
107 voc->remaining_size = 0;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
108 max_size -= 4;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
109 break;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
110
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
111 case VOC_TYPE_NEW_VOICE_DATA:
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
112 dec->sample_rate = get_le32(pb);
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3766
diff changeset
113 dec->bits_per_coded_sample = get_byte(pb);
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
114 dec->channels = get_byte(pb);
5058
33a244b7ca65 Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents: 4201
diff changeset
115 dec->codec_id = ff_codec_get_id(ff_voc_codec_tags, get_le16(pb));
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
116 url_fskip(pb, 4);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
117 voc->remaining_size -= 12;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
118 max_size -= 12;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
119 break;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
120
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
121 default:
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
122 url_fskip(pb, voc->remaining_size);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
123 max_size -= voc->remaining_size;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
124 voc->remaining_size = 0;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
125 break;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
126 }
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
127 }
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
128
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3766
diff changeset
129 dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample;
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
130
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
131 if (max_size <= 0)
1884
1792b6c5387b simplification
alex
parents: 1883
diff changeset
132 max_size = 2048;
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
133 size = FFMIN(voc->remaining_size, max_size);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
134 voc->remaining_size -= size;
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
135 return av_get_packet(pb, pkt, size);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
136 }
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
137
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
138 static int voc_read_packet(AVFormatContext *s, AVPacket *pkt)
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
139 {
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
140 return voc_get_packet(s, pkt, s->streams[0], 0);
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
141 }
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
142
1169
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
143 AVInputFormat voc_demuxer = {
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
144 "voc",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 2771
diff changeset
145 NULL_IF_CONFIG_SMALL("Creative Voice file format"),
4081
3d6e7901bf05 avoid POSIX reserved _t suffix
aurel
parents: 3908
diff changeset
146 sizeof(VocDecContext),
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
147 voc_probe,
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
148 voc_read_header,
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
149 voc_read_packet,
3766
f062deeedb8d Change codec_tag type from const struct AVCodecTag ** to const struct AVCodecTag * const *
reimar
parents: 3764
diff changeset
150 .codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0},
937
a887adfe9dc5 add a Creative VOC (de)muxer
aurel
parents:
diff changeset
151 };