搜索 社区服务 统计排行 帮助
  • 4353阅读
  • 1回复

谁说说yuy2和yv12的区别?

楼层直达
级别: 工作组
注册时间:
2002-10-17
在线时间:
0小时
发帖:
900
感谢
xxp
级别: 工作组
注册时间:
2002-05-08
在线时间:
0小时
发帖:
6398
只看该作者 1楼 发表于: 2003-01-04
Silky


普通会员

注册日期: Sep 2002
来自:
发帖数量: 17
96 12-28-2002 12:01:26

--------------------------------------------------------------------------------

MPEG 储存的 YU(Cb)V(Cr) 格式是遵循 CCIR601,也就是 ITU-R BT.601 的规范,Y 亮度的范围是 16~235,UV(CbCr) 色度是以无色 =128 为中心,范围是 16~240。
一般民生消费产品使用的 MPEG 压缩,大都采用 YUV 4:2:0 的格式,也就是如果分办率是 720x576,则每个 Frame,Y 有 720x576 个点,U 只有 360x288 个点,V 也只有 360x288 个点。色度的信息只有亮度的 1/4。那么为什么不写 YUV 4:1:1(UV 和 Y 的比例是 1:4) 而要写 YUV 4:2:0?这是因为要区分取样的方式不同。YUV 4:1:1 是指水平 Y 取样四个点,UV 各只取样一个点,水平的 Y 和 UV 的取样比例是 4:1,也就是
Y Y Y Y 一个 U 一个 V ....

YUV 4:2:0 是指水平和垂直 Y 各取样两个点,UV 各只取样一个点,水平的取样比例是 2:1,重直的取样比例 2:1,也就是
Y Y
Y Y 一个 U 一个 V ....

和 YUV 4:1:1 一样,色度和亮度差 1/2 * 1/2 = 1/4,只是取样的方式不同。

而 MPEG 最常采用的 YUV 4:2:0 格式,其 UV 的取样位置,MPEG-1 和 MPEG-2 又不同(MPEG-4 是用和 MPEG-2 一样的取样位置)
MPEG-1
Y Y
_x
Y Y

x 是 UV 的取样位置

MPEG-2
Y Y
x
Y Y

x 是 UV 的取样位置


了解了 YUV 4:2:0 以后,我们来看什么是 YV12,什么是 YUY2。
在个人计算机上,这些 YUV 读出来以后会以一些格式包装起来,送给软件或硬件处理。包装的方式分成两种,一种是 packed format,把 Y 和相对应的 UV 包在一起。另一种是 planar format,把 Y 和 U 和 V 三种分别包装,拆成三个 plane(平面)。
其中 YV12 和 YUY2 都是一种 YUV 的包装格式,而且两种都是 packed format。
YV12 和 YUY2 的不同,在于 YV12 是 YUV 4:2:0 格式,也就是 DVD/VCD 上原本储存的格式。YUY2 则是 YUV 4:2:2 格式,也就是

Y Y 一个 UV Y Y 一个 UV ....

水平取样比例是 1/2
重直取样比例是 1/1,也就是垂直 UV 和 Y 的个数一样多
以分辨率来讲,就是 Y 720x576 U 360x576 V 360x576。

至于详细的包装格式,这里就不画图了,请参考
http://www.fourcc.org/fccyuv.htm
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/YUVFormats.asp


以 DVD/VCD 的播放来说,读出来的 YUV 4:2:0 包成 YV12 的格式,如果显示卡有支持 YV12 的 FourCC Codec,播放时就会直接走 DirectDraw YV12 Overlay,直接丢 YV12 的数据给显示卡处理,由显示卡去做 YUV 4:2:0 展开(内插补点)-> YUV 4:2:2 -> YUV 4:4:4 -> RGB32,也就是色彩空间转换的的工作。如果你的屏幕分辨率大于影片原始分办率,显示卡还要做 scaling,也就是放大画面的动作,将影片的分办率放大到和你的屏幕的分办率相同,例如 640x480 -> 1024x768。(内插补点,补出不足的点)
所以显示卡的 YUV 4:2:0 -> 4:4:4 内插补点的好坏第一个就影响 MPEG 的播放品质,如果显示卡的 interpolating filter 不好,色彩补得不够平滑,红色的部分(人眼对红色较敏感,特别容易看出)就会出现一格一格的锯齿状。
再来就是显示卡的 scaling filter,放大补点的好坏,放大补点不好,画面就容易出现锯齿或是变得模糊不够清晰。

YV12 是最多显示卡支持的格式,传输的资料只有 YUV 4:2:0,比 RGB32 少很多,速度最快,所以大部分的软件都用这种格式传送数据。然而这种格式在遇到 interlaced 场线交错的画面的时候,会发生色度译码错误的问题。这个问题说起来很复杂,再讲个这篇文章又会太长,有兴趣的人可以参考 DVD2AVI 作者的网页,他有详细的说明,这个译码错误的问题也是他撰写 DVD2AVI 这个软件的原因:
The decoding problem with interlaced frame of most software MPEG-2 decoders
http://arbor.ee.ntu.edu.tw/~jackei/dvd2avi/interlace/

另一种错误,发生在 progressive frame 上
http://www.hometheaterhifi.com/volume_8_2/dvd-benchmark-special-report-chroma-bug-4-2001.html

这个说起来太长,有机会我再解释。

另一种常见的格式,就是 YUY2,也有许多显示卡支持,PowerDVD 为了解决上述的交错线彩色信息译码错误的问题便是使用这种格式。YUY2 也就是 YUV 4:2:2 的一种包装形式,播放时软件会先自己做 YUV 4:2:0 -> YUV 4:2:2 的内插补点(upsampling),做好以后再将 YUV 4:2:2 包成 YUY2,走 DirectDraw YUY2 Overlay,直接丢资料给显示卡,由显示卡去做后续的 YUV 4:2:2 -> 4:4:4 -> RGB32 的工作。

我们再来看显示卡的 DirectDraw Overlay 什么时候会启动,这个很重要,因为由以上可知,如果不使用 DirectDraw Overlay,而走传统的 GDI(Graphic Display Interface)图形显示接口,显示速度会很慢
1. 无法使用 DirectDraw 硬件加速,无法使用硬件的内插补点和色彩空间转换,CPU 负担非常重
2. 直接传送 RGB32,数据量大。无法使用显示卡的 scaling/interpolating filter,放大到全屏幕,会锯齿方块一格一格的非常难看。

所以 DirectDraw Overlay 有没有启动非常重要,现在大部分的显示卡,即使在高分办率的时候,DirectDraw Overlay 还是会启动,尤其是 ATI 的显示卡,即使在超高分办率的时候还是可以启动。
但是大部分的显示卡都有一个限制,那就是影片的分办率,水平的点数必须能被 32 整除,这样才能使用 DirectDraw Overlay。所以 GKnot 的 resize 选项,水平部分会有一个 32 Mod(能被 32 整除)的限制,就是这个原因。由上述可知,720 的水平分办率不能被 32 整除,所以会有无法启动 DirectDraw Overlay 的危险,为了最大的兼容性,制作的影片水平分办率最好是能够被 32 整除。
附带一提,垂直高度最好是能够被 16 整除,因为 MPEG 压缩是以 16x16 的巨方块为单位压缩,不是 16 的倍数的高度会制造压缩困难,压缩后可能会出现压缩瑕疵。
最好是先做好 resize 再压缩,不要以原始的分办率 720x576 压缩,播放时才调整比例作实时 resize。
实时 resize 的效果无法和慢慢计算的高品质 resize 相比,画质会比较差,本来是想保留较多的原始讯息,结果播放时的 resize 不好,反而得不偿失。


提到 YV12,顺便聊一下最近引起热烈讨论的 Avisynth 2.5 alpha。
Avisynth 2.5 alpha 最大的特色,就是支持 YV12 直接处理。我们知道原始 MPEG 数据是 YUV 4:2:0,也就是 YV12 的格式,以前我们在做 DivX/XviD 压缩的时候,处理流程是:
DVD/VCD(YUV 4:2:0) -> DVD2AVI(YUV 4:2:0 -> YUV 4:2:2 -> YUV 4:4:4 -> RGB24) -> VFAPI(RGB24) -> TMPGEnc/AviUtl/VirtualDub(RGB24) -> DivX/XviD Codec(RGB24 -> YUV 4:2:0) -> MPEG-4(YUV 4:2:0)

ps. VFAPI 内部只能以 RGB24 传递数据,所以会转成 RGB24 输出

或是
DVD/VCD(YUV 4:2:0) -> MPG2DEC.DLL(YUV 4:2:0 -> YUV 4:2:2) -> Avisynth 2.0.x(只能用支援 YUV 4:2:2 的 filter,不能用 RGB24/32 的 filter) -> VirtualDub(YUV 4:2:2,不能使用 VD 的 filter,因为 VD 的 filetr 都是在 RGB32 上处理,压缩时要选 Fast recompress,才会直接原封不动的送 YUV 4:2:2,也就是 YUY2 的数据给 Codec 压缩) -> DivX/XviD Codec(YUV 4:2:2 -> YUV 4:2:0) -> MPEG-4(YUV 4:2:0)

所以以前的处理流程中间要经过好几次 YUV <-> RGB 的转换。这个转换是有损的,做得越多次,原始的色彩信息就损失的越严重。而且这个转换的计算又耗时。那么有人(Marc FD)就想到,反正最后转成 MPEG 都要存成 YUV 4:2:0 的格式,那么为什么不干脆一路到底,全程都以 YV12 处理,也就是所有的 filter 都改写成 YV12 的版本,直接在 YV12 上做调整色彩、滤噪讯、IVTC 等工作,这样
1. 处理的数据量少。(YV12 的资料,UV 比 YUY2 少一半,比 RGB 24/32 少更多)
2. 不用转换计算

所以速度快。再加上又可以避免 YUV <-> RGB 转换的损失,岂不是一举两得?
所以支持 YV12 的 Avisynth 2.5 就诞生了
但是目前 VirtualDub 还是不支持 YV12,即使选 Fast recompress,VD 还是会将 YV12 的输入转为 YUY2,所以要得到全程 YV12 处理的好处,必须使用 VirtualDubMod 这个软件才行,这个改版才有支持 YV12(一样要选 Fast recompress)。

不过因为我要用 TMPGEnc(只接受 RGB24/32),所以我还是没使用全程 YV12 的方法


因为前面提到了 YUV 的数值范围(Y: 16~235, UV: 16~240),之前 Doom9 上也有一篇 Lumi masking 的帖子在讨论这个,不过.....,所以我顺便转贴以前写的一篇文章给大家参考:



DVD/VCD/DV 等使用的 MPEG/MJPEG 压缩,记录的 YCbCr 格式,是遵循 ITU-R BT.601 的
规范,其数据范围(动态范围)为 Y(亮度)16~235,C(色度)以 128 为中心代表无色
,范围 16~240。
做处理和显示的时候,YCbCr 要转为 RGB,其范围为 16~235。
但是计算机屏幕上,纯白的点,其 RGB 值为 (255,255,255),纯黑的点,
其 RGB 为 (0,0,0)。所以 MPEG/MJPEG 所记录的纯白 (235,235,235) 在计算机屏幕上看起
来就不是纯白,纯黑 (16,16,16) 在计算机屏幕上看起来也不会是纯黑。
因此 DV 录下来的东西,拿到计算机上看,会觉得颜色变淡,好像照上了一层白纱。
同时因为数据范围(动态范围)缩小为 16~235,而不是全范围(Full Scale)0~255,
所以会觉得对比不足(最亮和最暗的差距缩小),不如在电视上看漂亮。
所以在计算机上看、编辑 DV AVI,必需要先做 Y/C 伸张,也就是将 Y/C 的动态由原来的
16~235 扩展到 0~255,然后转为 RGB 0~255,这样在计算机屏幕上看到的颜色才会是正确的
。以此为基准作颜色校正、各种滤镜处理,出来的结果才会是正确的。
经过 Y/C 伸张以后,然后才作各种的编辑。
最后要压成 DVD/VCD/DV 的时候,因为仍然是存成 MPEG/MJPEG 格式,
数据范围还是 16~235,所以已经做过 Y/C 伸张的影像在压缩之前,必须先做 Y/C 压缩,
把目前 RGB 0~255 的数据压缩为 16~235,然后转为 YCbCr 16~235,这样才会正确。
不然超过的数据在转为 YCbCr 16~235 的时候会被削掉(clipping),
对比、颜色会完全错误。

如果没有编辑、修改画面的必要,只是要将 DV AVI 直接做成 DVD/VCD,
则可以不必做 Y/C 伸张,直接压缩为 DVD/VCD。
此时数据没有做过 Y/C 伸张,所以压缩的时候,不可以再做一次 Y/C 压缩然后压 MPEG,
否则做好的 DVD/VCD 即使在电视上播放,对比、颜色也会是错的。

总结:
原始数据以 MPEG/MJPEG 储存,为 Y/C 压缩过的数据,
修改编辑时需先做 Y/C 伸张之后再修改。
若做过 Y/C 伸张,压缩时需做 Y/C 压缩,出来的画面才是正确的。
若没做过 Y/C 伸张,压缩时不可以做 Y/C 压缩,出来的画面才是正确的。

以 TMPGEnc 这个压缩软件为例,压缩时预设是接收 0~255 的 RGB 数据,
先做 Y/C 压缩,然后才压 MPEG。
所以如果是 YCbCr 16~235 的数据要对画面做修改,必须使用 Descale CCIR601 这个滤镜
(CCIR601 就是 ITU-R BT.601,CCIR 是 ITU 以前的名字),把 Luminous, Chroma 两个
选项都推到 255(也就是做 Y/C 伸张),然后才做其它的编辑动作。
Descale CCIR601 的顺位要排第一位。
然后压缩时直接压缩便可以得到正确的结果。
如果没有要对画面做修改,则不必做 Y/C 伸张,但是压缩的时候必需要勾选
进阶设定--> 量子化行列(Quantize matrix)底下的 "Basic YCbCr ?出力"
(Out YUV data as Basic YCbCr not CCIR601),这样 TMPGEnc 压缩时便不会
做 Y/C 压缩,压出来的颜色、对比才会正确。

总结:
如果原始数据是 YCbCr 16~235
有做 Y/C 伸张的话,压缩时直接压缩就好,不能勾选 "Basic YCbCr ?出力"。
没有做 Y/C 伸张的话,压缩时必须勾选 "Basic YCbCr ?出力"。

再以 Cinema Craft Encoder SP 这个压缩软件为例,设定选项的
"16 ??235" = TMPGEnc 不勾选 "Basic YCbCr ?出力" = 压缩时先做 Y/C 压缩
"0 ??255" = TMPGEnc 勾选 "Basic YCbCr ?出力" = 压缩时不做 Y/C 压缩

实际上 CCE SP 是用两个不同的 YUV <--> RGB 转换式,列在下面给有兴趣的人参考:
"16 ??235"
Rd = 219*R + 16*256
Gd = 219*G + 16*256
Bd = 219*B + 16*256
Y = 77*Rd + 150*Gd + 29*Bd / 2^16
CR = (( 131*Rd - 110*Gd - 21*Bd ) / 2^16 ) +128
CB = (( -44*Rd - 87*Gd + 131*Bd ) / 2^16 ) +128

"0 ??255"
Y = 77*Rd + 150*Gd + 29*Bd / 2^8
CR = (( 131*Rd - 110*Gd - 21*Bd ) / 2^8 ) +128
CB = (( -44*Rd - 87*Gd + 131*Bd ) / 2^8 ) +128

而 YC 伸张的计算式是(简略)
Y' = (Y - 16) * 255 / (235 - 16)
C' = C * 255 / (255 - (240-16))

再来探讨两个问题,第一个是 DV Codec 在输出数据给压缩软件时,可能会输出两种格式
,第一种是直接输出 YUV 4:1:1,由压缩软件自己去做 YUV --> RGB 的转换。
第二种是由 Codec 内部先做 YUV --> RGB 转换,再输出 RGB 给压缩软件。
如果 Codec 是输出 YUV 4:1:1,则转换后的 RGB 范围是 0~255(有做 Y/C 伸张)
还是 16~235(没做 Y/C 伸张),由执行转换的压缩软件决定。
如 TMPGEnc 的环境设定的选项中,有针对 Canopus DV Codec 做设定,提供你选择,
YUV --> RGB 转换时,要用哪一种转换式。有三种,Basic YCbCr,CCIR601,YUV。

如果是由 Codec 做转换,输出 RGB,则是否做伸张由 Codec 决定。
不同 Codec 有不同作法,是否有做伸张必须要做实验才能确定。

如果 YUV --> RGB 时已经做过伸张,则 RGB 数据已经是 0~255 的范围,
就不可以再用 Descale CCIR601 滤镜,否则会有许多资料破表被削掉,切记。

第二个问题,压缩软件压缩时,是否会先做 Y/C 压缩?
如 MS MPEG-4 Codec,DivX Codec,XviD Codec 这几个 Codec 都是假设收到的数据是
0~255,会先做 Y/C 压缩的动作。那么其它 Codec 和压缩软件呢?
这个也必须要做实验确认才能确定。

唯有解压缩和压缩的转换式能正确搭配(做过 Y/C 伸张压缩时就必须做 Y/C 压缩,
没做 Y/C 伸张压缩时就不可以做 Y/C 压缩)最后压出来的成品才会是正确的。


补充一
DVD2AVI 的 Color Space 选 RGB/YUV 和 PC Scale/TV Scale 的差异

RGB 模式是输出 RGB24,YV12 (YUV 4:2:0) --> YUY2 (YUV 4:2:2) --> RGB24,
由 dvd2avi 做内插展开(4:2:0 -> 4:2:2)和转换的工作(YUV -> RGB)。
内插展开的算式作者的网站有写,相当于 6-tap 的 FIR Filter。

YUV 模式是输出 YUV 4:2:2(YUY2)。

输出 RGB 时,preview 显示会走传统的 GDI 图形显示接口,送 RGB24 的资料给显示卡,
此时计算机屏幕上看到的颜色正不正确,由 YUV -> RGB 这个选项决定。
(要选 PC Scale 看到的颜色才会正确)

输出 YUV 时,preview 显示会走 DirectDraw YUY2 Overlay,直接送 YUY2 的数据
给显示卡,由显示卡去做展开和色空间转换。显示卡用的都是 PC Scale
(会做 Y/C 伸张,扩展原来的 16~235 的数据为 0~255),所以您可以在屏幕上
看到正确的颜色。

(同理,DVD/VCD 播放时,播放软件会走 DirectDraw Overlay 丢 YUY2 或 YV12
的资料给显示卡,由显示卡来做展开、色空间转换、和放大(scaling filter)的工作。
由于显示卡用的是 PC Scale,会做 Y/C 伸张,所以您才可以在计算机屏幕上看到正确的
DVD/VCD 的颜色)

(前提是,做好的 DVD/VCD,其 YUV 4:2:0 的数据范围必须是 16~235,
经过显示卡 PC Scale 16~235 -> 0~255 才会正确。
如果 DVD/VCD 做错,压缩前没有先做 Y/C 压缩,储存的是 0~255 的 YUV 数据,
则显示时再经过显示卡的 Y/C 伸张,会发生 clipping(资料超过范围被削掉))

(而 16~235 的数据拿到电视上放,电视本来就吃 16~235 的资料,
所以显示也是正常的)
(所以结论,DVD/VCD 上的数据,必须遵照 CCIR601 的规范,维持 16~235 的范围)

至于输出,也是按照 YUV/RGB 的设定,分别输出 YUY2 和 RGB24。

但是如果您有用 vfapi,因为 vfapi 内部完全以 RGB24 传送数据,
所以如果你把 .d2v 转成 vfapi-ref-avi,即使 color space 选 YUV,
dvd2avi 也会做展开转换成 RGB24 输出。如果要用 dvd2avi 直接做 Y/C 伸张,
dvd2avi 的 YUV -> RGB 选项勾选 PC Scale 即可。

另外,如果用 TMPGEnc/AviUtl 直接开启 .d2v,因为这些软件还是以 RGB24
读取,所以 dvd2avi 也还是以 RGB24 输出。

那.... 倒底什么时候会用 YUY2 输出?
直接存 AVI 的时候... ^^;

所以如果您是用 vfapi 或用 TMPGEnc/AviUtl 读取,选 YUV 或 RGB 都没有差异。

附带一提 ^^; 如果 dvd2avi 输出时已经选了 PC Scale(有做 Y/C 伸张),
就不可以再用 TMPGEnc 的 Descale CCIR601 这个滤镜,也不可以用
AviUtl 的 "ITU-R BT.601 补正",这两个作的事情是一样的,都是做 Y/C 伸张。
已经伸张过再做伸张,会有许多资料 clipping。

补充二
XviD 使用的 RGB -> YUV 算式

由 source code 可以得知,XviD 和大部分的软件一样是遵照这本书的标准转换式作的
http://www.video-demystified.com/book1/index.htm
算式为

Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16

Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128

Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128

此算式等于上述 CCE SP 的第一个算式,也就是假设收到的是 0~255 的 RGB 数据,会先做 Y/C 压缩,然后才压 MPEG。

可以多点去“精品论坛”的视频技术区看看...xxp留
http://bbs.et8.net/bbs/forumdisplay.php?s=&forumid=51

你不能决定生命的长度,但你可以控制它的宽度。
你不能左右天气,但你可以改变心情。
你不能改变容貌,但你可以展现笑容。
你不能控制他人,但你可以掌握自己。
你不能预知明天,但你可以利用今天。
你不能样样胜利,但你可以事事尽力。
快速回复

限150 字节
上一个 下一个