[FFmpeg-devel] [PATCH] ogg: Fix seek to zero and packet pts after read through.

dalecurtis at chromium.org dalecurtis at chromium.org
Thu Apr 19 20:07:42 CEST 2012


From: Dale Curtis <dalecurtis at chromium.org>

Seeking to zero doesn't always work for some ogg files.  Even the
one included with the FATE test.

Additionally, pts values are not equivalent between the first and
second pass through an ogg file with a zero seek in between.
Specifically:

  while(av_read_frame(packet))
    print(packet.pts);
  av_seek_frame(0)
  while(av_read_frame(packet))
    print(packet.pts);

Will print different values.  Previously this lead to a problem
where seeking to zero was broken.  Some concrete numbers:

  1st pass pts: -128   0 128 256  832
  2nd pass pts:    0 576 704 832 1408

Reproducible using FATE and the following sample program and test case:

http://commondatastorage.googleapis.com/dalecurtis-shared/ogg-test.tar.bz2

Signed-off-by: Dale Curtis <dalecurtis at chromium.org>
---
 libavformat/oggdec.c    |   28 ++++++++++++++++++++++++++++
 tests/ref/seek/lavf_ogg |   24 ++++++++++++++++--------
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 6a55f89..f823e85 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -657,6 +657,8 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
     int64_t pts = AV_NOPTS_VALUE;
     int64_t keypos = -1;
     int i = -1;
+    int packet = 0;
+    int64_t start_pos = *pos_arg;
     int pstart, psize;
     avio_seek(bc, *pos_arg, SEEK_SET);
     ogg_reset(ogg);
@@ -676,6 +678,12 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
                 else
                     pts = AV_NOPTS_VALUE;
             }
+
+            // This is for the special case for the first packet in the stream.
+            if (pts == AV_NOPTS_VALUE && start_pos <= s->data_offset && !packet) {
+                pts = 0;
+            }
+            ++packet;
         }
         if (pts != AV_NOPTS_VALUE)
             break;
@@ -690,6 +698,10 @@ static int ogg_read_seek(AVFormatContext *s, int stream_index,
     struct ogg *ogg = s->priv_data;
     struct ogg_stream *os = ogg->streams + stream_index;
     int ret;
+    int64_t seek_pos;
+    int64_t pos_arg;
+    int64_t seek_pts;
+    int i;
 
     av_assert0(stream_index < ogg->nstreams);
     // Ensure everything is reset even when seeking via
@@ -706,6 +718,22 @@ static int ogg_read_seek(AVFormatContext *s, int stream_index,
     os = ogg->streams + stream_index;
     if (ret < 0)
         os->keyframe_seek = 0;
+
+    // Save the position seeked to.
+    pos_arg = seek_pos = avio_tell(s->pb);
+    seek_pts = ogg_read_timestamp(s, stream_index, &pos_arg, avio_size(s->pb));
+    os = ogg->streams + stream_index;
+
+    // Since we have seeked to the beginning then reset lastpts and lastdts to 0.
+    if (!seek_pts) {
+        for (i = 0; i < ogg->nstreams; i++){
+            struct ogg_stream *stream = ogg->streams + i;
+            stream->lastpts = 0;
+            stream->lastdts = 0;
+        }
+        os->keyframe_seek = 0;
+    }
+    avio_seek(s->pb, seek_pos, SEEK_SET);
     return ret;
 }
 
diff --git a/tests/ref/seek/lavf_ogg b/tests/ref/seek/lavf_ogg
index a9704f3..2898d10 100644
--- a/tests/ref/seek/lavf_ogg
+++ b/tests/ref/seek/lavf_ogg
@@ -1,27 +1,35 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-ret:-1         st:-1 flags:0  ts:-1.000000
+ret: 0         st:-1 flags:0  ts:-1.000000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret:-1         st:-1 flags:1  ts: 1.894167
 ret:-1         st: 0 flags:0  ts: 0.788345
-ret:-1         st: 0 flags:1  ts:-0.317506
+ret: 0         st: 0 flags:1  ts:-0.317506
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret:-1         st:-1 flags:0  ts: 2.576668
 ret:-1         st:-1 flags:1  ts: 1.470835
 ret:-1         st: 0 flags:0  ts: 0.365011
-ret:-1         st: 0 flags:1  ts:-0.740839
+ret: 0         st: 0 flags:1  ts:-0.740839
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret:-1         st:-1 flags:0  ts: 2.153336
 ret:-1         st:-1 flags:1  ts: 1.047503
-ret:-1         st: 0 flags:0  ts:-0.058322
+ret: 0         st: 0 flags:0  ts:-0.058322
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret:-1         st: 0 flags:1  ts: 2.835828
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret:-1         st:-1 flags:1  ts: 0.624171
-ret:-1         st: 0 flags:0  ts:-0.481655
+ret: 0         st: 0 flags:0  ts:-0.481655
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret:-1         st: 0 flags:1  ts: 2.412494
 ret:-1         st:-1 flags:0  ts: 1.306672
 ret:-1         st:-1 flags:1  ts: 0.200839
-ret:-1         st: 0 flags:0  ts:-0.904989
+ret: 0         st: 0 flags:0  ts:-0.904989
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret:-1         st: 0 flags:1  ts: 1.989184
 ret:-1         st:-1 flags:0  ts: 0.883340
-ret:-1         st:-1 flags:1  ts:-0.222493
+ret: 0         st:-1 flags:1  ts:-0.222493
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
 ret:-1         st: 0 flags:0  ts: 2.671678
 ret:-1         st: 0 flags:1  ts: 1.565850
 ret:-1         st:-1 flags:0  ts: 0.460008
-ret:-1         st:-1 flags:1  ts:-0.645825
+ret: 0         st:-1 flags:1  ts:-0.645825
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    143 size:  1364
-- 
1.7.7.3



More information about the ffmpeg-devel mailing list