当前位置: 首页 > news >正文

FFmpeg时间基相关函数大杂烩

目录

一、核心时间基概念速记

二、时间基转换「主函数表」(最重要)

三、AVRational 工具函数表

四、FFmpeg 内置时间基常量

五、不同场景「怎么选函数」对照表

1️. Packet PTS → 毫秒(最常用)

2️. Frame PTS → 秒(double)

3️. 音频 frame → 下一帧 pts(防抖动)

4️. Seek 时间戳(必须 round)

5️. 音视频同步(master clock = audio clock)

六、av_rescale_q_rnd 的 rounding 参数详解

七、Stream / Codec / Frame 时间基到底用哪个?

八、完整“黄金模板”

九、时间基“血泪坑”速查表

十、一句话总结


觉得有用,就请您帮忙点赞转发收藏吧,您的鼓励是我创作的动力,多谢看官。

由于能力水平有限,文中的错误或不严谨的地方在所难免,还请批评指正。

FFmpeg 在处理视频和音频时,经常需要与时间基(time base)相关联的操作。时间基是视频和音频处理中的一个核心概念,它定义了帧之间的时间间隔。FFmpeg 提供了一系列的函数和工具来帮助开发者处理与时间基相关的问题。


一、核心时间基概念速记

名字

类型

含义

AVRational

{int num, den}

时间单位:1 / den

time_base

AVRational

一单位 pts 等于多少秒

pts / dts

int64_t

时间戳(单位是 time_base)

AV_TIME_BASE

1000000

ffmpeg 内部时间:微秒

公式一句话:

真实时间(s) = pts × num / den

二、时间基转换「主函数表」(最重要)

函数

原型 / 参数

用途

常见场景

av_rescale_q()

(a, src_tb, dst_tb)

pts 从 A 时间基 → B 时间基

99% 用这个

av_rescale_q_rnd()

(a, src, dst, enum AVRounding)

同上 + 四舍五入 / ceil

音频 / 精确对齐

av_rescale()

(a, b, c)

a*b/c防止溢出

自己算 ratio

av_rescale_rnd()

(a, b, c, rnd)

带 round 的整数 rescale

底层封装

av_mul_q()

(AVRational a, AVRational b)

rational 乘法

推导 time_base

av_div_q()

(a, b)

rational 除法

fps ↔ duration

av_add_q()/av_sub_q()

(a,b)

rational 加减

偏移时间

记住一句话:FFmpeg 里永远用av_rescale_q()做 pts 转换


三、AVRational 工具函数表

函数

作用

示例

av_make_q(num, den)

构造 AVRational

AVRational tb = av_make_q(1, 1000);

av_d2q(d, max)

double → AVRational

tb = av_d2q(1.0/44100, 100000);

av_q2d(tb)

tb → double 秒

sec = pkt->pts * av_q2d(tb);

av_inv_q(tb)

倒数

fps → 每帧秒数

av_reduce()

约分 rational

内部用


四、FFmpeg 内置时间基常量

常量 / API

含义

AV_TIME_BASE

1000000(微秒)

AV_TIME_BASE_Q

(AVRational){1, AV_TIME_BASE}

av_get_time_base_q()

返回AV_TIME_BASE_Q

音视频同步常用目标:

dst_tb = AV_TIME_BASE_Q; // 微秒 dst_tb = av_make_q(1,1000); // 毫秒

五、不同场景「怎么选函数」对照表

1️. Packet PTS → 毫秒(最常用)

int64_t ms = av_rescale_q(pkt->pts, stream->time_base, av_make_q(1, 1000));

av_rescale_q


2️. Frame PTS → 秒(double)

double sec = pkt->pts * av_q2d(stream->time_base);

av_q2d(只读不写)


3️. 音频 frame → 下一帧 pts(防抖动)

AVRational tb = codec_ctx->pkt_timebase; int64_t next_pts = av_rescale_q( frame->nb_samples, av_make_q(1, frame->sample_rate), tb );

推导音频时钟


4️. Seek 时间戳(必须 round)

int64_t seek_ts = av_rescale_q_rnd( target_ms, av_make_q(1, 1000), stream->time_base, AV_ROUND_DOWN // 或 AV_ROUND_NEAR_INF ); avformat_seek_file(fmt_ctx, audio_idx, INT64_MIN, seek_ts, INT64_MAX, 0);

seek 必须用_rnd


5️. 音视频同步(master clock = audio clock)

double vid_clk = vid_pkt->pts * av_q2d(vid_tb); double aud_clk = aud_pkt->pts * av_q2d(aud_tb); double diff = aud_clk - vid_clk;

六、av_rescale_q_rnd 的 rounding 参数详解

行为

用途

AV_ROUND_ZERO

向 0 取整

不推荐

AV_ROUND_INF

远离 0

很少用

AV_ROUND_DOWN

向下

✅ seek(避免越界)

AV_ROUND_UP

向上

buffer size

AV_ROUND_NEAR_INF

四舍五入

✅ 显示时间 / 音频对齐

AV_ROUND_PASS_MINMAX

保留 INT64_MIN/MAX

内部用

推荐记忆:

seek → AV_ROUND_DOWN ui ms → AV_ROUND_NEAR_INF

七、Stream / Codec / Frame 时间基到底用哪个?

这是新手地狱,直接给结论表:

对象

pts 所在 timebase

怎么转

AVPacket

AVStream::time_base

av_rescale_q(pkt->pts, st->time_base, dst)

AVFrame(video)

AVCodecContext::pkt_timebasest->time_base

解码后一般继承 stream

AVFrame(audio)

解码后建议转成1/sample_rate

自己算

avformat_seek_file()

AVStream::time_base

别用 AV_TIME_BASE

经典错误:

avformat_seek_file(fmt_ctx, idx, ..., ms, ..., 0); // ❌ ms 直接塞

八、完整“黄金模板”

static int64_t pts_ms(AVPacket *pkt, AVStream *st) { return av_rescale_q_rnd( pkt->pts, st->time_base, av_make_q(1, 1000), AV_ROUND_NEAR_INF ); } static int64_t pts_us(AVFrame *frm, AVStream *st) { return av_rescale_q(frm->pts, st->time_base, AV_TIME_BASE_Q); }

九、时间基“血泪坑”速查表

结果

pkt pts 当秒用

快进 1000 倍

seek 用微秒直接塞

seek 到天边

audio frame 用 video timebase

声音飞走

rescale 不 rnd

帧跳

pkt/dts 混用

B 帧倒放


十、一句话总结

FFmpeg 时间基只有三条铁律:

1️.pts 永远是int64_t,单位是AVRational

2️.转换只用av_rescale_q()/av_rescale_q_rnd()

3️.seek / 显示 / 同步各选一个主时钟,统一 rescale 再比

http://www.jsqmd.com/news/1368679/

相关文章:

  • 5步修复老旧Mac网络功能:OpenCore Legacy Patcher让你的WiFi重新工作
  • Godot-Mixing-Desk API完全参考:从基础函数到高级应用
  • 终极指南:如何用OpCore Simplify工具30分钟完成Hackintosh系统配置
  • React 现代化 Web 应用开发:本地环境怎样一次跑通
  • 嵌入式处理器虚拟化仿真技术(九)——SimpleScalar原理与应用
  • 15-07-YooAsset面试篇-Unity性能优化与内存管理
  • Orb二次开发指南:扩展自定义数据接收器的完整步骤
  • Hello-World项目中的奇葩语言:Brainfuck与Whitespace代码解析
  • 深入解析金庸群侠传C++重制版:现代游戏引擎架构实战指南
  • 5步快速部署Alpamayo:终极自动驾驶推理模型实战指南
  • FFmpeg中根据枚举获取名称的相关函数总结,例如av_get_sample_fmt_name和avcodec_get_name等
  • 3个技巧让Windows窗口管理效率翻倍:FancyZones深度指南
  • 日记于8月10日
  • 如何在macOS上快速启用OBS虚拟摄像头:新手完整指南
  • 短剧、虚拟制片行业缺口扩大,拆解梵映、好影两大线上影视后期机构教学适配度差异 - 生活动态圈
  • OpenScan隐私优先文档扫描:如何在3分钟内实现本地化文档数字化管理
  • 【单片机毕业设计推荐】基于 STM32 单片机的智能饮水设备控制系统设计与实现,基于 STM32 与 ESP‑01S 的物联网饮水监控系统设计(012106)
  • 如何精通DevOps Interview Guide中的数据仓库运维:Snowflake与Redshift实战指南
  • Pock:5个高效技巧彻底改造你的MacBook Touch Bar体验
  • 为什么你的RAG回答忽好忽坏?问题通常出在这5个地方
  • 2026年常州市万华机房设备有限公司:江苏源头工厂防静电与网络地板实力观察 - 优企名品
  • 从js闭包谈到作用域、作用域链、执行上下文、内存管理
  • 5分钟快速上手:RuoYi-Vue权限管理系统的完整部署指南 [特殊字符]
  • 快消行业常用的管理软件有哪些?从进销存到BI一文明白
  • 2026三明卫生间漏水避坑指南 - 房屋修缮
  • 小白程序员必看:收藏这份AI大模型学习指南,轻松入门大模型时代!
  • 如何安全合规地处理微信数据:从开源项目下架看技术合规的重要性
  • 如何用Rust构建跨平台Android去预装应用工具:Universal Android Debloater完整指南
  • Tendermint-rs核心组件解析:Light Client如何保障区块链数据安全?
  • 深入理解DeferredTexturing核心技术:延迟纹理与传统延迟渲染的差异对比