三个常见 time base

tbc → time base (codec)

Codec 层的时间基数
在 FFmpeg 里是 AVCodecContext->time_base
表示「编码器/解码器理解的时间单位」
常见:
视频:1/framerate(例如 1/30)
音频:1/samplerate(例如 1/48000)

tbn → time base (stream)

Stream 层的时间基数
在 FFmpeg 里是 AVStream->time_base
表示「容器 / 协议使用的时间戳单位」
常见:
MP4/MKV → {1,1000} 毫秒
TS/RTP → {1,90000}(90 kHz 时钟)
RTMP → {1,1000} 毫秒
音频轨 → 通常 {1,sample_rate}

tbr → time base (rate)(准确说是 frame rate guess)

avg_frame_rate / r_frame_rate
ffmpeg 根据 PTS 统计出来的平均帧率
给人看的帧率估算就是不是时基,只

为什么有了 tbc 还应该有 tbn

音视频的 tbc 本来就不一样。
视频:1/30 → 每个 PTS 单位 = 0.0333 秒
音频:1/48000 → 每个 PTS 单位 = 0.0000208 秒
如果直接把它们丢进容器,播放器根本没法对齐(一个用 0.0333s 计时,一个用 0.0000208s 计时)。
所以,容器层引入 统一的 time base(tbn):
所有流的时间戳都要 rescale 成 同一种“货币单位”,比如毫秒或 90kHz。
这样容器里的音视频轨才能对齐,播放器才能同步解码和播放。

什么时候得转换时间基

一帧视频的渲染时间为 pts*时间基;
当刚开始 pts 的时间基是以 tbc 为单位保存的,在录制和发送前需要将 pts 和 dts 转换成对应协议的时间基下的 pts 和 dts。

btn 的时间基是怎么来的,可以改变吗?

btn 的时间基是每种协议根据自身场景,定义出来的,不能随意改变。

  • MPEG-TS / RTP(H.264) → 90 kHz
    来自广播电视标准(MPEG-2 Systems),定义了 PCR/PTS/DTS 的时钟基准是 90 kHz。
    90 kHz 刚好是 27 MHz 时钟(硬件常用)除以 300,方便整数除法。
    因此 TS、RTP 推流几乎都用 90 kHz time base。
  • MP4/MOV → 通常 1/1000 或者其他 timescale(trak 级别可变)
    ISO BMFF 规范里,timescale 是一个整数,表示“一秒有多少时间单位”。
    写文件时 muxer 通常选 1000(毫秒)或者 600/48000(和音频采样率对齐),便于人类可读或和音频同步。
  • MKV/WebM → 1/1000 秒
    Matroska 规定了默认 timecode scale 是 1ms,因而大部分 MKV 就是 {1,1000}。
  • AVI → 多数情况下 1/帧率
    AVI 比较古老,直接用 dwScale/dwRate 定义帧率关系。
    RTMP → 毫秒
    Adobe RTMP 协议规定时间戳就是毫秒。
posted on 2025-09-19 09:04  ycfenxi  阅读(7)  评论(0)    收藏  举报