AIGC标识 同是 1080P,为什么有的视频糊?6 档码率压缩 PSNR 实测

同一张 1920×1080 的画面,压成 6 档码率,差距不用放大镜就能看出来。

1 Mbps 那一档只剩 3.7 KB/帧,PSNR 24.09 dB;32 Mbps 有 130.2 KB/帧,PSNR 33.45 dB。

图 1:6 档压缩结果同屏,低码率三档已经出现明显块状

两档标称分辨率完全一样,都是 1080P。

变的是每一帧能分到多少字节。

分辨率决定画布有多大,码率决定画布里能装多少细节。

为什么这件事值得看

视频平台给每个视频分配的码率不一样。

同一个 1080P 标签,可能是 1 Mbps 的会议录屏,也可能是 30 Mbps 的相机原片。

码率不够时,编码器先丢掉高频细节,再放大色块。

画面先变软,接着出现方块,最后连边缘都糊成一片。

看懂这件事,至少能回答三个日常问题。

为什么下载的“高清”电影只有 2 GB。

为什么手机拍的视频发到群里就糊。

1 小时 4K 视频到底要占多少硬盘。

准备环境:进入码道 Web

浏览器打开码道 Web 版:https://devcloud.cn-north-4.huaweicloud.com/chat?source=dmzntgwlb&sourcead=dmzntgwlb1&invitecode=INV-IXhxk5bwWx_qKSP1FcgSuiOEf6ruDXtjvLFiCH9nMs5dZGLapaSSylwt-cKRj5LoT3MlxikWxy8VhqplfvtQjefQOq31Tbp3R3wYP3K535Cn4XTaUzqqExKPYTWvvw4LijV14IS1torXdTGp7oyXb6SR5VxgYTg50jM,登录后直接在对话窗口输入需求。

码道有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

我让码道做了什么

需求写死了六件事:内置 1080P 测试画面、6 档码率、真实 JPEG 字节数、逐像素 PSNR、可拖动分屏对比、8 条自检。

码道交付的是一个单文件 index.html,没有外部依赖。

页面左边是控制区,右边是结果、曲线、换算器和自检面板。

内置画面由 Canvas 画出来,有天空渐变、树叶、水波和噪点,细节足够多,压缩损失看得见。

每次点“开始压缩”,6 档全部重算,实测耗时 1.37 秒。

验证一:6 档数据都是当场算的

每一档都记录真实字节数,再反推实际码率和 bpp。

PSNR 是把压缩图解码回 1920×1080 后,与原图逐像素比较算出来的。

目标码率 实际字节/帧 实际码率 JPEG q 编码尺寸 PSNR 实际 bpp
1 Mbps 3.7 KB 0.91 Mbps 0.064 672×378 24.09 dB 0.015
2 Mbps 8.3 KB 2.04 Mbps 0.050 1152×648 24.04 dB 0.033
4 Mbps 15.5 KB 3.81 Mbps 0.054 1632×918 24.48 dB 0.061
8 Mbps 30.4 KB 7.47 Mbps 0.082 1920×1080 27.36 dB 0.120
16 Mbps 64.0 KB 15.72 Mbps 0.194 1920×1080 30.67 dB 0.253
32 Mbps 130.2 KB 32.00 Mbps 0.504 1920×1080 33.45 dB 0.514

先看低三档。

1 Mbps 目标每帧只有 4.17 KB,1080P 全尺寸 JPEG 即使 q=0.05 也远不止这个数。

所以它先把编码尺寸降到 672×378,再用 q=0.064 压到 3.7 KB,最后放大回 1080P 算 PSNR。

2 Mbps 用 1152×648,4 Mbps 用 1632×918。

8 Mbps 以上才回到全尺寸 1080P。

这里有个反直觉的细节:2 Mbps 的 PSNR 比 1 Mbps 低 0.05 dB。

不是算错,是两档踩在不同的分辨率台阶上,损失的结构不一样。

自检对这条曲线给了 ±0.5 dB 容差,并把这个前提写在了结果里。

图 2:1 Mbps 分屏对比,右边已经变成一块一块的色斑

把 1 Mbps 那档放大,左边原图还能数清树叶,右边已经是一块一块的色斑。

图 3:32 Mbps 分屏对比,分屏线两侧几乎看不出差别

换到 32 Mbps,分屏线两侧几乎看不出差别。

PSNR 33.45 dB 不算高,但在这个画面和这个观看尺寸下,肉眼已经够用。

再看 bpp。

32 Mbps 在 1080P、30fps 下是 0.514 bit/像素/帧。

1 Mbps 只有 0.015,差了 34 倍。

bpp 比 Mbps 更适合横向比较不同分辨率。

同样是 8 Mbps,1080P 是 0.129 bpp,4K 只有 0.032 bpp。

换算器算的是另一头。

4K、60fps、50 Mbps,一小时 20.95 GB,一部两小时电影 41.91 GB。

100 Mbps 宽带只够同时看 2 路。

这些数字按 1 GB = 1024 MB 计算,不含容器开销。

图 4:换算器切到 4K 60fps 50 Mbps,结果实时重算

验证二:页面自检 8/8 通过

页面自带 8 条断言,点一次全部跑完。

  • 相同画面 PSNR 为 ∞ 或 ≥ 60 dB
  • 码率升高时 PSNR 不下降,容差 0.5 dB
  • 实际字节不超过目标字节的 110%
  • bpp 与 Mbps、像素数、帧率的关系一致
  • 折线图数据点等于 6
  • 压缩图解码后仍是 1920×1080
  • 目标字节等于码率 ÷ 8 ÷ 帧率
  • 实际 Mbps 等于字节 × 8 × 帧率

最后是 8/8 全过。

但第一次跑并不是。

真实踩坑:低码率根本压不到

第一版只搜 JPEG 质量 q。

结果 1 Mbps 实际字节是目标的 5.16 倍,2 Mbps 是 2.58 倍,4 Mbps 是 1.29 倍。

三档全都卡在 q=0.05,PSNR 都是 24.58 dB。

这不是实验,是同一个结果换了三个标签。

自检里的“实际字节 ≤ 目标字节的 110%”直接把它拦下来了。

修复办法是加一列分辨率台阶。

从 1.0 到 0.1 共 13 档,先找一档 q=0.05 能压进目标 110% 的尺寸。

找到后再二分搜索 q,让字节数贴近目标。

压完再放大回 1080P,和原图逐像素算 PSNR。

改完之后,6 档全部落在 110% 内,低三档也终于有了各自的损失曲线。

这不是给页面补一个假数字,而是把“码率不够时先降分辨率”的真实取舍写进了实验。

复现与失败路径

本地起一个静态服务,打开页面,点“开始压缩”即可。

python -m http.server 8000

自检 8/8,6 档总耗时 1.37 秒。

失败路径也测了。

帧率填 0 再点开始,页面给出红色提示:帧率必须大于 0,当前输入无效;已保留上一次有效结果。

6 档结果和曲线都还在,没有白屏。

图 5:帧率填 0 的失败路径,中文提示出现且上一次结果保留

使用码道的一点体会

这次最有用的一句需求,是“所有计算必须真实执行,不能写死假数据”。

码道按这句话把 JPEG 字节数、PSNR、bpp 都做成了运行时计算,自检也能查出问题。

但它一开始没想到 1080P JPEG 有码率下限。

所以自检不是装饰。

断言写对了,它能在发布前把实验设计的问题拦下来。

另外,需求里把 6 档、8 条断言、失败提示都写成可验收的句子,返工明显少。

边界:它不模拟完整视频编码

这是一次单帧帧内压缩实验,不是完整视频编码。

页面用 JPEG 模拟每一帧的帧内压缩,没有 H.264、VP9 的帧间预测、运动补偿和码率控制。

所以 PSNR 的绝对值不能直接和真实视频编码器对比。

它复现的是“字节不够时细节怎么丢”,不是“某个编码器在某个片源上的真实表现”。

测试画面也是程序生成的,换成真实拍摄素材,数字会变。

想更接近真实,可以把同一段视频用不同码率转码,再逐帧算 PSNR,那是下一步。

结论

1080P 只是分辨率,不是清晰度承诺。

同一分辨率下,码率决定每帧能分到多少字节。

bpp 决定这些字节够不够铺满像素。

下次看到“高清”两个字,先问一句:多少码率。

想自己试,可以打开码道复刻这个需求,也可以直接看公开示例:https://atomgit.com/deli007/demo_park/tree/main/codearts-video-bitrate-lab。

posted @ 2026-11-06 07:43  新科技观察员  阅读(3)  评论(0)    收藏  举报