00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/audioconvert.h"
00023 #include "libavutil/intreadwrite.h"
00024 #include "libavutil/dict.h"
00025 #include "avformat.h"
00026 #include "internal.h"
00027 #include "apetag.h"
00028 #include "id3v1.h"
00029
00030
00031 #define WV_BLOCK_LIMIT 1047576
00032
00033 #define WV_EXTRA_SIZE 12
00034
00035 #define WV_START_BLOCK 0x0800
00036 #define WV_END_BLOCK 0x1000
00037 #define WV_SINGLE_BLOCK (WV_START_BLOCK | WV_END_BLOCK)
00038
00039 enum WV_FLAGS{
00040 WV_MONO = 0x0004,
00041 WV_HYBRID = 0x0008,
00042 WV_JOINT = 0x0010,
00043 WV_CROSSD = 0x0020,
00044 WV_HSHAPE = 0x0040,
00045 WV_FLOAT = 0x0080,
00046 WV_INT32 = 0x0100,
00047 WV_HBR = 0x0200,
00048 WV_HBAL = 0x0400,
00049 WV_MCINIT = 0x0800,
00050 WV_MCEND = 0x1000,
00051 };
00052
00053 static const int wv_rates[16] = {
00054 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000,
00055 32000, 44100, 48000, 64000, 88200, 96000, 192000, -1
00056 };
00057
00058 typedef struct{
00059 uint32_t blksize, flags;
00060 int rate, chan, bpp;
00061 uint32_t chmask;
00062 uint32_t samples, soff;
00063 int multichannel;
00064 int block_parsed;
00065 uint8_t extra[WV_EXTRA_SIZE];
00066 int64_t pos;
00067 }WVContext;
00068
00069 static int wv_probe(AVProbeData *p)
00070 {
00071
00072 if (p->buf_size <= 32)
00073 return 0;
00074 if (p->buf[0] == 'w' && p->buf[1] == 'v' &&
00075 p->buf[2] == 'p' && p->buf[3] == 'k')
00076 return AVPROBE_SCORE_MAX;
00077 else
00078 return 0;
00079 }
00080
00081 static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb, int append)
00082 {
00083 WVContext *wc = ctx->priv_data;
00084 uint32_t tag, ver;
00085 int size;
00086 int rate, bpp, chan;
00087 uint32_t chmask;
00088
00089 wc->pos = avio_tell(pb);
00090 if(!append){
00091 tag = avio_rl32(pb);
00092 if (tag != MKTAG('w', 'v', 'p', 'k'))
00093 return -1;
00094 size = avio_rl32(pb);
00095 if(size < 24 || size > WV_BLOCK_LIMIT){
00096 av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size);
00097 return -1;
00098 }
00099 wc->blksize = size;
00100 ver = avio_rl16(pb);
00101 if(ver < 0x402 || ver > 0x410){
00102 av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
00103 return -1;
00104 }
00105 avio_r8(pb);
00106 avio_r8(pb);
00107 wc->samples = avio_rl32(pb);
00108 wc->soff = avio_rl32(pb);
00109 avio_read(pb, wc->extra, WV_EXTRA_SIZE);
00110 }else{
00111 size = wc->blksize;
00112 }
00113 wc->flags = AV_RL32(wc->extra + 4);
00114
00115 if (!AV_RN32(wc->extra))
00116 return 0;
00117
00118 bpp = ((wc->flags & 3) + 1) << 3;
00119 chan = 1 + !(wc->flags & WV_MONO);
00120 chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
00121 rate = wv_rates[(wc->flags >> 23) & 0xF];
00122 wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK);
00123 if(wc->multichannel){
00124 chan = wc->chan;
00125 chmask = wc->chmask;
00126 }
00127 if((rate == -1 || !chan) && !wc->block_parsed){
00128 int64_t block_end = avio_tell(pb) + wc->blksize - 24;
00129 if(!pb->seekable){
00130 av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n");
00131 return -1;
00132 }
00133 while(avio_tell(pb) < block_end){
00134 int id, size;
00135 id = avio_r8(pb);
00136 size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
00137 size <<= 1;
00138 if(id&0x40)
00139 size--;
00140 switch(id&0x3F){
00141 case 0xD:
00142 if(size <= 1){
00143 av_log(ctx, AV_LOG_ERROR, "Insufficient channel information\n");
00144 return -1;
00145 }
00146 chan = avio_r8(pb);
00147 switch(size - 2){
00148 case 0:
00149 chmask = avio_r8(pb);
00150 break;
00151 case 1:
00152 chmask = avio_rl16(pb);
00153 break;
00154 case 2:
00155 chmask = avio_rl24(pb);
00156 break;
00157 case 3:
00158 chmask = avio_rl32(pb);
00159 break;
00160 case 5:
00161 avio_skip(pb, 1);
00162 chan |= (avio_r8(pb) & 0xF) << 8;
00163 chmask = avio_rl24(pb);
00164 break;
00165 default:
00166 av_log(ctx, AV_LOG_ERROR, "Invalid channel info size %d\n", size);
00167 return -1;
00168 }
00169 break;
00170 case 0x27:
00171 rate = avio_rl24(pb);
00172 break;
00173 default:
00174 avio_skip(pb, size);
00175 }
00176 if(id&0x40)
00177 avio_skip(pb, 1);
00178 }
00179 if(rate == -1){
00180 av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
00181 return -1;
00182 }
00183 avio_seek(pb, block_end - wc->blksize + 24, SEEK_SET);
00184 }
00185 if(!wc->bpp) wc->bpp = bpp;
00186 if(!wc->chan) wc->chan = chan;
00187 if(!wc->chmask) wc->chmask = chmask;
00188 if(!wc->rate) wc->rate = rate;
00189
00190 if(wc->flags && bpp != wc->bpp){
00191 av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp);
00192 return -1;
00193 }
00194 if(wc->flags && !wc->multichannel && chan != wc->chan){
00195 av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan);
00196 return -1;
00197 }
00198 if(wc->flags && rate != -1 && rate != wc->rate){
00199 av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate);
00200 return -1;
00201 }
00202 wc->blksize = size - 24;
00203 return 0;
00204 }
00205
00206 static int wv_read_header(AVFormatContext *s,
00207 AVFormatParameters *ap)
00208 {
00209 AVIOContext *pb = s->pb;
00210 WVContext *wc = s->priv_data;
00211 AVStream *st;
00212
00213 wc->block_parsed = 0;
00214 for(;;){
00215 if(wv_read_block_header(s, pb, 0) < 0)
00216 return -1;
00217 if(!AV_RN32(wc->extra))
00218 avio_skip(pb, wc->blksize - 24);
00219 else
00220 break;
00221 }
00222
00223
00224 st = avformat_new_stream(s, NULL);
00225 if (!st)
00226 return -1;
00227 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00228 st->codec->codec_id = CODEC_ID_WAVPACK;
00229 st->codec->channels = wc->chan;
00230 st->codec->channel_layout = wc->chmask;
00231 st->codec->sample_rate = wc->rate;
00232 st->codec->bits_per_coded_sample = wc->bpp;
00233 avpriv_set_pts_info(st, 64, 1, wc->rate);
00234 st->start_time = 0;
00235 st->duration = wc->samples;
00236
00237 if(s->pb->seekable) {
00238 int64_t cur = avio_tell(s->pb);
00239 ff_ape_parse_tag(s);
00240 if(!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
00241 ff_id3v1_read(s);
00242 avio_seek(s->pb, cur, SEEK_SET);
00243 }
00244
00245 return 0;
00246 }
00247
00248 static int wv_read_packet(AVFormatContext *s,
00249 AVPacket *pkt)
00250 {
00251 WVContext *wc = s->priv_data;
00252 int ret;
00253 int size, ver, off;
00254 int64_t pos;
00255
00256 if (url_feof(s->pb))
00257 return AVERROR(EIO);
00258 if(wc->block_parsed){
00259 if(wv_read_block_header(s, s->pb, 0) < 0)
00260 return -1;
00261 }
00262
00263 pos = wc->pos;
00264 off = wc->multichannel ? 4 : 0;
00265 if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0)
00266 return AVERROR(ENOMEM);
00267 if(wc->multichannel)
00268 AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12);
00269 memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE);
00270 ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize);
00271 if(ret != wc->blksize){
00272 av_free_packet(pkt);
00273 return AVERROR(EIO);
00274 }
00275 while(!(wc->flags & WV_END_BLOCK)){
00276 if(avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')){
00277 av_free_packet(pkt);
00278 return -1;
00279 }
00280 if((ret = av_append_packet(s->pb, pkt, 4)) < 0){
00281 av_free_packet(pkt);
00282 return ret;
00283 }
00284 size = AV_RL32(pkt->data + pkt->size - 4);
00285 if(size < 24 || size > WV_BLOCK_LIMIT){
00286 av_free_packet(pkt);
00287 av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size);
00288 return -1;
00289 }
00290 wc->blksize = size;
00291 ver = avio_rl16(s->pb);
00292 if(ver < 0x402 || ver > 0x410){
00293 av_free_packet(pkt);
00294 av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
00295 return -1;
00296 }
00297 avio_r8(s->pb);
00298 avio_r8(s->pb);
00299 wc->samples = avio_rl32(s->pb);
00300 wc->soff = avio_rl32(s->pb);
00301 if((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0){
00302 av_free_packet(pkt);
00303 return ret;
00304 }
00305 memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE);
00306
00307 if(wv_read_block_header(s, s->pb, 1) < 0){
00308 av_free_packet(pkt);
00309 return -1;
00310 }
00311 ret = av_append_packet(s->pb, pkt, wc->blksize);
00312 if(ret < 0){
00313 av_free_packet(pkt);
00314 return ret;
00315 }
00316 }
00317 pkt->stream_index = 0;
00318 wc->block_parsed = 1;
00319 pkt->pts = wc->soff;
00320 av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
00321 return 0;
00322 }
00323
00324 static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
00325 {
00326 AVStream *st = s->streams[stream_index];
00327 WVContext *wc = s->priv_data;
00328 AVPacket pkt1, *pkt = &pkt1;
00329 int ret;
00330 int index = av_index_search_timestamp(st, timestamp, flags);
00331 int64_t pos, pts;
00332
00333
00334 if (index >= 0 &&
00335 timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
00336 wc->block_parsed = 1;
00337 avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
00338 return 0;
00339 }
00340
00341 if(timestamp < 0 || timestamp >= s->duration)
00342 return -1;
00343
00344 pos = avio_tell(s->pb);
00345 do{
00346 ret = av_read_frame(s, pkt);
00347 if (ret < 0){
00348 avio_seek(s->pb, pos, SEEK_SET);
00349 return -1;
00350 }
00351 pts = pkt->pts;
00352 av_free_packet(pkt);
00353 }while(pts < timestamp);
00354 return 0;
00355 }
00356
00357 AVInputFormat ff_wv_demuxer = {
00358 .name = "wv",
00359 .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
00360 .priv_data_size = sizeof(WVContext),
00361 .read_probe = wv_probe,
00362 .read_header = wv_read_header,
00363 .read_packet = wv_read_packet,
00364 .read_seek = wv_read_seek,
00365 };