FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 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 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
)
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
ff_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_EOF
;
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
if
(!dec->
sample_rate
) {
90
dec->
sample_rate
= 1000000 / (256 -
avio_r8
(pb));
91
if
(sample_rate)
92
dec->
sample_rate
=
sample_rate
;
93
avpriv_set_pts_info
(st, 64, 1, dec->
sample_rate
);
94
dec->
channels
= channels;
95
dec->
bits_per_coded_sample
=
av_get_bits_per_sample
(dec->
codec_id
);
96
}
else
97
avio_skip
(pb, 1);
98
tmp_codec =
avio_r8
(pb);
99
voc->
remaining_size
-= 2;
100
max_size -= 2;
101
channels = 1;
102
break
;
103
104
case
VOC_TYPE_VOICE_DATA_CONT
:
105
break
;
106
107
case
VOC_TYPE_EXTENDED
:
108
sample_rate =
avio_rl16
(pb);
109
avio_r8
(pb);
110
channels =
avio_r8
(pb) + 1;
111
sample_rate = 256000000 / (channels * (65536 -
sample_rate
));
112
voc->
remaining_size
= 0;
113
max_size -= 4;
114
break
;
115
116
case
VOC_TYPE_NEW_VOICE_DATA
:
117
if
(!dec->
sample_rate
) {
118
dec->
sample_rate
=
avio_rl32
(pb);
119
avpriv_set_pts_info
(st, 64, 1, dec->
sample_rate
);
120
dec->
bits_per_coded_sample
=
avio_r8
(pb);
121
dec->
channels
=
avio_r8
(pb);
122
}
else
123
avio_skip
(pb, 6);
124
tmp_codec =
avio_rl16
(pb);
125
avio_skip
(pb, 4);
126
voc->
remaining_size
-= 12;
127
max_size -= 12;
128
break
;
129
130
default
:
131
avio_skip
(pb, voc->
remaining_size
);
132
max_size -= voc->
remaining_size
;
133
voc->
remaining_size
= 0;
134
break
;
135
}
136
}
137
138
if
(tmp_codec >= 0) {
139
tmp_codec =
ff_codec_get_id
(
ff_voc_codec_tags
, tmp_codec);
140
if
(dec->
codec_id
==
AV_CODEC_ID_NONE
)
141
dec->
codec_id
= tmp_codec;
142
else
if
(dec->
codec_id
!= tmp_codec)
143
av_log
(s,
AV_LOG_WARNING
,
"Ignoring mid-stream change in audio codec\n"
);
144
if
(dec->
codec_id
==
AV_CODEC_ID_NONE
) {
145
if
(s->
audio_codec_id
==
AV_CODEC_ID_NONE
) {
146
av_log
(s,
AV_LOG_ERROR
,
"unknown codec tag\n"
);
147
return
AVERROR
(EINVAL);
148
}
149
av_log
(s,
AV_LOG_WARNING
,
"unknown codec tag\n"
);
150
}
151
}
152
153
dec->
bit_rate
= dec->
sample_rate
* dec->
channels
* dec->
bits_per_coded_sample
;
154
155
if
(max_size <= 0)
156
max_size = 2048;
157
size =
FFMIN
(voc->
remaining_size
, max_size);
158
voc->
remaining_size
-=
size
;
159
return
av_get_packet
(pb, pkt, size);
160
}
161
162
static
int
voc_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
163
{
164
return
ff_voc_get_packet
(s, pkt, s->
streams
[0], 0);
165
}
166
167
AVInputFormat
ff_voc_demuxer
= {
168
.
name
=
"voc"
,
169
.long_name =
NULL_IF_CONFIG_SMALL
(
"Creative Voice"
),
170
.priv_data_size =
sizeof
(
VocDecContext
),
171
.
read_probe
=
voc_probe
,
172
.
read_header
=
voc_read_header
,
173
.
read_packet
=
voc_read_packet
,
174
.codec_tag = (
const
AVCodecTag
*
const
[]){
ff_voc_codec_tags
, 0 },
175
};
Generated on Sun Mar 23 2014 23:50:14 for FFmpeg by
1.8.2