为什么同一个视频在 mpv 和 IINA 中比在 QuickTime 中暗

在 Mac 上把同一个文件并排在 QuickTime 和基于 mpv 的播放器中打开,mpv 那边看起来更暗,暗部也更沉。两个播放器都没有坏。它们用两条不同的色调曲线读取同一个视频。我们把两条曲线都测量了,下面说明差别是什么、标准站在哪一边,以及如何得到另一种效果。

更新于

在 Mac 上把同一部电影分别放进 QuickTime 和 IINA、mpv 或 Frame Player,基于 mpv 的那几个看起来更暗:昏暗房间里的人脸失去轮廓,夜景变成一片漆黑中的几点灯光。常见的解释是 mpv“把暗部压死了”,或者文件没有色彩信息,mpv 猜错了。我们测量了一下,发现两种说法都不太对。

差别究竟是什么

测试用的是一帧 H.264 视频,上面有十六条已知亮度的灰条,在同一台 MacBook Pro 的显示屏上分别用 QuickTime 和 Frame Player 播放,截取两个窗口并逐像素读取。下面的数字是每个播放器发送到屏幕的值,满分 255:

文件中的亮度(16 = 黑,235 = 白)QuickTimempv 的曲线差值
203.74.3+0.6
2811.013.6+2.6
4029.727.6−2.1
6463.355.5−7.8
96102.391.6−10.7
128(中灰)140.0128.7−11.3
160176.7167.1−9.6
224242.7240.6−2.1

有两点很明显。最暗的几级在 mpv 中根本没有更暗,反而亮了一两级。mpv 画得更暗的是中间调偏暗的部分,最多暗 12 级。昏暗场景的大部分内容就在这个范围里,所以看起来像是丢失了暗部细节。

在真实画面上,差距的形状相同:在一帧明亮的动画画面上,整个画面的平均值在 QuickTime 中是 177.5,在 mpv 的曲线下是 170.9;文件本身暗部的像素则是 54.6 对 47.9,大约暗了八分之一。

色彩本身完全相同。纯红在 QuickTime 中是 232、51、35,在 Frame Player 中是 231、50、34。这是色调曲线的差异,而不是色彩偏移。

原因:读取 BT.709 的两种方式

几乎所有 SDR 视频(电影、剧集、YouTube)都是 BT.709。这个标准规定的是画面如何编码;屏幕应如何把它还原成光,是另一个标准 BT.1886 规定的,它描述的曲线大约为 2.4,适用于昏暗的房间,也就是调色师调色时所在的那种房间。

  • mpv 把视频的数值原样交给屏幕。然后 Mac 的显示器用自己的曲线读取,接近 2.2,比参考的 2.4 稍亮,但属于同一类。
  • QuickTime 用约 1.96 的曲线解码 BT.709,再为显示器对结果进行编码。在中灰处,这就是 140 而不是 129。这是 Apple 由来已久的选择,视频剪辑师称之为“QuickTime gamma shift”,而且与我们的测量结果非常吻合:该模型预测 64 那一条为 63.6,中灰为 141;QuickTime 显示的是 63.3 和 140。

所以按标准,mpv 较暗的画面更接近。按习惯,在 Mac 上,QuickTime 较亮的画面才是大家熟悉的:系统自带播放器显示的就是它,而且根据促成这次测试的那些反馈,其他基于 Apple 视频框架的播放器显示的也是它;在 Mac 上剪辑和检查的视频,往往就是按这种样子审定的。两者都不是 bug,也都不是在任何情况下都正确。

“文件没有色彩信息”

很多关于这个问题的反馈都涉及 MKV 文件,ffprobe 显示它们没有 color_space,也没有 color_range,所以人们自然会怀疑是播放器猜错了。我们去掉了测试视频的所有色彩标记,然后又做了一个正确标记为 BT.709 的副本。两个播放器对标记和未标记的副本画得完全一样,每一条都一样。对于未标记的高清视频,mpv 假定为 BT.709,QuickTime 也是;然后它们各自按自己的方式绘制 BT.709。给你的文件加上标记,不会改变任何一方的画面。

彩条测试测的是什么

比较这些播放器的另一种方法是 SMPTE 彩条:以 BT.709 生成彩条,用数码测色计在“以 sRGB 显示”模式下从屏幕上读取每一条,然后计算与“理论”值的平均偏差。我们也做了这个测试,结果发现它在测量色彩之前,先测量了另外两样东西。

首先是范围。彩条以有限范围视频存储,其中黑色的代码值是 16,75% 的彩条是 180。播放器应当把它拉伸到屏幕的 0–255:(180 − 16) × 255 / 219 = 191,而 16 变成 0。如果把“理论”值取为 180 和 16,也就是文件中的数值,那么每个正确解码文件的播放器都会被扣分,每个满通道扣 11 级,每个空通道扣 16 级,而跳过拉伸的播放器看起来却几乎完美。我们用两个每个像素都相同的文件做了验证,一个标记为有限范围,一个标记为完整范围:同一个播放器、同样的像素,正确解码时相对 180/16 的得分是 12.9,被告知不拉伸时是 1.9。以正确的 191/0 为参照则正好相反,分别是 0.5 和 11.4。以 180/16 为参照的排名,排的是播放器是否扩展了范围。

然后是曲线。以正确的数值为参照,Frame Player 的默认效果平均偏差 0.3 级,QuickTime 为 3.3 级,我们的“与 macOS 一致”设置为 3.6 级,恰恰因为它与 QuickTime 一致。这是 mpv 的惯例在给自己打分:把正确扩展后的数值不加任何曲线地发送到屏幕,正是 mpv 的做法。这个分数告诉你播放器遵循哪种惯例,而不是它是否准确。

而且它掩盖了大部分差异。27 个色块中有 7 个是纯黑或纯白,所有曲线在这里都一致;其余大多是 75% 的颜色,位于曲线的顶部附近;只有两个是中间调。QuickTime 和 mpv 在彩条上的平均差异是 3.4 级,而一组普通的灰阶在中间调上显示的差异是 8.3 级,是前者的两倍多,而且恰恰位于昏暗场景实际所在的那部分画面。如果你想看到这个差异,要看灰色,而不是彩条。

流传的配方,以及它为什么对我们不管用

为 IINA 流传的修复方法通常是三项 mpv 设置:

gamma-factor=1.1218765935747068
vf=format=gamma=gamma2.2
icc-profile-auto=yes

前两项是核心:它们让 mpv 把视频当作一条普通的 2.2 曲线,再按 2.2 / 1.961(也就是 Apple 的 1.96)进行弯曲。在 Frame Player 中,用上这两项后色调曲线是对的。但第三项,即显示器的 ICC 描述文件,让每种颜色都变淡了:纯红从 232、51、35 变成 213、68、49,绿色从 117、251、76 变成 152、244、103。画面被做了两次色彩管理:一次是 mpv 为显示器做的,另一次是 macOS 做的,它本来就会自行为屏幕转换 Frame Player 的视频图层。

去掉 ICC 那一行后,单靠曲线会把最深的暗部提得太亮(28 那一条是 18.7,而 QuickTime 是 11.0),因为这时 mpv 是为纯 2.2 的显示器编码,而 Mac 的显示器曲线在接近黑色处有一段直线。最终匹配上的是第四项设置,它让 mpv 使用那条真实的曲线:

target-trc=srgb
treat-srgb-as-power22=no

配合格式滤镜和 gamma 因子,这样从 32 那一条往上与 QuickTime 相差不到半级,每种颜色相差都在两个单位以内。

Frame Player 如何处理

Frame Player 默认保留 mpv 的曲线,并把 QuickTime 的曲线作为一个选项:设置 › 视频 › SDR 视频色彩 › 与 macOS 一致。

  • 它就是上面测量的那组组合,不含 ICC,所以色彩完全保持原样,只改变色调曲线。
  • 它会立即改变画面,即使在暂停的帧上也一样,来回切换就能看出你更喜欢哪一个。
  • 它只影响 SDR 视频。HDR 文件保留自己的色调映射,图片不受影响。HDR 文件紧接在 SDR 文件之后播放时,相关设置会在它的第一帧绘制之前恢复。
  • 你自己的 mpv.conf 优先。如果你在那里自己设置了 gamma-factor 或 target-trc,这个开关不会动那一行。
  • 截图遵循这项选择,所以你导出的帧和播放器显示的样子一致。

这个开关只在 macOS 上提供:它回答的问题是“mpv 还是 Apple”,而 Windows 上没有可以对照的 Apple 一方。

常见问题

mpv 显示的视频是错的吗?

不是。在同一块显示器上与 QuickTime 对比实测,mpv 在中间调偏暗的部分最多暗 12 级(满分 255),色彩完全相同。这是一条不同的色调曲线,而不是错误,而且它更接近广播标准,该标准假定的是昏暗的房间。QuickTime 是有意把同一个视频画得更亮。

是因为文件没有色彩信息吗?

在 QuickTime 和 Frame Player 中都不是:同一个文件标记为 BT.709 的副本,在两者中测得的结果与未标记的完全相同。IINA 每次打开时会在两种效果之间变化,我们无法把这归因于标记。

哪一个是对的?

按标准,较暗的那个更接近。按 Mac 用户平常对照的东西,则是较亮的那个:QuickTime 的曲线就是系统自带播放器显示的效果,在 Mac 上剪辑和检查的视频,往往就是按这种样子审定的。用哪一个,取决于你期待的是哪一种。

某个彩条测试说 mpv 是最准确的播放器,是这样吗?

取决于参照值。以文件中的原始数值(180 和 16)为参照,它奖励的是跳过有限范围到完整范围扩展的播放器。以正确扩展后的数值(191 和 0)为参照,它的设计本身就偏向 mpv 的惯例:mpv 的偏差约为 0.3 级,QuickTime 约为 3.3 级。无论哪种,它告诉你的都是播放器遵循哪种惯例,而且彩条几乎不涉及中间调,而 mpv 和 QuickTime 恰恰在中间调差别最大。

这会影响 HDR 视频吗?

不会。HDR 视频使用不同的传递函数,并经过色调映射;这里描述的差异只涉及 SDR。

Windows 上也会这样吗?

在那里这个问题基本不会出现。差异存在于 mpv 和 Apple 自己的视频框架之间,而 Windows 没有一个让人们拿来对照曲线的系统播放器。

随便打开点什么。下次从你停下的地方接着看。

$ brew install --cask risenxxx/tap/frame-player

版本 1.38.1macOS 版已通过公证Windows 版未签名,SmartScreen 会拦截一次