[FFmpeg-cvslog] oggdec: fix keyframe seeking when granule_is_start is 0.

Reimar Döffinger git at videolan.org
Sun Feb 5 14:21:46 CET 2012


ffmpeg | branch: master | Reimar Döffinger <Reimar.Doeffinger at gmx.de> | Sat Feb  4 20:31:21 2012 +0100| [1b0dc96fc98f29fbd0d8d4bd8335982e5d47f2c8] | committer: Reimar Döffinger

oggdec: fix keyframe seeking when granule_is_start is 0.

In this case, the pts values will be delayed by one, but
at the same time pts values might only be supplied for e.g.
keyframes.
This results on only the frame after the keyframe having a
pts value.
As a hack, make read_timestamp return the keyframe position
together with the pts from a following frame when seeking
to a keyframe.
Fixes trac issue #438.
However it causes the read_timestamp function to return a
pos value that is actually before the packet with the
indicated pts.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1b0dc96fc98f29fbd0d8d4bd8335982e5d47f2c8
---

 libavformat/oggdec.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 4280f8f..9e6832b 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -637,6 +637,7 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
     struct ogg *ogg = s->priv_data;
     AVIOContext *bc = s->pb;
     int64_t pts = AV_NOPTS_VALUE;
+    int64_t keypos = -1;
     int i = -1;
     avio_seek(bc, *pos_arg, SEEK_SET);
     ogg_reset(ogg);
@@ -645,8 +646,16 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
         if (i == stream_index) {
             struct ogg_stream *os = ogg->streams + stream_index;
             pts = ogg_calc_pts(s, i, NULL);
-            if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
-                pts = AV_NOPTS_VALUE;
+            if (os->pflags & AV_PKT_FLAG_KEY) {
+                keypos = *pos_arg;
+            } else if (os->keyframe_seek) {
+                // if we had a previous keyframe but no pts for it,
+                // return that keyframe with this pts value.
+                if (keypos >= 0)
+                    *pos_arg = keypos;
+                else
+                    pts = AV_NOPTS_VALUE;
+            }
         }
         if (pts != AV_NOPTS_VALUE)
             break;



More information about the ffmpeg-cvslog mailing list