[FFmpeg-devel] ogg seeking status

Don Moir donmoir at comcast.net
Fri Feb 10 06:22:39 CET 2012

> On Wed, Feb 08, 2012 at 05:06:29AM -0500, Don Moir wrote:
>> Open this file like you would normally in some of your own code or
>> use the MPlayer code to get it opened. I open the audio and video
>> streams for this file.
>> Then do: avformat _seek_file (pFormatCtx, videoStreamIndex, INT64_MIN, 
>> 0x405c,
>> INT64_MAX);
>> For this file, the 0x405c corresponds to about 9 minutes.
>> Start reading packets until you get the first videoStreamIndex
>> packet using av_read_frame (pFormatCtx, &packet);
>> The first videoStreamIndex packet should contain 0x1b41 for both the
>> packet pts and dts values. 0x1b41 a little less than 4 minutes for
>> the video stream for this file and this is way off.
> Are you using latest FFmpeg?
> I run:
> $ ./mplayer -ss 9:00 bad_seek_not_accurate.ogv  -quiet

The first patch you did for ogg_read_timestamp did not include 
ogg_validate_keyframe. When you posted the 2nd patch it did, but it was not 
clear from your comments if you were going to keep that or not. You said 
something begrudgingly like: "We could do this and put out a big fat warning 
or something". I had implemented it both ways but I commented out the one 
with ogg_validate_keyframe. Not sure I got the email that the 2nd and final 
patch was commited, but I could have missed that.

Ok the good news is the seeked to position is now dead on close with 
ogg_validate_keyframe in place and the changes associated with that.

The problem now is on the first ogg_packet_read, os->pflags is not set to 
indicate a keyframe. But we just seeked to a keyframe.

ogg_read_packet calls ogg_packet which sets os->pflags to zero among other 
things and that appears to be normal. It drops into the final else statement 
in ogg_packet which clears pflags etc.

After setting pflags to zero, ogg_packet steps into this code:

os->page_end = 1;
for (i = os->segp; i < os->nsegs; i++)
    if (os->segments [i] < 255) {
        os->page_end = 0;

NOTE os->page_end = 0; this is set on first packet_read after seek.

Back in ogg_read_packet now after returning from ogg_packet.

We at this code in ogg_read_packet:

pts = ogg_calc_pts (s, idx, &dts);

Since os->page_end is 0, ogg_calc_pts will not set os->pflags as a keyframe. 
This is set normally via ogg_gptopts and in this case theora_gptopts but 
since os->page_end is zero it never gets there.

This is the reason setting os->keyframe_seek to 0 after seek has better 
behavior. Doing this prevents it from reading thru a bunch of packets 
(because of bug) until it finds one that makes it happy. It will cycle thru 
retry several times. (goto retry).

I think if you find the reason for the above problem we will be done with 
this go around. You can check me on this pretty easy I would guess. Just do 
any seek on the file Roaring Fork Motor file and then check the behavor on 
the first ogg_packet read. 

More information about the ffmpeg-devel mailing list