From 49561f992e74b9ec1417707e36e73ca61ed33246 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sun, 28 Jan 2007 17:23:28 +0000 Subject: [PATCH] Seeking support in WavPack Originally committed as revision 7750 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/wv.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/libavformat/wv.c b/libavformat/wv.c index c50a150..7664aa1 100644 --- a/libavformat/wv.c +++ b/libavformat/wv.c @@ -50,8 +50,10 @@ static const int wv_rates[16] = { typedef struct{ uint32_t blksize, flags; int rate, chan, bpp; + uint32_t samples, soff; int block_parsed; uint8_t extra[WV_EXTRA_SIZE]; + int64_t pos; }WVContext; static int wv_probe(AVProbeData *p) @@ -73,6 +75,7 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb) int size; int rate, bpp, chan; + wc->pos = url_ftell(pb); tag = get_le32(pb); if (tag != MKTAG('w', 'v', 'p', 'k')) return -1; @@ -89,8 +92,8 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb) } get_byte(pb); // track no get_byte(pb); // track sub index - get_le32(pb); // total samples in file - get_le32(pb); // offset in samples of current block + wc->samples = get_le32(pb); // total samples in file + wc->soff = get_le32(pb); // offset in samples of current block get_buffer(pb, wc->extra, WV_EXTRA_SIZE); wc->flags = AV_RL32(wc->extra + 4); //parse flags @@ -155,6 +158,8 @@ static int wv_read_header(AVFormatContext *s, st->codec->sample_rate = wc->rate; st->codec->bits_per_sample = wc->bpp; av_set_pts_info(st, 64, 1, wc->rate); + s->start_time = 0; + s->duration = (int64_t)wc->samples * AV_TIME_BASE / st->codec->sample_rate; return 0; } @@ -182,7 +187,8 @@ static int wv_read_packet(AVFormatContext *s, pkt->stream_index = 0; wc->block_parsed = 1; pkt->size = ret + WV_EXTRA_SIZE; - + pkt->pts = wc->soff; + av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; } @@ -191,6 +197,38 @@ static int wv_read_close(AVFormatContext *s) return 0; } +static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) +{ + AVStream *st = s->streams[stream_index]; + WVContext *wc = s->priv_data; + AVPacket pkt1, *pkt = &pkt1; + int ret; + int index = av_index_search_timestamp(st, timestamp, flags); + int64_t pos, pts; + + /* if found, seek there */ + if (index >= 0){ + wc->block_parsed = 1; + url_fseek(&s->pb, st->index_entries[index].pos, SEEK_SET); + return 0; + } + /* if timestamp is out of bounds, return error */ + if(timestamp < 0 || timestamp >= s->duration) + return -1; + + pos = url_ftell(&s->pb); + do{ + ret = av_read_frame(s, pkt); + if (ret < 0){ + url_fseek(&s->pb, pos, SEEK_SET); + return -1; + } + pts = pkt->pts; + av_free_packet(pkt); + }while(pts < timestamp); + return 0; +} + AVInputFormat wv_demuxer = { "wv", "WavPack", @@ -199,4 +237,5 @@ AVInputFormat wv_demuxer = { wv_read_header, wv_read_packet, wv_read_close, + wv_read_seek, }; -- 2.7.4