3 * Copyright (c) 2009 Vitor Sessak
5 * This file is part of Libav.
7 * Libav 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.
12 * Libav 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/dict.h"
25 #include "libavutil/mathematics.h"
27 typedef struct VqfContext
{
29 uint8_t last_frame_bits
;
33 static int vqf_probe(AVProbeData
*probe_packet
)
35 if (AV_RL32(probe_packet
->buf
) != MKTAG('T','W','I','N'))
38 if (!memcmp(probe_packet
->buf
+ 4, "97012000", 8))
39 return AVPROBE_SCORE_MAX
;
41 if (!memcmp(probe_packet
->buf
+ 4, "00052200", 8))
42 return AVPROBE_SCORE_MAX
;
44 return AVPROBE_SCORE_MAX
/2;
47 static void add_metadata(AVFormatContext
*s
, const char *tag
,
48 unsigned int tag_len
, unsigned int remaining
)
50 int len
= FFMIN(tag_len
, remaining
);
56 buf
= av_malloc(len
+1);
59 avio_read(s
->pb
, buf
, len
);
61 av_dict_set(&s
->metadata
, tag
, buf
, AV_DICT_DONT_STRDUP_VAL
);
64 static int vqf_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
66 VqfContext
*c
= s
->priv_data
;
67 AVStream
*st
= avformat_new_stream(s
, NULL
);
75 return AVERROR(ENOMEM
);
79 header_size
= avio_rb32(s
->pb
);
81 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
82 st
->codec
->codec_id
= CODEC_ID_TWINVQ
;
87 chunk_tag
= avio_rl32(s
->pb
);
89 if (chunk_tag
== MKTAG('D','A','T','A'))
92 len
= avio_rb32(s
->pb
);
94 if ((unsigned) len
> INT_MAX
/2) {
95 av_log(s
, AV_LOG_ERROR
, "Malformed header\n");
102 case MKTAG('C','O','M','M'):
103 st
->codec
->channels
= avio_rb32(s
->pb
) + 1;
104 read_bitrate
= avio_rb32(s
->pb
);
105 rate_flag
= avio_rb32(s
->pb
);
106 avio_skip(s
->pb
, len
-12);
108 st
->codec
->bit_rate
= read_bitrate
*1000;
109 st
->codec
->bits_per_coded_sample
= 16;
111 case MKTAG('N','A','M','E'):
112 add_metadata(s
, "title" , len
, header_size
);
114 case MKTAG('(','c',')',' '):
115 add_metadata(s
, "copyright", len
, header_size
);
117 case MKTAG('A','U','T','H'):
118 add_metadata(s
, "author" , len
, header_size
);
120 case MKTAG('A','L','B','M'):
121 add_metadata(s
, "album" , len
, header_size
);
123 case MKTAG('T','R','C','K'):
124 add_metadata(s
, "track" , len
, header_size
);
126 case MKTAG('C','O','M','T'):
127 add_metadata(s
, "comment" , len
, header_size
);
129 case MKTAG('F','I','L','E'):
130 add_metadata(s
, "filename" , len
, header_size
);
132 case MKTAG('D','S','I','Z'):
133 add_metadata(s
, "size" , len
, header_size
);
135 case MKTAG('D','A','T','E'):
136 add_metadata(s
, "date" , len
, header_size
);
138 case MKTAG('G','E','N','R'):
139 add_metadata(s
, "genre" , len
, header_size
);
142 av_log(s
, AV_LOG_ERROR
, "Unknown chunk: %c%c%c%c\n",
143 ((char*)&chunk_tag
)[0], ((char*)&chunk_tag
)[1],
144 ((char*)&chunk_tag
)[2], ((char*)&chunk_tag
)[3]);
145 avio_skip(s
->pb
, FFMIN(len
, header_size
));
151 } while (header_size
>= 0);
155 av_log(s
, AV_LOG_ERROR
, "COMM tag not found!\n");
158 st
->codec
->sample_rate
= 44100;
161 st
->codec
->sample_rate
= 22050;
164 st
->codec
->sample_rate
= 11025;
167 st
->codec
->sample_rate
= rate_flag
*1000;
171 switch (((st
->codec
->sample_rate
/1000) << 8) +
172 read_bitrate
/st
->codec
->channels
) {
189 av_log(s
, AV_LOG_ERROR
, "Mode not suported: %d Hz, %d kb/s.\n",
190 st
->codec
->sample_rate
, st
->codec
->bit_rate
);
193 c
->frame_bit_len
= st
->codec
->bit_rate
*size
/st
->codec
->sample_rate
;
194 av_set_pts_info(st
, 64, 1, st
->codec
->sample_rate
);
199 static int vqf_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
201 VqfContext
*c
= s
->priv_data
;
203 int size
= (c
->frame_bit_len
- c
->remaining_bits
+ 7)>>3;
205 pkt
->pos
= avio_tell(s
->pb
);
206 pkt
->stream_index
= 0;
208 if (av_new_packet(pkt
, size
+2) < 0)
211 pkt
->data
[0] = 8 - c
->remaining_bits
; // Number of bits to skip
212 pkt
->data
[1] = c
->last_frame_bits
;
213 ret
= avio_read(s
->pb
, pkt
->data
+2, size
);
220 c
->last_frame_bits
= pkt
->data
[size
+1];
221 c
->remaining_bits
= (size
<< 3) - c
->frame_bit_len
+ c
->remaining_bits
;
226 static int vqf_read_seek(AVFormatContext
*s
,
227 int stream_index
, int64_t timestamp
, int flags
)
229 VqfContext
*c
= s
->priv_data
;
234 st
= s
->streams
[stream_index
];
235 pos
= av_rescale_rnd(timestamp
* st
->codec
->bit_rate
,
237 st
->time_base
.den
* (int64_t)c
->frame_bit_len
,
238 (flags
& AVSEEK_FLAG_BACKWARD
) ?
239 AV_ROUND_DOWN
: AV_ROUND_UP
);
240 pos
*= c
->frame_bit_len
;
242 st
->cur_dts
= av_rescale(pos
, st
->time_base
.den
,
243 st
->codec
->bit_rate
* (int64_t)st
->time_base
.num
);
245 if ((ret
= avio_seek(s
->pb
, ((pos
-7) >> 3) + s
->data_offset
, SEEK_SET
)) < 0)
248 c
->remaining_bits
= -7 - ((pos
-7)&7);
252 AVInputFormat ff_vqf_demuxer
= {
254 .long_name
= NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"),
255 .priv_data_size
= sizeof(VqfContext
),
256 .read_probe
= vqf_probe
,
257 .read_header
= vqf_read_header
,
258 .read_packet
= vqf_read_packet
,
259 .read_seek
= vqf_read_seek
,