aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2006-12-28 05:33:31 +0000
committerKostya Shishkov <kostya.shishkov@gmail.com>2006-12-28 05:33:31 +0000
commite311363245db963389dd62e8028641fbcdac35b5 (patch)
tree23583c3cd36c174276a689d1564f2a08d29751a2
parentd037d797a4e1b5518839a03c004b65df860b9ebe (diff)
downloadffmpeg-e311363245db963389dd62e8028641fbcdac35b5.tar.gz
Enable forward seek in Musepack demuxer
Originally committed as revision 7381 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/mpc.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/libavformat/mpc.c b/libavformat/mpc.c
index abc7617695..1c941d8159 100644
--- a/libavformat/mpc.c
+++ b/libavformat/mpc.c
@@ -71,6 +71,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
c->curframe = 0;
c->lastframe = -1;
c->curbits = 8;
+ c->frames_noted = 0;
st = av_new_stream(s, 0);
if (!st)
@@ -156,15 +157,42 @@ static int mpc_read_close(AVFormatContext *s)
return 0;
}
+/**
+ * Seek to the given position
+ * If position is unknown but is within the limits of file
+ * then packets are skipped unless desired position is reached
+ *
+ * Also this function makes use of the fact that timestamp == frameno
+ */
static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
{
AVStream *st = s->streams[stream_index];
MPCContext *c = s->priv_data;
+ AVPacket pkt1, *pkt = &pkt1;
+ int ret;
int index = av_index_search_timestamp(st, timestamp, flags);
- if (index < 0)
- return -1;
- c->curframe = st->index_entries[index].pos;
+ uint32_t lastframe;
+ /* if found, seek there */
+ if (index >= 0){
+ c->curframe = st->index_entries[index].pos;
+ return 0;
+ }
+ /* if timestamp is out of bounds, return error */
+ if(timestamp < 0 || timestamp >= c->fcount)
+ return -1;
+ /* seek to the furthest known position and read packets until
+ we reach desired position */
+ lastframe = c->curframe;
+ if(c->frames_noted) c->curframe = c->frames_noted - 1;
+ while(c->curframe < timestamp){
+ ret = av_read_frame(s, pkt);
+ if (ret < 0){
+ c->curframe = lastframe;
+ return -1;
+ }
+ av_free_packet(pkt);
+ }
return 0;
}