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

Dale Curtis dalecurtis at chromium.org
Tue Apr 24 01:53:13 CEST 2012


On Thu, Apr 19, 2012 at 11:07 AM, <dalecurtis at chromium.org> wrote:

> 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
>
>
Ping? This is another patch we've had in place for a while, testing shows
it's still necessary for seeking to zero in any ogg file. Thanks in advance.


More information about the ffmpeg-devel mailing list