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