[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