奇数分辨率的导出报错
前记:有群u说了个冷知识,说ae里面mp4导出奇数分辨率会报错,我当时就当作个知识点来看待了。最近想起来这件事,就去了解查询了一下,发现是yuv编码还有输出本身的问题。我也只是浅入浅出,内容写的可能有点乱,见谅
尝试验证阶段
AE内置
我用的是23sp版本,记得好像是23版本以上就开始支持不用AME也能导h264了。所以我直接用原生的来试试。合成调成奇数分辨率后,发现左下角已经是上警告了,确实是不给导。如果你强行导的话,奇数会自动减一。
AfterCode
用aftercode来导h264的奇数分辨率视频,他就没惯着你帮你修改了,直接给你报错(aftercode默认是yuv422)
但是,如果你修改这个YUV变成444后,它是可以导出的
而且他不是偷偷摸摸帮你修改分辨率,而是真的是奇数分辨率的视频
YUV编码
前面的情景讲了这么多,ae能成功导出奇数分辨率的mp4格式视频就是靠YUV444来的。那么YUV是什么?
什么是YUV
YUV编码格式是一种将彩色图像表示为亮度(Y)和色度(U、V)分量的颜色空间编码方法。它是一种广泛用于视频压缩和传输的格式。其中的Y(Luma)表示图像的明亮度或灰度信息,它决定了图像的亮暗程度。U和V(Chroma)表示图像的颜色信息,它们决定了图像的色调和饱和度。
YUV数值/色彩转换
YUV中的数值,使用的是图像中的RGB来做转换而来的,转换公式有挺多种,这里列出一个
例如:将 RGB888 转换为 YUV 4:4:4
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16
U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128
V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128
- R、G、B中相乘的数值是一系列权重而来的常数
>>
为右移8位- 后面相加的数值也是各种权重而来的值
例子来自于链接内,想了解的更深可以看看这里使用 8 位 YUV 格式进行视频渲染 |Microsoft 学习
那么到这里,就差不多可以理解YUV是对像素点做了亮度和色彩信息上的收集
YUV优势
- 节省存储空间:相对于RGB格式,YUV格式可以更有效地压缩视频数据。因为对于RGB来说需要同时存储R、G、B三种信息,而YUV只要存储Y和UV即可
- 视频编码效率高:由于人眼对亮度的敏感性更高,视频编码器可以更多地分配比特率给亮度分量,从而保留更多的细节和质量。这种分配比特率的方式与人眼感知的特性相匹配,可以在保持良好视觉质量的同时减少数据量。
- 跨平台兼容性:YUV格式是广泛支持的视频格式之一,几乎所有的视频编码器和解码器都支持YUV格式。
常见YUV格式
常见的YUV格式有YUV 444、YUV 422和YUV 420,它们之间的区别在于色度(U和V)的取样方式和存储方式。
-
YUV 444:
-
YUV 444是一种无损的取样格式,它在每个像素中都包含完整的亮度(Y)和色度(U和V)信息。
-
对于每个像素,都有一个对应的Y、U和V值,因此色度的取样率与亮度相同。
-
这种格式产生的图像质量最高,但需要更多的存储空间。
YUV 444采样格式图--X代表亮度样本、⚪代表色度样本
-
-
YUV 422:
-
YUV 422是一种有损的取样格式,它在每两个水平像素中共享一个色度(U和V)样本。
-
对于每两个相邻的像素,都有一个对应的Y值,但只有一个U和一个V值。
-
这种格式在色度分辨率上进行了折衷,相对于YUV 444,它减少了一半的色度样本,从而减少了存储空间。
YUV 422采样格式图--X代表亮度样本、⚪代表色度样本
-
-
YUV 420:
-
YUV 420是一种更高度压缩的取样格式,它在每四个像素中共享一个色度(U和V)样本(2×2)。
-
对于每四个相邻的像素,都有一个对应的Y值,但只有一个U和一个V值。
-
这种格式在色度分辨率上进一步减少,相对于YUV 422,它减少了一半的色度样本,从而进一步减少了存储空间。
YUV 420采样格式图--X代表亮度样本、⚪代表色度样本
对UV采样方式的了解可以看看这个文章一文读懂 YUV 的采样与格式 - 知乎 (zhihu.com)
-
导出失败原因分析
当我了解到YUV的三种采样格式后,我第一感觉就是:“哦!是奇数分辨率导致UV取样时候不能平均分配”。但是又仔细想了想,不对啊!1921*1080不都是能被2(YUV422)和4(YUV420)整除吗?怎么会报错呢?
我拿了个24*19
分辨率的视频导出,AE自己的h264报错(情理之中),然后用aftercode里面的yuv422和yuv420来导h264,都失败了。24是2也是4的倍数,按道理UV采样不是能整数分配吗?网上查询一番,突然看到有人贴了个315*81
的格式工厂导出来的视频,YUV居然是420.我开始感觉到不理解了这怎么做到的(找不到原因,有知道的佬说说)。
格式工厂
我直接去格式工厂试了试,发现会导出错误,然后捣鼓了一番,没有找到可以改YUV的地方
但是发现编码格式改为DivX后可以导24*19
的视频,YUV为420。我当时感觉挺合理的,因为24是4的倍数,能均分UV。但是当我极端一点,用17*15
来尝试,用格式工厂来导,发现也可以。
这个时候我感觉的是自己在YUV420的知识点可能是接触的不够深了。
FFMPEG
后面我转希望在ffmpeg,为了能展示到YUV422与420的区别性,我拿18*19
这个富有代表性的分辨率来尝试
- YUV422是成功的
ffmpeg -i 2419-444.mp4 -s 18*19 -pix_fmt yuv422p 1819-422.mp4
-i指定选择的视频
-s指定输出大小
- YUV420会报错
ffmpeg -i 2419-444.mp4 -s 18*19 -pix_fmt yuv420p 1819-420.mp4
报错如下:
[libx264 @ 00000242bd1ba3c0] height not divisible by 2 (18x19)
[vost#0:0/libx264 @ 00000242bd1ba100] Error while opening encoder - maybe incorrect parameters such as bit_rate, rate, width or height.
Error while filtering: Generic error in an external library
[out#0/mp4 @ 00000242bd1b1d40] Nothing was written into output file, because at least one of its streams received no packets.
符合我的想法预期
总结
对于用YUV编码格式导出奇数分辨率这个问题,除了编码原因本身,渲染导出工具的逻辑也是一个问题。像AE就写死不给你导出奇数分辨率,不管他默认的YUV是多少,Aftercode也是一样。而对于格式工厂的奇怪问题,有佬明白的话可以说说。内置的QuickTime倒是能随便导各种分辨率,因为他的色彩空间是RGB类型的,不受像素点数量而影响。
标签:视频,奇数,分辨率,YUV,色度,报错,格式 From: https://www.cnblogs.com/ethereal258/p/17810556.html