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