gpt4 book ai didi

c++ - FFMPEG:av_rescale_q - time_base 差异

转载 作者:行者123 更新时间:2023-12-03 10:03:49 30 4
gpt4 key购买 nike

我想一劳永逸地知道时基计算和重新缩放在 FFMPEG 中是如何工作的。
在回答这个问题之前,我做了一些研究,发现了许多有争议的答案,这使得它更加困惑。
所以基于官方FFMPEG examples一个必须

rescale output packet timestamp values from codec to stream timebase



像这样:
pkt->pts = av_rescale_q_rnd(pkt->pts, *time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt->dts = av_rescale_q_rnd(pkt->dts, *time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt->duration = av_rescale_q(pkt->duration, *time_base, st->time_base);

但是在 this question一个人问了我类似的问题,他举了更多的例子,每个人的做法都不一样。与说所有这些方法都很好的答案相反,对我来说只有以下方法有效:
frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);

在我的应用程序中,我在 FFMPEG API 之外以 60 fps 的速度生成视频数据包 (h264),然后将它们写入 mp4 容器。

我明确设置:
video_st->time_base = {1,60};
video_st->r_frame_rate = {60,1};
video_st->codec->time_base = {1 ,60};

在我为输出格式上下文编写标题之后,我看到的第一件奇怪的事情发生了:
AVDictionary *opts = nullptr;
int ret = avformat_write_header(mOutputFormatContext, &opts);
av_dict_free(&opts);

之后, video_st->time_base填充有:
num = 1;
den = 15360

我不明白为什么。

我想请人解释一下。接下来,在写框架之前,我计算
数据包的 PTS。在我的情况下,PTS = DTS,因为我根本不使用 B 帧。

我必须这样做:
 const int64_t duration = av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
totalPTS += duration; //totalPTS is global variable
packet->pts = totalPTS ;
packet->dts = totalPTS ;
av_write_frame(mOutputFormatContext, mpacket);

我不明白,为什么编解码器和流具有不同的 time_base 值,即使我明确地将它们设置为相同。因为我在所有示例中都看到 av_rescale_q总是用来计算持续时间我真的很想有人解释这一点。

另外,作为比较,为了实验,我决定尝试为 WEBM 写流。容器。所以我根本不使用 libav 输出流。
我只是抓取用于编码 MP4 的相同数据包并将其手动写入 EBML stream .在这种情况下,我这样计算持续时间:
 const int64_t duration =
( video_st->codec->time_base.num / video_st->codec->time_base.den) * 1000;

WEBM 需要乘以 1000,因为时间戳在该容器中以毫秒为单位显示。这是有效的。那么为什么在 MP4 流编码的情况下,必须重新调整 time_base 的差异?

最佳答案

ffmpeg 的这种行为也让我感到困惑。用户在这里讨论了一点 - http://ffmpeg.org/pipermail/libav-user/2018-January/010843.html .但是那里的解决方案是只处理 15360 time_base 而不是对其施加控制。
从该论坛主题( https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/movenc.c ,搜索“* = 2”)中的发布者指出的来源,据我所知,它看起来不容易避免。看来您的选择是让 time_base 改变,或者选择 >= 10000 的东西,然后它就不会改变。

关于c++ - FFMPEG:av_rescale_q - time_base 差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46507210/

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