So I want to grab a frame from a video at a specific time using libav for the use as a thumbnail.
What I\'m using is t
I replaced
av_seek_frame(format_context, stream_index, request_timestamp, 0);
with
avformat_seek_file(format_context, stream_index, INT64_MIN, request_timestamp, INT64_MAX, 0);
and suddenly I get reasonable output. Great.
And it only took a day in almost complete documentation darkness. :/
It's mostly like this:
the stream timebase is what you are really interested in. It's what the packet timestamps are in, and also pkt_pts
on the output frame (since it's just copied from the corresponding packet).
the codec timebase is (if set at all) just the inverse of the framerate that might be written in the codec-level headers. It can be useful in cases where there is no container timing information (e.g. when you're reading raw video), but otherwise can be safely ignored.
AVFrame.pkt_pts is the timestamp of the packet that got decoded into this frame. As already said, it's just a straight copy from the packet, so it's in the stream timebase. This is the field you want to use (if the container has timestamps).
AVFrame.pts is not ever set to anything useful when decoding, ignore it (it might replace pkt_pts
in the future, to make the whole mess less confusing, but for now it's like this, for historical reasons mostly).
the format context's duration is in AV_TIME_BASE
(i.e. microseconds). It cannot be in any stream timebase, since you can have three bazillion streams, each with its own timebase.
the problem you see with getting a different timestamp after seeking is simply that seeking is not accurate. In most cases you can only seek to closest keyframe, so it's common to be a couple seconds off. Decoding and discarding the frames you don't need must be done manually.