Enable forward seek in Musepack demuxer
authorKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 28 Dec 2006 05:33:31 +0000 (05:33 +0000)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 28 Dec 2006 05:33:31 +0000 (05:33 +0000)
Originally committed as revision 7381 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/mpc.c

index abc76176959815db6639e268ec90347792ac78a2..1c941d8159eef2b4e0f6f5fe865048905017795e 100644 (file)
@@ -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;
 }