1.2 信号地基:采样、帧率与时间戳


1.2 信号地基:采样、帧率与时间戳

本节摘要:视频与音频在电脑里不是「画面」和「声音」,而是一串数字。本节讲清三个地基概念——采样率、帧率与时间戳,并给出它们在 FFmpeg 里的实际换算方法,为理解码率、同步问题打底。

本节目标:阅读完本节,你应当能够:

  1. 解释视频帧率、分辨率、音频采样率、位深各自测量什么
  2. 做一次「原始未压缩数据量」的估算,理解为什么必须压缩
  3. 说出 PTS 与 DTS 的区别,理解时间戳如何决定音画是否同步

一、一段历史:从胶片到比特

胶片时代,「一帧画面」是物理存在的:一格胶片就是一幅图。每秒 24 格,连续放映就是运动。这个朴素的直觉一直延续到了数字时代,也成了不少误解的源头——很多人以为视频文件里存的也是一帧帧完整的图片。

真相是:视频文件里存的几乎全是「压缩后的差异信息」。电影里一个静止镜头,连续几百帧其实只有极少的数据变化。这个「先讲清帧,再讲差异」的逻辑,是理解 H.264、HEVC 一切压缩技巧的前提。而这一切,都建立在本节的三个数字地基上。

二、三个地基概念

采样与帧率

音频按采样率测量:每秒采多少个点,常用 44100 Hz(CD 品质)、48000 Hz(视频行业标准)。位深决定每个采样点用多少比特描述,16 bit 是最低常见配置。两者相乘就是每声道每秒的原始数据量。

视频按帧率测量:每秒多少帧,电影 24 fps、国内电视 25 fps、欧洲 25 fps、游戏录制常用 30/60 fps。每帧的分辨率(如 1920×1080)决定了单帧数据量。帧率越高越流畅,但数据量也越大。

原始数据量怎么算

单帧原始大小 = 宽 × 高 × 每像素字节数。以常见的 YUV420 像素格式为例,每像素平均 1.5 字节(Y 全量 + 色度各四分之一)。

  • 1080p 单帧:1920 × 1080 × 1.5 ≈ 3.1 MB
  • 30 fps 一秒:约 93 MB
  • 两小时电影:约 670 GB

所以不压缩是不可能的。压缩的全部目标,就是用更少的比特尽量还原人眼能接受的画面——这直接决定了第 5 章编码参数怎么选。

PTS 与 DTS:时间戳的两个角色

压缩会引入帧之间的依赖。比如 H.264 里有 I 帧(关键帧,完整画面)、P 帧(参考前面的帧)、B 帧(参考前后两帧)。因为 B 帧要参考后面的帧,解码顺序和显示顺序就分道扬镳了:

  • DTS(解码时间戳):告诉解码器「按什么顺序解开这堆数据」
  • PTS(显示时间戳):告诉渲染器「按什么顺序把解出来的帧摆到屏幕上」

FFmpeg 里所有「音画不同步」问题,追根溯源几乎都是 PTS 在某个环节被弄乱了——裁剪、变速、丢帧、流拼接,每个操作都可能重排时间轴。

下面用一张图把「采样→压缩→时间戳」串起来,这也是 FFmpeg 处理数据的最小心智模型。

01-02-fig01

图说明:数据流的时间线

从模拟信号到数字流要过四道关。采样量化把连续信号变成离散数字,压缩编码把原始数据大幅缩小但引入帧间依赖,时间戳标注把「解码顺序」和「显示顺序」分开记账,最后封装成流放进容器。每一步都有对应的 FFmpeg 概念,第 2、3 章会逐一对应到命令行和数据结构上。

三、工程实践要点

在 FFmpeg 里验证一下上面的概念,胜过背十遍定义。假设你有一个视频 input.mp4,执行:

# 用 ffprobe 看一个文件的真实结构:流、编码、时间基准 ffprobe -v error -show_streams -show_format input.mp4

输出里的关键字段(节选示意):

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4': Duration: 00:00:10.04, start: 0.000000, bitrate: 952 kb/s Stream #0:0: Video: h264, yuv420p, 1280x720, 30 fps Stream #0:1: Audio: aac, 48000 Hz, stereo, fltp

解读:这是 MP4 容器(mov,mp4,...),10 秒时长、总码率 952 kb/s;Stream #0:0 是视频流,H.264 编码、yuv420p 像素格式、1280×720、30 帧每秒;Stream #0:1 是音频流,AAC 编码、48 kHz 采样率、双声道。注意编号 0:0 的含义——前一个 0 是输入文件序号,后一个 0 是流序号,第 3 章用 -map 时会反复用到。

实际开发中关于「时间基准」最常踩的坑在流拼接。两个视频帧率不同,直接拼会越拼越不同步,原因就是各自的时间基准不一致。碰到这种情况,先统一帧率再拼,或者用 setpts 强制重排时间戳(第 4 章会讲具体命令)。

⚠️ 常见坑:fps 数字写在流信息里,但很多文件没有固定帧率(VFR,可变帧率)。手机竖屏录制尤其常见。对 VFR 文件做精确剪辑时,用 -vsync-fps_mode 显式指定处理策略,否则输出可能忽快忽慢。

💡 关键直觉:所有同步问题的根子都在时间戳,不在画面本身。先确认「PTS 有没有乱」,再谈其他,能省下大量排查时间。

帧率与采样率为什么会互相牵扯

转码时有一个容易被忽略的事实:视频帧率和音频采样率不匹配本身不是问题,因为它们是两条独立的流,各走各的时间轴,靠时间戳对齐。真正的问题是「重新封装时时间基准被改变」。比如把 30 fps 的视频丢进一个假定 25 fps 的流程,播放器按错误的帧率换算时长,结果就是画面快进或慢放。

所以 FFmpeg 里有个「时间基准」概念(timebase),它决定时间戳用什么单位计数。日常命令中你很少直接碰它,但一旦出现音画不同步,第一个怀疑对象就是「输出文件的 timebase 和输入不一致」。到第 8 章用 SDK 写转码程序时,你会显式地给输出流设置 timebase,那时本节的理论就变成了必须执行的代码。

要点回顾

  • 采样率与帧率:音频讲采样率与位深,视频讲帧率与分辨率,两者衡量维度不同,别混用
  • 原始数据量巨大:1080p30 一秒约 93 MB,压缩是必然,压缩目标是在比特与观感之间找平衡
  • I/P/B 帧结构:帧间参考让解码顺序与显示顺序分离,这就是 PTS 与 DTS 存在的原因
  • 时间戳是同步的根:PTS 决定显示顺序,DTS 决定解码顺序,任何一个环节弄乱都会音画不同步
  • 容器与流分层:一个文件是容器,里面可以装多条流,每条流有自己的编码与时间基准

下一节,我们把目光从「数据长什么样」转向「FFmpeg 内部怎么组织」——第 2 章讲它的骨架。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U