video - 为什么 libavcodec 只能提供时间戳的估计值?

标签 video ffmpeg libavcodec

当尝试获取 AVFrame 的时间戳时,有一个名为 best_effort_timestamp 的字段它描述为:

frame timestamp estimated using various heuristics, in stream time base

查看代码库,我可以看到计算此值的函数由 guess_correct_pts 给出.源代码如下:

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

据我所知,每次调用此函数时,它都会通过查看是否小于或等于看到的值来确定 ptsdts 是否有问题最后一帧。然后它返回 ptsdts,具体取决于总错误值较少的那个。

虽然代码看起来简单易懂,但它并没有真正解释为什么这些是必要的,也没有解释 best_effort_timestamp 不正确的常见情况。

我的主要问题是:

  1. 什么会导致视频有错误的 ptsdts 值?
  2. 视频的错误值是否很常见?
  3. 当存在错误值时,best_effort_timestamp 可以有多不准确?我们是在谈论几毫秒还是可能很多秒?

最佳答案

似乎已添加代码以确保从可能仅包含 DTS 的容器中解复用的流的单调 PTS,并且流存储由于 B 帧而重新排序的帧。

参见 http://www.ffmpeg.org/pipermail/ffmpeg-devel/2011-January/108014.html进行相关讨论。这在当时是有争议的。

对于同时具有 PTS 和 DTS 的容器,它们通常在对数据包进行多路分解之前清理时间戳,因此尽力而为应该等于设置值。任何“校正”都应该在几帧间隔的数量级上。

关于video - 为什么 libavcodec 只能提供时间戳的估计值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57641774/

相关文章:

video - 加速视频时提高 webm 质量

jquery - Vimeo 覆盖在悬停时永久删除

javascript - Youtube 是否对自己域中的视频使用 &lt;iframe&gt; 或 <video> ?

ios - objective-c:通过删除默认的全屏等功能来播放视频

FFMPEG 在特定垂直位置覆盖 1080X1920 视频覆盖 1280X720 视频

java - 如何等待来自 DockerClient.waitContainerCmd() 的 ResultCallback?

video - 如何使用 rm/rmvb 支持编译 ffmpeg?

c++ - sws_scale YUV --> RGB 失真图像

windows-services - 在同一台机器上从 Windows 服务运行 ffmpeg 遇到权限问题

build - 即使已经构建和安装了 ffmpeg,也找不到 libavcodec