gpt4 book ai didi

libav - 在FFmpeg中进行帧编码之前计算PTS

转载 作者:行者123 更新时间:2023-12-03 20:48:59 27 4
gpt4 key购买 nike

如何在FFmpeg C API中编码之前为帧计算正确的PTS值?

为了进行编码,我使用了avcodec_encode_video2函数,然后通过av_interleaved_write_frame编写它。

我找到了一些公式,但是它们都不起作用。

doxygen example中,他们正在使用

frame->pts = 0;
for (;;) {
// encode & write frame
// ...
frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
}

This blog说公式必须是这样的:

(1 / FPS) * sample rate * frame number



某人仅使用帧号来设置点数:
frame->pts = videoCodecCtx->frame_number;

或另一种方式:
int64_t now = av_gettime();
frame->pts = av_rescale_q(now, (AVRational){1, 1000000}, videoCodecCtx->time_base);

最后一个:
// 40 * 90 means 40 ms and 90 because of the 90kHz by the standard for PTS-values. 
frame->pts = encodedFrames * 40 * 90;

哪一个是正确的?我认为回答这个问题不仅对我有帮助。

最佳答案

最好在尝试代码之前更抽象地考虑PTS。

您正在做的是将3个“时间集”啮合在一起。第一个是我们习惯的时间,基于每秒1000毫秒,每分钟60秒等等。第二个是您正在使用的特定编解码器的编解码器时间。每个编解码器都有某种表示时间的方式,通常以1 /数字格式表示,这意味着每一秒都有“数字”个刻度。第三种格式的工作方式与第二种类似,不同的是它是使用容器的时基。

有些人喜欢从实际时间开始,其他人则喜欢从帧数开始,都不是“错误的”。

从帧计数开始,您需要首先根据帧速率进行转换。 请注意,我说过的所有转换都使用av_rescale_q(...)。这种转换的目的是将计数器转换为时间,以便您以帧速率(通常是视频流时基)进行缩放。然后,您必须在编码之前将其转换为视频编解码器的time_base。

同样,在实时情况下,您的首次转换需要从current_time-start_time缩放到视频编解码器时间。

任何仅使用帧计数器的人都可能使用time_base等于其帧速率的编解码器。大多数编解码器无法像这样工作,并且它们的hack无法移植。例:

frame->pts = videoCodecCtx->frame_number;  // BAD

此外,任何在其av_rescale_q中使用硬编码数字的人都在利用这样的事实,即他们知道自己的time_base是什么,应该避免这种情况。该代码不可移植到其他视频格式。而是使用video_st-> time_base,video_st-> codec-> time_base和output_ctx-> time_base来解决问题。

我希望从更高的层次上理解它,可以帮助您了解哪些是“正确”的,哪些是“不良实践”。没有一个单一的答案,但是也许现在您可以决定哪种方法最适合您。

关于libav - 在FFmpeg中进行帧编码之前计算PTS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20909252/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com