Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is libavcodec only able to provide an estimate of the timestamp?

When trying to get the timestamp of an AVFrame, there is a field called best_effort_timestamp which it describes as:

frame timestamp estimated using various heuristics, in stream time base

Looking into the codebase, I can see that the function that calculates this value is given by guess_correct_pts. The source code can be seen below:

static int64_t guess_correct_pts(AVCodecContext *ctx,
                                 int64_t reordered_pts, int64_t dts)
{
    int64_t pts = AV_NOPTS_VALUE;

    if (dts != AV_NOPTS_VALUE) {
        ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts;
        ctx->pts_correction_last_dts = dts;
    } else if (reordered_pts != AV_NOPTS_VALUE)
        ctx->pts_correction_last_dts = reordered_pts;

    if (reordered_pts != AV_NOPTS_VALUE) {
        ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts;
        ctx->pts_correction_last_pts = reordered_pts;
    } else if(dts != AV_NOPTS_VALUE)
        ctx->pts_correction_last_pts = dts;

    if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE)
       && reordered_pts != AV_NOPTS_VALUE)
        pts = reordered_pts;
    else
        pts = dts;

    return pts;
}

From what I can tell, every time this function is called it determines if the pts or dts is faulty by seeing if it is less than or equal to what seen last frame. Then it returns the pts or dts depending on which one has less faulty values in total.

While the code seems straightforward to follow, it doesn't really explain why any of this is necessary or how common it is for best_effort_timestamp to be incorrect.

My main questions are:

  1. What could cause a video to have faulty pts or dts values?
  2. Is it common for videos to have faulty values?
  3. When there are faulty values, how inaccurate can best_effort_timestamp get? Are we talking about a few milliseconds or potentially many seconds?
like image 410
Cameron Aavik Avatar asked Dec 14 '25 13:12

Cameron Aavik


1 Answers

The code appears to have been added to ensure monotonic PTS for streams demuxed from containers that may contain DTS only and the stream stores reordered frames due to B-frames.

See http://www.ffmpeg.org/pipermail/ffmpeg-devel/2011-January/108014.html for a related discussion. It was controversial at that time.

For containers with both PTS and DTS, they usually sanitize timestamps before demuxing the packet, so best effort should equal to the set values. Any 'correction' should be on the order of a few frame intervals.

like image 140
Gyan Avatar answered Dec 16 '25 23:12

Gyan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!