3 * Copyright (c) 2009 Vitor Sessak
5 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/intreadwrite.h"
25 typedef struct VqfContext
{
27 uint8_t last_frame_bits
;
31 static int vqf_probe(AVProbeData
*probe_packet
)
33 if (AV_RL32(probe_packet
->buf
) != MKTAG('T','W','I','N'))
36 if (!memcmp(probe_packet
->buf
+ 4, "97012000", 8))
37 return AVPROBE_SCORE_MAX
;
39 if (!memcmp(probe_packet
->buf
+ 4, "00052200", 8))
40 return AVPROBE_SCORE_MAX
;
42 return AVPROBE_SCORE_MAX
/2;
45 static void add_metadata(AVFormatContext
*s
, const char *tag
,
46 unsigned int tag_len
, unsigned int remaining
)
48 int len
= FFMIN(tag_len
, remaining
);
54 buf
= av_malloc(len
+1);
57 get_buffer(s
->pb
, buf
, len
);
59 av_metadata_set2(&s
->metadata
, tag
, buf
, AV_METADATA_DONT_STRDUP_VAL
);
62 static int vqf_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
64 VqfContext
*c
= s
->priv_data
;
65 AVStream
*st
= av_new_stream(s
, 0);
73 return AVERROR(ENOMEM
);
77 header_size
= get_be32(s
->pb
);
79 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
80 st
->codec
->codec_id
= CODEC_ID_TWINVQ
;
85 chunk_tag
= get_le32(s
->pb
);
87 if (chunk_tag
== MKTAG('D','A','T','A'))
90 len
= get_be32(s
->pb
);
92 if ((unsigned) len
> INT_MAX
/2) {
93 av_log(s
, AV_LOG_ERROR
, "Malformed header\n");
100 case MKTAG('C','O','M','M'):
101 st
->codec
->channels
= get_be32(s
->pb
) + 1;
102 read_bitrate
= get_be32(s
->pb
);
103 rate_flag
= get_be32(s
->pb
);
104 url_fskip(s
->pb
, len
-12);
106 st
->codec
->bit_rate
= read_bitrate
*1000;
107 st
->codec
->bits_per_coded_sample
= 16;
109 case MKTAG('N','A','M','E'):
110 add_metadata(s
, "title" , len
, header_size
);
112 case MKTAG('(','c',')',' '):
113 add_metadata(s
, "copyright", len
, header_size
);
115 case MKTAG('A','U','T','H'):
116 add_metadata(s
, "author" , len
, header_size
);
118 case MKTAG('A','L','B','M'):
119 add_metadata(s
, "album" , len
, header_size
);
121 case MKTAG('T','R','C','K'):
122 add_metadata(s
, "track" , len
, header_size
);
124 case MKTAG('C','O','M','T'):
125 add_metadata(s
, "comment" , len
, header_size
);
127 case MKTAG('F','I','L','E'):
128 add_metadata(s
, "filename" , len
, header_size
);
130 case MKTAG('D','S','I','Z'):
131 add_metadata(s
, "size" , len
, header_size
);
133 case MKTAG('D','A','T','E'):
134 add_metadata(s
, "date" , len
, header_size
);
136 case MKTAG('G','E','N','R'):
137 add_metadata(s
, "genre" , len
, header_size
);
140 av_log(s
, AV_LOG_ERROR
, "Unknown chunk: %c%c%c%c\n",
141 ((char*)&chunk_tag
)[0], ((char*)&chunk_tag
)[1],
142 ((char*)&chunk_tag
)[2], ((char*)&chunk_tag
)[3]);
143 url_fskip(s
->pb
, FFMIN(len
, header_size
));
149 } while (header_size
>= 0);
153 av_log(s
, AV_LOG_ERROR
, "COMM tag not found!\n");
156 st
->codec
->sample_rate
= 44100;
159 st
->codec
->sample_rate
= 22050;
162 st
->codec
->sample_rate
= 11025;
165 st
->codec
->sample_rate
= rate_flag
*1000;
169 switch (((st
->codec
->sample_rate
/1000) << 8) +
170 read_bitrate
/st
->codec
->channels
) {
187 av_log(s
, AV_LOG_ERROR
, "Mode not suported: %d Hz, %d kb/s.\n",
188 st
->codec
->sample_rate
, st
->codec
->bit_rate
);
191 c
->frame_bit_len
= st
->codec
->bit_rate
*size
/st
->codec
->sample_rate
;
192 av_set_pts_info(st
, 64, 1, st
->codec
->sample_rate
);
197 static int vqf_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
199 VqfContext
*c
= s
->priv_data
;
201 int size
= (c
->frame_bit_len
- c
->remaining_bits
+ 7)>>3;
203 pkt
->pos
= url_ftell(s
->pb
);
204 pkt
->stream_index
= 0;
206 if (av_new_packet(pkt
, size
+2) < 0)
209 pkt
->data
[0] = 8 - c
->remaining_bits
; // Number of bits to skip
210 pkt
->data
[1] = c
->last_frame_bits
;
211 ret
= get_buffer(s
->pb
, pkt
->data
+2, size
);
218 c
->last_frame_bits
= pkt
->data
[size
+1];
219 c
->remaining_bits
= (size
<< 3) - c
->frame_bit_len
+ c
->remaining_bits
;
224 static int vqf_read_seek(AVFormatContext
*s
,
225 int stream_index
, int64_t timestamp
, int flags
)
227 VqfContext
*c
= s
->priv_data
;
232 st
= s
->streams
[stream_index
];
233 pos
= av_rescale_rnd(timestamp
* st
->codec
->bit_rate
,
235 st
->time_base
.den
* (int64_t)c
->frame_bit_len
,
236 (flags
& AVSEEK_FLAG_BACKWARD
) ?
237 AV_ROUND_DOWN
: AV_ROUND_UP
);
238 pos
*= c
->frame_bit_len
;
240 st
->cur_dts
= av_rescale(pos
, st
->time_base
.den
,
241 st
->codec
->bit_rate
* (int64_t)st
->time_base
.num
);
243 if ((ret
= url_fseek(s
->pb
, ((pos
-7) >> 3) + s
->data_offset
, SEEK_SET
)) < 0)
246 c
->remaining_bits
= -7 - ((pos
-7)&7);
250 AVInputFormat vqf_demuxer
= {
252 NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"),