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 03:58:49 for FFmpeg by
1.8.2