Mercurial > libavformat.hg
changeset 1743:75909fc5b5a9 libavformat
Seeking support in WavPack
author | kostya |
---|---|
date | Sun, 28 Jan 2007 17:23:28 +0000 |
parents | da3d430bfe71 |
children | 1f8dc697cb11 |
files | wv.c |
diffstat | 1 files changed, 42 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/wv.c Sun Jan 28 09:07:49 2007 +0000 +++ b/wv.c Sun Jan 28 17:23:28 2007 +0000 @@ -50,8 +50,10 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ wv_read_header, wv_read_packet, wv_read_close, + wv_read_seek, };