Mercurial > libavformat.hg
annotate vocdec.c @ 3962:72efef66f566 libavformat
This patch refactors RDT packet header parsing so that it can be used in
rtsp.c to detect the ID of the packet source also in case of TCP streams.
This allows proper playback of RDT streams with multiple stream types, e.g.
audio + video. Accepted by LucaB in "RDT/Realmedia patches #2" thread on ML.
author | rbultje |
---|---|
date | Wed, 01 Oct 2008 12:37:07 +0000 |
parents | 1d3d17de20ba |
children | 3d6e7901bf05 |
rev | line source |
---|---|
937 | 1 /* |
2 * Creative Voice File demuxer. | |
3 * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org> | |
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 | 8 * modify it under the terms of the GNU Lesser General Public |
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 | 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 | 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 | |
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 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
937 | 20 */ |
21 | |
22 #include "voc.h" | |
23 | |
24 | |
25 static int voc_probe(AVProbeData *p) | |
26 { | |
27 int version, check; | |
28 | |
3764 | 29 if (memcmp(p->buf, ff_voc_magic, sizeof(ff_voc_magic) - 1)) |
937 | 30 return 0; |
2184 | 31 version = AV_RL16(p->buf + 22); |
32 check = AV_RL16(p->buf + 24); | |
937 | 33 if (~version + 0x1234 != check) |
34 return 10; | |
35 | |
36 return AVPROBE_SCORE_MAX; | |
37 } | |
38 | |
39 static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap) | |
40 { | |
41 voc_dec_context_t *voc = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2276
diff
changeset
|
42 ByteIOContext *pb = s->pb; |
937 | 43 int header_size; |
44 AVStream *st; | |
45 | |
46 url_fskip(pb, 20); | |
47 header_size = get_le16(pb) - 22; | |
48 if (header_size != 4) { | |
1883 | 49 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
|
50 return AVERROR(ENOSYS); |
937 | 51 } |
52 url_fskip(pb, header_size); | |
53 st = av_new_stream(s, 0); | |
54 if (!st) | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2217
diff
changeset
|
55 return AVERROR(ENOMEM); |
937 | 56 st->codec->codec_type = CODEC_TYPE_AUDIO; |
57 | |
58 voc->remaining_size = 0; | |
59 return 0; | |
60 } | |
61 | |
62 int | |
63 voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) | |
64 { | |
65 voc_dec_context_t *voc = s->priv_data; | |
66 AVCodecContext *dec = st->codec; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2276
diff
changeset
|
67 ByteIOContext *pb = s->pb; |
937 | 68 voc_type_t type; |
69 int size; | |
70 int sample_rate = 0; | |
71 int channels = 1; | |
72 | |
73 while (!voc->remaining_size) { | |
74 type = get_byte(pb); | |
75 if (type == VOC_TYPE_EOF) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
76 return AVERROR(EIO); |
937 | 77 voc->remaining_size = get_le24(pb); |
78 max_size -= 4; | |
79 | |
80 switch (type) { | |
81 case VOC_TYPE_VOICE_DATA: | |
82 dec->sample_rate = 1000000 / (256 - get_byte(pb)); | |
83 if (sample_rate) | |
84 dec->sample_rate = sample_rate; | |
85 dec->channels = channels; | |
3764 | 86 dec->codec_id = 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
|
87 dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); |
937 | 88 voc->remaining_size -= 2; |
89 max_size -= 2; | |
90 channels = 1; | |
91 break; | |
92 | |
93 case VOC_TYPE_VOICE_DATA_CONT: | |
94 break; | |
95 | |
96 case VOC_TYPE_EXTENDED: | |
97 sample_rate = get_le16(pb); | |
98 get_byte(pb); | |
99 channels = get_byte(pb) + 1; | |
100 sample_rate = 256000000 / (channels * (65536 - sample_rate)); | |
101 voc->remaining_size = 0; | |
102 max_size -= 4; | |
103 break; | |
104 | |
105 case VOC_TYPE_NEW_VOICE_DATA: | |
106 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
|
107 dec->bits_per_coded_sample = get_byte(pb); |
937 | 108 dec->channels = get_byte(pb); |
3764 | 109 dec->codec_id = codec_get_id(ff_voc_codec_tags, get_le16(pb)); |
937 | 110 url_fskip(pb, 4); |
111 voc->remaining_size -= 12; | |
112 max_size -= 12; | |
113 break; | |
114 | |
115 default: | |
116 url_fskip(pb, voc->remaining_size); | |
117 max_size -= voc->remaining_size; | |
118 voc->remaining_size = 0; | |
119 break; | |
120 } | |
121 } | |
122 | |
3908
1d3d17de20ba
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
3766
diff
changeset
|
123 dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample; |
937 | 124 |
125 if (max_size <= 0) | |
1884 | 126 max_size = 2048; |
937 | 127 size = FFMIN(voc->remaining_size, max_size); |
128 voc->remaining_size -= size; | |
129 return av_get_packet(pb, pkt, size); | |
130 } | |
131 | |
132 static int voc_read_packet(AVFormatContext *s, AVPacket *pkt) | |
133 { | |
134 return voc_get_packet(s, pkt, s->streams[0], 0); | |
135 } | |
136 | |
1169 | 137 AVInputFormat voc_demuxer = { |
937 | 138 "voc", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
2771
diff
changeset
|
139 NULL_IF_CONFIG_SMALL("Creative Voice file format"), |
937 | 140 sizeof(voc_dec_context_t), |
141 voc_probe, | |
142 voc_read_header, | |
143 voc_read_packet, | |
3766
f062deeedb8d
Change codec_tag type from const struct AVCodecTag ** to const struct AVCodecTag * const *
reimar
parents:
3764
diff
changeset
|
144 .codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0}, |
937 | 145 }; |