🎬 第二章 FFmpeg命令行初体验
📄 一句话概括

625 行不是全画内容,去掉消隐只剩 576 行;宽度 720 是取样标准定的。 而且 720×576 的像素不是正方形,实际显示比例是 4:3。

📝 本节和前面几节的关系

2.8.1 把三种制式摆在一起比,这一节只把 PAL 这一条算到底。 2.8.3 用同一套方法算 NTSC,你会发现两者只差一个「打折比例」。

一、从 625 行到 576 行

625 是扫描总行数,但其中一部分是「消隐期」——那段时间电子束在回扫,不画内容。 扣掉上下消隐,真正画内容的正好是 576 行。

项 值 为什么是这个数


扫描总行 625 含消隐期,不是全都画内容 有效行 576 去掉上下消隐,正好 576 数字宽度 720 取样标准定死的,不是算出来的 帧率 25 50 场 ÷ 2

第三行的 720 常被误会成「算出来的」。不是。 它是 ITU-R BT.601 取样标准规定的每行取样点数,跟模拟的 625 行没有换算关系。

所以「720×576」这个组合里,576 来自模拟行数,720 来自数字取样标准。 两个数出自两套体系,只是凑巧拼在一起用了几十年。

二、像素不是正方形这件事

这是本节最值得记住的一点:720×576 的像素宽高比是 16:15,不是 1:1。

算法 结果 说明


按像素数直接除 1.2500 720 ÷ 576,这是错的 乘上像素宽高比 1.3333 1.25 × 16 ÷ 15 4:3 的标准值 1.3333 两者对上,说明算对了

第一行就是「画面被拉扁」的根源:播放器如果不认这个像素宽高比, 就会按正方形像素显示,把 4:3 的画面按 5:4 显示出来,看起来就是横向压扁了。

所以看到「视频比例不对」,第一件事不是去改分辨率,而是去查像素宽高比。 ffprobe 里那两个字段是 sample_aspect_ratio 和 display_aspect_ratio。

这也是为什么 720×576 和 768×576 两个分辨率可能显示出一模一样的大小—— 因为它们只是用不同方式表达了同一个 4:3。

三、一帧要多少字节

PAL 的像素量在今天的标准里很小,但换成裸数据仍然很吓人:

单位 字节 换算


一帧 yuv420p 622080 720×576×1.5 一秒 15552000 约 14.8 MB 一小时 55987200000 约 52.1 GB

52 GB 一小时是裸数据的量。压成 DVD 质量的 MPEG-2 大约 4 Mbps, 也就是每秒 0.5 MB,压缩比差不多 31 倍。

这个对比说明了一件事:模拟时代的存储问题,到数字时代变成了编码问题。 录像带能存一小时,靠的是磁记录密度;光盘能存一小时,靠的是压缩。

四、动手 Demo:625 行是怎么变成 720×576 的

把 PAL 的每一步换算都算一遍:行数怎么打折、像素宽高比怎么影响显示、一帧多少字节。 最后和 720p、1080p、4K 摆在一起,看像素量差多少倍。

# PAL 的关键参数
LINES, ACTIVE, WIDTH, FPS = 625, 576, 720, 25
SAR_N, SAR_D = 16, 15          # 像素宽高比 16:15

print(u"扫描行 %d,有效行 %d,宽度 %d" % (LINES, ACTIVE, WIDTH))

# 显示比例:不能直接用像素数除
raw = float(WIDTH) / ACTIVE
disp = raw * SAR_N / SAR_D
print(u"直接除 %.4f,乘上像素比 %.4f" % (raw, disp))
print(u"和 4:3 = %.4f 对上了吗:%s" % (4.0 / 3, abs(disp - 4.0 / 3) < 1e-4))

# 一帧与一秒的字节数
frame = int(WIDTH * ACTIVE * 1.5)
print(u"一帧 %d 字节,一秒 %d 字节(%.1f MB)"
      % (frame, frame * FPS, frame * FPS / 1024.0 / 1024))
print(u"一小时 %.1f GB" % (frame * FPS * 3600 / 1024.0 ** 3))

# 和其他分辨率比
for name, w, h in ((u"PAL", 720, 576), (u"720p", 1280, 720),
                   (u"1080p", 1920, 1080), (u"4K", 3840, 2160)):
    n = int(w * h * 1.5)
    print(u"%-6s %dx%d  一帧 %d  相对 PAL %.2f 倍"
          % (name, w, h, n, float(n) / frame))

实跑输出:

--------------------------------------------------------------------
PAL 制式——625 行是怎么变成 720×576 的
--------------------------------------------------------------------

**① 从模拟行数到数字分辨率,中间要打个折**

  项           值      为什么
  -----------------------------------------------------
  扫描行数     625     含消隐期,不是全都画内容
  有效行数     576     去掉上下消隐,正好 576
  数字宽度     720     取样标准定死的,不是算出来的
  帧率         25      50 场 ÷ 2

**② 720×576 的像素不是正方形**

**PAL 的像素宽高比是 16:15,也就是说像素比正方形稍微「胖」一点。**
**所以 720×576 显示出来的实际比例是 4:3,而不是 720:576。**

  算法               结果
  ------------------------------------------------
  按像素数直接算     720 ÷ 576 = 1.2500
  乘上像素宽高比     1.2500 × 16 ÷ 15 = 1.3333
  4:3 的标准值       1.3333

**这一条是很多人第一次遇到「为什么这个视频看起来被拉扁了」的根源:**
**播放器如果不认这个像素宽高比,就会按正方形像素显示,画面就被压扁了。**

**③ 一帧要多少字节,一秒钟要多少**

  项               值
  ---------------------------------------------
  一帧 yuv420p     622080 字节
  一秒             15552000 字节(14.8 MB)
  一小时           52.1 GB

**这是裸数据的量。压成 DVD 质量的 MPEG-2 之后大约是 4 Mbps,也就是每秒 0.5 MB。**
**压缩比大约 31 倍——这就是为什么模拟时代的存储问题,到数字时代变成了编码问题。**

**④ 和 1080p 摆在一起看**

  格式      分辨率        一帧字节     相对 PAL
  -------------------------------------------------
  PAL       720×576       622080       1.00×
  720p      1280×720      1382400      2.22×
  1080p     1920×1080     3110400      5.00×
  4K        3840×2160     12441600     20.00×

**4K 一帧是 PAL 的 20.0 倍。这个倍数解释了一件事:**
**同样用软件编码,4K 的耗时不是「慢一点」,是按这个倍数往上翻。**

第二段那个 disp 就是「显示比例」的正解:先算像素比,再乘像素宽高比。 很多工具只做第一步,结果把 4:3 算成 5:4,画面就扁了。

注意 abs(disp - 4.0/3) < 1e-4 这句判断——它是浮点比较,不能直接写等号。 算出来的 1.3333 和 4/3 在二进制里永远不会完全相等。

最后那张对比表里,4K 一帧是 PAL 的 20 倍。 这个倍数解释了一件事:同样用软件编码,4K 的耗时不是「慢一点」,是按这个倍数往上翻。

反过来,解码也有类似的比例关系,但没有编码那么夸张—— 因为解码只是还原,不需要搜索最优的压缩方式。 这也是为什么很多机器能放 4K 但编不了 4K。

30 秒实验

  1. 算一次:用 720×576×1.5 手算一帧字节,和 demo 的输出对一下。
  2. 看一个真文件:ffprobe -show_streams 找一个 PAL DVD 素材,看 sample_aspect_ratio 是不是 16:15。
  3. 转一次:ffmpeg -i in.mp4 -vf setsar=1 -s 768x576 out.mp4,把非方形像素转成方形,比一下文件。

常见误区

  1. 用 720÷576 算显示比例。算出 1.25 就错了,得乘像素宽高比 16:15 才是 1.3333。
  2. 以为 720 是从 625 换算出来的。720 是取样标准规定的每行取样点数,跟模拟行数没有换算关系。
  3. 看到画面拉扁就去改分辨率。先查 sample_aspect_ratio,问题多半在那儿,改分辨率反而更糟。
自测三问(点开对答案) 1. PAL 的 625 行里,为什么只有 576 行是画面内容? —— 其余是消隐期,电子束在回扫、不画内容。扣掉上下消隐,真正有效的正好是 576 行。 2. 720×576 实际显示成 4:3,怎么算出来的? —— 720÷576 = 1.25,再乘像素宽高比 16:15,得 1.3333,正好是 4:3。 3. 4K 一帧是 PAL 的多少倍?说明了什么? —— 20 倍。说明同样用软件编码,4K 的耗时是按这个倍数往上翻,不是「慢一点」。

相关笔记