首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FFMPEG:av_rescale_q - time_base差分

FFMPEG:av_rescale_q - time_base差分
EN

Stack Overflow用户
提问于 2017-09-30 21:31:46
回答 1查看 4.5K关注 0票数 13

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

从编解码器到流时基的重放输出数据包时间戳值

就像这样:

代码语言:javascript
复制
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);

但是在这个问题中,一个人问的问题和我的相似,他给出了更多的例子,每个例子都是不同的。相反,答案说,所有这些方法都是好的,对我来说,只有以下方法有效:

代码语言:javascript
复制
frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);

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

我明确指出:

代码语言:javascript
复制
video_st->time_base = {1,60};
video_st->r_frame_rate = {60,1};
video_st->codec->time_base = {1 ,60};

我看到的第一件奇怪的事情发生在我为输出格式上下文编写了标题之后:

代码语言:javascript
复制
AVDictionary *opts = nullptr;
int ret = avformat_write_header(mOutputFormatContext, &opts);
av_dict_free(&opts);

在此之后,video_st->time_base中填充了:

代码语言:javascript
复制
num = 1;
den = 15360

和我不明白为什么。

我希望有人能训斥我的that.Next,在编写框架之前,我计算包的PTS。在我的例子中,PTS = DTS,因为我根本不使用B帧。

我必须这样做:

代码语言:javascript
复制
 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流。在这种情况下,我计算的持续时间如下:

代码语言:javascript
复制
 const int64_t duration =
 ( video_st->codec->time_base.num / video_st->codec->time_base.den) * 1000;

WEBM需要乘以1000,因为时间戳是以毫秒为单位的,在container.And中,这是工作的。那么,为什么在MP4流编码的情况下,time_base中有一个必须重新缩放的区别呢?

EN

回答 1

Stack Overflow用户

发布于 2020-12-02 20:07:01

芬伯的这种行为也让我感到困惑。这里的用户对此进行了一些讨论-- 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,这样就不会更改。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46507210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档