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
int64_t
duration
;
75
int
ret
;
76
77
av_add_index_entry
(st,
78
avio_tell
(pb),
79
voc->
pts
,
80
voc->
remaining_size
,
81
0,
82
AVINDEX_KEYFRAME
);
83
84
while
(!voc->
remaining_size
) {
85
type =
avio_r8
(pb);
86
if
(type ==
VOC_TYPE_EOF
)
87
return
AVERROR_EOF
;
88
voc->
remaining_size
=
avio_rl24
(pb);
89
if
(!voc->
remaining_size
) {
90
if
(!s->
pb
->
seekable
)
91
return
AVERROR
(EIO);
92
voc->
remaining_size
=
avio_size
(pb) -
avio_tell
(pb);
93
}
94
max_size -= 4;
95
96
switch
(type) {
97
case
VOC_TYPE_VOICE_DATA
:
98
if
(!dec->
sample_rate
) {
99
dec->
sample_rate
= 1000000 / (256 -
avio_r8
(pb));
100
if
(sample_rate)
101
dec->
sample_rate
=
sample_rate
;
102
avpriv_set_pts_info
(st, 64, 1, dec->
sample_rate
);
103
dec->
channels
= channels;
104
dec->
bits_per_coded_sample
=
av_get_bits_per_sample
(dec->
codec_id
);
105
}
else
106
avio_skip
(pb, 1);
107
tmp_codec =
avio_r8
(pb);
108
voc->
remaining_size
-= 2;
109
max_size -= 2;
110
channels = 1;
111
break
;
112
113
case
VOC_TYPE_VOICE_DATA_CONT
:
114
break
;
115
116
case
VOC_TYPE_EXTENDED
:
117
sample_rate =
avio_rl16
(pb);
118
avio_r8
(pb);
119
channels =
avio_r8
(pb) + 1;
120
sample_rate = 256000000 / (channels * (65536 -
sample_rate
));
121
voc->
remaining_size
= 0;
122
max_size -= 4;
123
break
;
124
125
case
VOC_TYPE_NEW_VOICE_DATA
:
126
if
(!dec->
sample_rate
) {
127
dec->
sample_rate
=
avio_rl32
(pb);
128
avpriv_set_pts_info
(st, 64, 1, dec->
sample_rate
);
129
dec->
bits_per_coded_sample
=
avio_r8
(pb);
130
dec->
channels
=
avio_r8
(pb);
131
}
else
132
avio_skip
(pb, 6);
133
tmp_codec =
avio_rl16
(pb);
134
avio_skip
(pb, 4);
135
voc->
remaining_size
-= 12;
136
max_size -= 12;
137
break
;
138
139
default
:
140
avio_skip
(pb, voc->
remaining_size
);
141
max_size -= voc->
remaining_size
;
142
voc->
remaining_size
= 0;
143
break
;
144
}
145
}
146
147
if
(tmp_codec >= 0) {
148
tmp_codec =
ff_codec_get_id
(
ff_voc_codec_tags
, tmp_codec);
149
if
(dec->
codec_id
==
AV_CODEC_ID_NONE
)
150
dec->
codec_id
= tmp_codec;
151
else
if
(dec->
codec_id
!= tmp_codec)
152
av_log
(s,
AV_LOG_WARNING
,
"Ignoring mid-stream change in audio codec\n"
);
153
if
(dec->
codec_id
==
AV_CODEC_ID_NONE
) {
154
if
(s->
audio_codec_id
==
AV_CODEC_ID_NONE
) {
155
av_log
(s,
AV_LOG_ERROR
,
"unknown codec tag\n"
);
156
return
AVERROR
(EINVAL);
157
}
158
av_log
(s,
AV_LOG_WARNING
,
"unknown codec tag\n"
);
159
}
160
}
161
162
dec->
bit_rate
= dec->
sample_rate
* dec->
channels
* dec->
bits_per_coded_sample
;
163
164
if
(max_size <= 0)
165
max_size = 2048;
166
size =
FFMIN
(voc->
remaining_size
, max_size);
167
voc->
remaining_size
-=
size
;
168
169
ret =
av_get_packet
(pb, pkt, size);
170
pkt->
dts
= pkt->
pts
= voc->
pts
;
171
172
duration =
av_get_audio_frame_duration
(st->
codec
, size);
173
if
(duration > 0 && voc->
pts
!=
AV_NOPTS_VALUE
)
174
voc->
pts
+=
duration
;
175
else
176
voc->
pts
=
AV_NOPTS_VALUE
;
177
178
return
ret
;
179
}
180
181
static
int
voc_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
182
{
183
return
ff_voc_get_packet
(s, pkt, s->
streams
[0], 0);
184
}
185
186
static
int
voc_read_seek
(
AVFormatContext
*
s
,
int
stream_index,
187
int64_t timestamp,
int
flags
)
188
{
189
VocDecContext
*voc = s->
priv_data
;
190
AVStream
*st = s->
streams
[stream_index];
191
int
index
=
av_index_search_timestamp
(st, timestamp, flags);
192
193
if
(index >= 0 && index < st->nb_index_entries - 1) {
194
AVIndexEntry
*e = &st->
index_entries
[
index
];
195
avio_seek
(s->
pb
, e->
pos
, SEEK_SET);
196
voc->
pts
= e->
timestamp
;
197
voc->
remaining_size
= e->
size
;
198
return
0;
199
}
else
if
(st->
nb_index_entries
&& st->
index_entries
[0].
timestamp
<= timestamp) {
200
AVIndexEntry
*e = &st->
index_entries
[st->
nb_index_entries
- 1];
201
// prepare context for seek_frame_generic()
202
voc->
pts
= e->
timestamp
;
203
voc->
remaining_size
= e->
size
;
204
}
205
return
-1;
206
}
207
208
AVInputFormat
ff_voc_demuxer
= {
209
.
name
=
"voc"
,
210
.long_name =
NULL_IF_CONFIG_SMALL
(
"Creative Voice"
),
211
.priv_data_size =
sizeof
(
VocDecContext
),
212
.
read_probe
=
voc_probe
,
213
.
read_header
=
voc_read_header
,
214
.
read_packet
=
voc_read_packet
,
215
.
read_seek
=
voc_read_seek
,
216
.codec_tag = (
const
AVCodecTag
*
const
[]){
ff_voc_codec_tags
, 0 },
217
};
Generated on Sun Mar 8 2015 02:35:13 for FFmpeg by
1.8.2