[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;
break;
}
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