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:
pts or dts values?best_effort_timestamp get? Are we talking about a few milliseconds or potentially many seconds?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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With