FFmpeg时间基相关函数大杂烩

目录

一、核心时间基概念速记

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

[三、AVRational 工具函数表](#三、AVRational 工具函数表)

[四、FFmpeg 内置时间基常量](#四、FFmpeg 内置时间基常量)

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

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

[2️. Frame PTS → 秒(double)](#2️. Frame PTS → 秒(double))

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

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

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

[六、av_rescale_q_rnd 的 rounding 参数详解](#六、av_rescale_q_rnd 的 rounding 参数详解)

[七、Stream / Codec / Frame 时间基到底用哪个?](#七、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_timebase或 st->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 再比

相关推荐
VidDown1 天前
自动给视频挑一张能看的封面:帧评分、构图与批量生成
python·ffmpeg·音视频·视频
可乐鸡翅yeah_2 天前
HLS 业务 Referer‑Policy 网页元标签引发播放异常排错
前端·javascript·网络·ffmpeg·php·音视频
开开心心就好3 天前
本地文件搜索工具推荐,占用小速度还快
智能手机·ffmpeg·ocr·word·音视频·网络攻击模型·安全架构
我科绝伦(Huanhuan Zhou)3 天前
oracle坏块导致备份不了
数据库·oracle·ffmpeg
RS迷途小书童3 天前
Python+FFmpeg提取大疆无人机MP4内嵌mov_text遥测SRT字幕并做完整性校验
python·ffmpeg·大疆·srt字幕·dji
开开心心就好3 天前
视频压缩工具推荐,画质效果很能打
智能手机·ffmpeg·ocr·word·排序算法·音视频·散列表
可乐鸡翅yeah_4 天前
业务中 M3U8 水印相关坑,硬水印和动态水印区别
前端·网络·数据库·ffmpeg·m3u8在线
redfred4 天前
HyperFrames 部署教程:5.6 万 Star 开源「写 HTML 出视频」框架,Windows 从零上手(CLI 三条命令 + 7 个避坑)
ffmpeg·开源·自动化·html·音视频
Arcai10244 天前
PostgreSQL数据备份和恢复完全指南
数据库·postgresql·ffmpeg·备份一体机·备份软件·smartstor·智备科技
可乐鸡翅yeah_5 天前
FFmpeg 生成 HLS 独立分片 independent‑segments 参数到底有什么用
javascript·ffmpeg·音视频·safari·m3u8