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
vqf.c
Go to the documentation of this file.
1
/*
2
* VQF demuxer
3
* Copyright (c) 2009 Vitor Sessak
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 "
avformat.h
"
23
#include "
internal.h
"
24
#include "
libavutil/intreadwrite.h
"
25
#include "
libavutil/dict.h
"
26
#include "
libavutil/mathematics.h
"
27
#include "
riff.h
"
28
29
typedef
struct
VqfContext
{
30
int
frame_bit_len
;
31
uint8_t
last_frame_bits
;
32
int
remaining_bits
;
33
}
VqfContext
;
34
35
static
int
vqf_probe
(
AVProbeData
*probe_packet)
36
{
37
if
(
AV_RL32
(probe_packet->
buf
) !=
MKTAG
(
'T'
,
'W'
,
'I'
,
'N'
))
38
return
0;
39
40
if
(!memcmp(probe_packet->
buf
+ 4,
"97012000"
, 8))
41
return
AVPROBE_SCORE_MAX
;
42
43
if
(!memcmp(probe_packet->
buf
+ 4,
"00052200"
, 8))
44
return
AVPROBE_SCORE_MAX
;
45
46
if
(
AV_RL32
(probe_packet->
buf
+ 12) > (1<<27))
47
return
AVPROBE_SCORE_EXTENSION
/2;
48
49
return
AVPROBE_SCORE_EXTENSION
;
50
}
51
52
static
void
add_metadata
(
AVFormatContext
*
s
, uint32_t
tag
,
53
unsigned
int
tag_len,
unsigned
int
remaining)
54
{
55
int
len
=
FFMIN
(tag_len, remaining);
56
char
*
buf
, key[5] = {0};
57
58
if
(len == UINT_MAX)
59
return
;
60
61
buf =
av_malloc
(len+1);
62
if
(!buf)
63
return
;
64
avio_read
(s->
pb
, buf, len);
65
buf[
len
] = 0;
66
AV_WL32
(key, tag);
67
av_dict_set
(&s->
metadata
, key, buf,
AV_DICT_DONT_STRDUP_VAL
);
68
}
69
70
static
const
AVMetadataConv
vqf_metadata_conv
[] = {
71
{
"(c) "
,
"copyright"
},
72
{
"ARNG"
,
"arranger"
},
73
{
"AUTH"
,
"author"
},
74
{
"BAND"
,
"band"
},
75
{
"CDCT"
,
"conductor"
},
76
{
"COMT"
,
"comment"
},
77
{
"FILE"
,
"filename"
},
78
{
"GENR"
,
"genre"
},
79
{
"LABL"
,
"publisher"
},
80
{
"MUSC"
,
"composer"
},
81
{
"NAME"
,
"title"
},
82
{
"NOTE"
,
"note"
},
83
{
"PROD"
,
"producer"
},
84
{
"PRSN"
,
"personnel"
},
85
{
"REMX"
,
"remixer"
},
86
{
"SING"
,
"singer"
},
87
{
"TRCK"
,
"track"
},
88
{
"WORD"
,
"words"
},
89
{ 0 },
90
};
91
92
static
int
vqf_read_header
(
AVFormatContext
*
s
)
93
{
94
VqfContext
*
c
= s->
priv_data
;
95
AVStream
*st =
avformat_new_stream
(s,
NULL
);
96
int
chunk_tag;
97
int
rate_flag = -1;
98
int
header_size;
99
int
read_bitrate = 0;
100
int
size
;
101
uint8_t
comm_chunk[12];
102
103
if
(!st)
104
return
AVERROR
(ENOMEM);
105
106
avio_skip
(s->
pb
, 12);
107
108
header_size =
avio_rb32
(s->
pb
);
109
110
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
111
st->
codec
->
codec_id
=
AV_CODEC_ID_TWINVQ
;
112
st->
start_time
= 0;
113
114
do
{
115
int
len
;
116
chunk_tag =
avio_rl32
(s->
pb
);
117
118
if
(chunk_tag ==
MKTAG
(
'D'
,
'A'
,
'T'
,
'A'
))
119
break
;
120
121
len =
avio_rb32
(s->
pb
);
122
123
if
((
unsigned
) len > INT_MAX/2) {
124
av_log
(s,
AV_LOG_ERROR
,
"Malformed header\n"
);
125
return
-1;
126
}
127
128
header_size -= 8;
129
130
switch
(chunk_tag){
131
case
MKTAG
(
'C'
,
'O'
,
'M'
,
'M'
):
132
avio_read
(s->
pb
, comm_chunk, 12);
133
st->
codec
->
channels
=
AV_RB32
(comm_chunk ) + 1;
134
read_bitrate =
AV_RB32
(comm_chunk + 4);
135
rate_flag =
AV_RB32
(comm_chunk + 8);
136
avio_skip
(s->
pb
, len-12);
137
138
if
(st->
codec
->
channels
<= 0) {
139
av_log
(s,
AV_LOG_ERROR
,
"Invalid number of channels\n"
);
140
return
AVERROR_INVALIDDATA
;
141
}
142
143
st->
codec
->
bit_rate
= read_bitrate*1000;
144
break
;
145
case
MKTAG
(
'D'
,
'S'
,
'I'
,
'Z'
):
// size of compressed data
146
{
147
av_dict_set_int
(&s->
metadata
,
"size"
,
avio_rb32
(s->
pb
), 0);
148
}
149
break
;
150
case
MKTAG
(
'Y'
,
'E'
,
'A'
,
'R'
):
// recording date
151
case
MKTAG
(
'E'
,
'N'
,
'C'
,
'D'
):
// compression date
152
case
MKTAG
(
'E'
,
'X'
,
'T'
,
'R'
):
// reserved
153
case
MKTAG
(
'_'
,
'Y'
,
'M'
,
'H'
):
// reserved
154
case
MKTAG
(
'_'
,
'N'
,
'T'
,
'T'
):
// reserved
155
case
MKTAG
(
'_'
,
'I'
,
'D'
,
'3'
):
// reserved for ID3 tags
156
avio_skip
(s->
pb
,
FFMIN
(len, header_size));
157
break
;
158
default
:
159
add_metadata
(s, chunk_tag, len, header_size);
160
break
;
161
}
162
163
header_size -=
len
;
164
165
}
while
(header_size >= 0 && !
avio_feof
(s->
pb
));
166
167
switch
(rate_flag) {
168
case
-1:
169
av_log
(s,
AV_LOG_ERROR
,
"COMM tag not found!\n"
);
170
return
-1;
171
case
44:
172
st->
codec
->
sample_rate
= 44100;
173
break
;
174
case
22:
175
st->
codec
->
sample_rate
= 22050;
176
break
;
177
case
11:
178
st->
codec
->
sample_rate
= 11025;
179
break
;
180
default
:
181
if
(rate_flag < 8 || rate_flag > 44) {
182
av_log
(s,
AV_LOG_ERROR
,
"Invalid rate flag %d\n"
, rate_flag);
183
return
AVERROR_INVALIDDATA
;
184
}
185
st->
codec
->
sample_rate
= rate_flag*1000;
186
break
;
187
}
188
189
if
(read_bitrate / st->
codec
->
channels
< 8 ||
190
read_bitrate / st->
codec
->
channels
> 48) {
191
av_log
(s,
AV_LOG_ERROR
,
"Invalid bitrate per channel %d\n"
,
192
read_bitrate / st->
codec
->
channels
);
193
return
AVERROR_INVALIDDATA
;
194
}
195
196
switch
(((st->
codec
->
sample_rate
/1000) << 8) +
197
read_bitrate/st->
codec
->
channels
) {
198
case
(11<<8) + 8 :
199
case
(8 <<8) + 8 :
200
case
(11<<8) + 10:
201
case
(22<<8) + 32:
202
size = 512;
203
break
;
204
case
(16<<8) + 16:
205
case
(22<<8) + 20:
206
case
(22<<8) + 24:
207
size = 1024;
208
break
;
209
case
(44<<8) + 40:
210
case
(44<<8) + 48:
211
size = 2048;
212
break
;
213
default
:
214
av_log
(s,
AV_LOG_ERROR
,
"Mode not suported: %d Hz, %d kb/s.\n"
,
215
st->
codec
->
sample_rate
, st->
codec
->
bit_rate
);
216
return
-1;
217
}
218
c->
frame_bit_len
= st->
codec
->
bit_rate
*size/st->
codec
->
sample_rate
;
219
avpriv_set_pts_info
(st, 64, size, st->
codec
->
sample_rate
);
220
221
/* put first 12 bytes of COMM chunk in extradata */
222
if
(
ff_alloc_extradata
(st->
codec
, 12))
223
return
AVERROR
(ENOMEM);
224
memcpy(st->
codec
->
extradata
, comm_chunk, 12);
225
226
ff_metadata_conv_ctx
(s,
NULL
, vqf_metadata_conv);
227
228
return
0;
229
}
230
231
static
int
vqf_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
232
{
233
VqfContext
*
c
= s->
priv_data
;
234
int
ret
;
235
int
size
= (c->
frame_bit_len
- c->
remaining_bits
+ 7)>>3;
236
237
if
(
av_new_packet
(pkt, size+2) < 0)
238
return
AVERROR
(EIO);
239
240
pkt->
pos
=
avio_tell
(s->
pb
);
241
pkt->
stream_index
= 0;
242
pkt->
duration
= 1;
243
244
pkt->
data
[0] = 8 - c->
remaining_bits
;
// Number of bits to skip
245
pkt->
data
[1] = c->
last_frame_bits
;
246
ret =
avio_read
(s->
pb
, pkt->
data
+2, size);
247
248
if
(ret != size) {
249
av_free_packet
(pkt);
250
return
AVERROR
(EIO);
251
}
252
253
c->
last_frame_bits
= pkt->
data
[size+1];
254
c->
remaining_bits
= (size << 3) - c->
frame_bit_len
+ c->
remaining_bits
;
255
256
return
size+2;
257
}
258
259
static
int
vqf_read_seek
(
AVFormatContext
*
s
,
260
int
stream_index, int64_t timestamp,
int
flags
)
261
{
262
VqfContext
*
c
= s->
priv_data
;
263
AVStream
*st;
264
int64_t
ret
;
265
int64_t pos;
266
267
st = s->
streams
[stream_index];
268
pos =
av_rescale_rnd
(timestamp * st->
codec
->
bit_rate
,
269
st->
time_base
.
num
,
270
st->
time_base
.
den
* (int64_t)c->
frame_bit_len
,
271
(flags &
AVSEEK_FLAG_BACKWARD
) ?
272
AV_ROUND_DOWN
:
AV_ROUND_UP
);
273
pos *= c->
frame_bit_len
;
274
275
st->
cur_dts
=
av_rescale
(pos, st->
time_base
.
den
,
276
st->
codec
->
bit_rate
* (int64_t)st->
time_base
.
num
);
277
278
if
((ret =
avio_seek
(s->
pb
, ((pos-7) >> 3) + s->
internal
->
data_offset
, SEEK_SET)) < 0)
279
return
ret
;
280
281
c->
remaining_bits
= -7 - ((pos-7)&7);
282
return
0;
283
}
284
285
AVInputFormat
ff_vqf_demuxer
= {
286
.
name
=
"vqf"
,
287
.long_name =
NULL_IF_CONFIG_SMALL
(
"Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"
),
288
.priv_data_size =
sizeof
(
VqfContext
),
289
.
read_probe
=
vqf_probe
,
290
.
read_header
=
vqf_read_header
,
291
.
read_packet
=
vqf_read_packet
,
292
.
read_seek
=
vqf_read_seek
,
293
.extensions =
"vqf,vql,vqe"
,
294
};
Generated on Sun Mar 8 2015 02:35:13 for FFmpeg by
1.8.2