[Libav-user] av_frame_get_best_effort_timestamp(): PTS or DTS?

wm4 nfxjfg at googlemail.com
Fri Mar 28 22:04:41 CET 2014

On Fri, 28 Mar 2014 21:19:55 +0100
Lucas Soltic <lucas.soltic at orange.fr> wrote:

> Hello!
> Does av_frame_get_best_effort_timestamp() gives a PTS or DTS?
> At first I would have thought it's a PTS, because it's impossible for decoding to correctly happen if DTS does not exist in the packet, but then I read that the packet DTS may be AV_NOPTS_VALUE (DTS being a NOPTS..??!). If that is correct, is there a reliable way to know the DTS too (in the core meaning of DTS, even if the file does not set it)?

Some files have PTS and DTS mixed (mpeg mostly), some files have PTS
only (e.g. Matroska), some files have DTS only (e.g. AVI). The general
solution is to use DTS if PTS is set to NOPTS.

Here's how av_frame_get_best_effort_timestamp() is calculated:


Looks complicated, but is rather simple. As I understand, this is
mostly a workaround if PTS or DTS are set incorrectly. 

This function takes AVFrame.pkt_pts and AVFrame.pkt_dts as inputs. It
returns what will be used as AVFrame.best_effort_timestamp. What this
function does is:

1. count how often it happens that PTS or DTS are not monotonic
   (normally, the DTS _and_ PTS should not decrease after the decoder;
   this is not true _before_ the decoder, but the decoder should
   reorder them so that they're monotonic, and some broken files might
   violate this)
2. if PTS is more often wrong than DTS, use the DTS as output timestamp

Libav does not have the AVFrame.best_effort_timestamp field. Butthe
Libav command line tools (avplay, avconv) calculates it the same way:


And that's why I would recommend just copying the code. It's trivial
anyway, at least once you understand it, and your project will be
compatible to both FFmpeg and Libav.

More information about the Libav-user mailing list