DirectShow中常见的RGB.docx
《DirectShow中常见的RGB.docx》由会员分享,可在线阅读,更多相关《DirectShow中常见的RGB.docx(21页珍藏版)》请在冰点文库上搜索。
DirectShow中常见的RGB
DirectShow中常见的RGB/YUV格式
sclarkca发表于2006-6-2610:
28:
00
窗体底端
计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red)、G(Green)、B(Blue)相加混色的原理:
通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红、绿、蓝磷光材料发光而产生色彩。
这种色彩的表示方法称为RGB色彩空间表示(它也是多媒体计算机技术中用得最多的一种色彩空间表示方法)。
根据三基色原理,任意一种色光F都可以用不同分量的R、G、B三色相加混合而成。
F=r[R]+g[G]+b[B]
其中,r、g、b分别为三基色参与混合的系数。
当三基色分量都为0(最弱)时混合为黑色光;而当三基色分量都为k(最强)时混合为白色光。
调整r、g、b三个系数的值,可以混合出介于黑色光和白色光之间的各种各样的色光。
那么YUV又从何而来呢?
在现代彩色电视系统中,通常采用三管彩色摄像机或彩色CCD摄像机进行摄像,然后把摄得的彩色图像信号经分色、分别放大校正后得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y(即U)、B-Y(即V),最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。
这种色彩的表示方法就是所谓的YUV色彩空间表示。
采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。
如果只有Y信号分量而没有U、V分量,那么这样表示的图像就是黑白灰度图像。
彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。
YUV与RGB相互转换的公式如下(RGB取值范围均为0-255):
Y=0.299R+0.587G+0.114B
U=-0.147R-0.289G+0.436B
V=0.615R-0.515G-0.100B
R=Y+1.14V
G=Y-0.39U-0.58V
B=Y+2.03U
在DirectShow中,常见的RGB格式有RGB1、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。
作为视频媒体类型的辅助说明类型(Subtype),它们对应的GUID见表2.3。
表2.3常见的RGB和YUV格式
GUID 格式描述
MEDIASUBTYPE_RGB1 2色,每个像素用1位表示,需要调色板
MEDIASUBTYPE_RGB4 16色,每个像素用4位表示,需要调色板
MEDIASUBTYPE_RGB8 256色,每个像素用8位表示,需要调色板
MEDIASUBTYPE_RGB565 每个像素用16位表示,RGB分量分别使用5位、6位、5位
MEDIASUBTYPE_RGB555 每个像素用16位表示,RGB分量都使用5位(剩下的1位不用)
MEDIASUBTYPE_RGB24 每个像素用24位表示,RGB分量各使用8位
MEDIASUBTYPE_RGB32 每个像素用32位表示,RGB分量各使用8位(剩下的8位不用)
MEDIASUBTYPE_ARGB32 每个像素用32位表示,RGB分量各使用8位(剩下的8位用于表示Alpha通道值)
MEDIASUBTYPE_YUY2 YUY2格式,以4:
2:
2方式打包
MEDIASUBTYPE_YUYV YUYV格式(实际格式与YUY2相同)
MEDIASUBTYPE_YVYU YVYU格式,以4:
2:
2方式打包
MEDIASUBTYPE_UYVY UYVY格式,以4:
2:
2方式打包
MEDIASUBTYPE_AYUV 带Alpha通道的4:
4:
4YUV格式
MEDIASUBTYPE_Y41P Y41P格式,以4:
1:
1方式打包
MEDIASUBTYPE_Y411 Y411格式(实际格式与Y41P相同)
MEDIASUBTYPE_Y211 Y211格式
MEDIASUBTYPE_IF09 IF09格式
MEDIASUBTYPE_IYUV IYUV格式
MEDIASUBTYPE_YV12 YV12格式
MEDIASUBTYPE_YVU9 YVU9格式
下面分别介绍各种RGB格式。
¨RGB1、RGB4、RGB8都是调色板类型的RGB格式,在描述这些媒体类型的格式细节时,通常会在BITMAPINFOHEADER数据结构后面跟着一个调色板(定义一系列颜色)。
它们的图像数据并不是真正的颜色值,而是当前像素颜色值在调色板中的索引。
以RGB1(2色位图)为例,比如它的调色板中定义的两种颜色值依次为0x000000(黑色)和0xFFFFFF(白色),那么图像数据001101010111…(每个像素用1位表示)表示对应各像素的颜色为:
黑黑白白黑白黑白黑白白白…。
¨RGB565使用16位表示一个像素,这16位中的5位用于R,6位用于G,5位用于B。
程序中通常使用一个字(WORD,一个字等于两个字节)来操作一个像素。
当读出一个像素后,这个字的各个位意义如下:
高字节 低字节
RRRRRGGG GGGBBBBB
可以组合使用屏蔽字和移位操作来得到RGB各分量的值:
#defineRGB565_MASK_RED 0xF800
#defineRGB565_MASK_GREEN 0x07E0
#defineRGB565_MASK_BLUE 0x001F
R=(wPixel&RGB565_MASK_RED)>>11; //取值范围0-31
G=(wPixel&RGB565_MASK_GREEN)>>5; //取值范围0-63
B= wPixel&RGB565_MASK_BLUE; //取值范围0-31
¨RGB555是另一种16位的RGB格式,RGB分量都用5位表示(剩下的1位不用)。
使用一个字读出一个像素后,这个字的各个位意义如下:
高字节 低字节
XRRRRGG GGGBBBBB (X表示不用,可以忽略)
可以组合使用屏蔽字和移位操作来得到RGB各分量的值:
#defineRGB555_MASK_RED 0x7C00
#defineRGB555_MASK_GREEN 0x03E0
#defineRGB555_MASK_BLUE 0x001F
R=(wPixel&RGB555_MASK_RED)>>10; //取值范围0-31
G=(wPixel&RGB555_MASK_GREEN)>>5; //取值范围0-31
B= wPixel&RGB555_MASK_BLUE; //取值范围0-31
¨RGB24使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。
注意在内存中RGB各分量的排列顺序为:
BGRBGRBGR…。
通常可以使用RGBTRIPLE数据结构来操作一个像素,它的定义为:
typedefstructtagRGBTRIPLE{
BYTErgbtBlue; //蓝色分量
BYTErgbtGreen; //绿色分量
BYTErgbtRed; //红色分量
}RGBTRIPLE;
¨RGB32使用32位来表示一个像素,RGB分量各用去8位,剩下的8位用作Alpha通道或者不用。
(ARGB32就是带Alpha通道的RGB32。
)注意在内存中RGB各分量的排列顺序为:
BGRABGRABGRA…。
通常可以使用RGBQUAD数据结构来操作一个像素,它的定义为:
typedefstructtagRGBQUAD{
BYTE rgbBlue; //蓝色分量
BYTE rgbGreen; //绿色分量
BYTE rgbRed; //红色分量
BYTE rgbReserved; //保留字节(用作Alpha通道或忽略)
}RGBQUAD;
下面介绍各种YUV格式。
YUV格式通常有两大类:
打包(packed)格式和平面(planar)格式。
前者将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三个数组分开存放YUV三个分量,就像是一个三维平面一样。
表2.3中的YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。
(注意:
在介绍各种具体格式时,YUV各分量都会带有下标,如Y0、U0、V0表示第一个像素的YUV分量,Y1、U1、V1表示第二个像素的YUV分量,以此类推。
)
¨YUY2(和YUYV)格式为每个像素保留Y分量,而UV分量在水平方向上每两个像素采样一次。
一个宏像素为4个字节,实际表示2个像素。
(4:
2:
2的意思为一个宏像素中有4个Y分量、2个U分量和2个V分量。
)图像数据中YUV分量排列顺序如下:
Y0U0Y1V0 Y2U2Y3V2…
¨YVYU格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
Y0V0Y1U0 Y2V2Y3U2…
¨UYVY格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
U0Y0V0Y1 U2Y2V2Y3…
¨AYUV格式带有一个Alpha通道,并且为每个像素都提取YUV分量,图像数据格式如下:
A0Y0U0V0 A1Y1U1V1…
¨Y41P(和Y411)格式为每个像素保留Y分量,而UV分量在水平方向上每4个像素采样一次。
一个宏像素为12个字节,实际表示8个像素。
图像数据中YUV分量排列顺序如下:
U0Y0V0Y1 U4Y2V4Y3 Y4Y5Y6Y8…
¨Y211格式在水平方向上Y分量每2个像素采样一次,而UV分量每4个像素采样一次。
一个宏像素为4个字节,实际表示4个像素。
图像数据中YUV分量排列顺序如下:
Y0U0Y2V0 Y4U4Y6V4…
¨YVU9格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个4x4的宏块,然后每个宏块提取一个U分量和一个V分量。
图像数据存储时,首先是整幅图像的Y分量数组,然后就跟着U分量数组,以及V分量数组。
IF09格式与YVU9类似。
¨IYUV格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个2x2的宏块,然后每个宏块提取一个U分量和一个V分量。
YV12格式与IYUV类似。
¨YUV411、YUV420格式多见于DV数据中,前者用于NTSC制,后者用于PAL制。
YUV411为每个像素都提取Y分量,而UV分量在水平方向上每4个像素采样一次。
YUV420并非V分量采样为0,而是跟YUV411相比,在水平方向上提高一倍色差采样频率,在垂直方向上以U/V间隔的方式减小一半色差采样,如图2.12所示。
使用8位YUV格式的视频呈现
发布日期:
12/9/2004|更新日期:
12/9/2004
GarySullivan和StephenEstrop
MicrosoftDigitalMediaDivision
适用于:
Microsoft®Windows®,MicrosoftDirectShow®
摘要:
本文讲述了在MicrosoftWindows操作系统中呈现视频时推荐使用的8位YUV格式。
本文讲述了可用于在YUV格式和RGB格式之间进行转换的技术,还提供了用于对YUV格式进行上采样的技术。
本文适用于在Windows中使用YUV视频解码或呈现的所有人员。
简介
在DirectShow中标识YUV格式
YUV采样
表面定义
颜色空间和色度采样率转换
其他信息
简介
在整个视频行业中,定义了很多YUV格式。
本文讲述的是在Microsoft®Windows®操作系统中呈现视频时推荐使用的8位YUV格式。
鼓励解码器供应商和显示供应商支持本文所讲述的格式。
本文不对YUV颜色的其他用途(如静止摄影)进行描述。
本文讲述的格式全部使用每个像素位置8位的方式来编码Y频道(也称为灯光频道),并使用每样例8位的方式来编码每个U或V色度样例。
但是,大多数YUV格式平均使用的每像素位数都少于24位,这是因为它们包含的U和V样例比Y样例要少。
本文不讲述带有10位和12位Y频道的YUV格式。
注在本文中,U一词相当于Cb,V一词相当于Cr。
本文包括以下主题:
•
在DirectShow中标识YUV格式—讲述了如何描述MicrosoftDirectShow®YUV格式类型。
•
YUV采样—讲述了一些最常用的YUV采样技术。
•
表面定义—讲述了推荐的YUV格式。
•
颜色空间和色度采样率转换—提供了一些在YUV和RGB格式之间进行转换的指南,以及在不同YUV格式之间进行转换的指南。
•
其他信息提供了其他信息。
在DirectShow中标识YUV格式
本文讲述的每种YUV格式都指定了一个FOURCC码。
FOURCC码是一个32位、不带正负号的整数,它是通过串联四个ASCII字符创建而成的。
有很多C/C++宏可使得在源代码中声明FOURCC值变得更加简单。
例如,MAKEFOURCC宏是在Mmsystem.h中声明的,FCC宏则是在Aviriff.h中声明的。
请按照下列方式使用这些宏:
DWORDfccYUY2=MAKEFOURCC('Y','U','Y','2');
DWORDfccYUY2=FCC('YUY2');
只需通过调转字符的顺序,您还可以将FOURCC码直接声明为字符文本。
例如:
DWORDfccYUY2='2YUY';//DeclarestheFOURCC'YUY2'
因为Windows操作系统使用的是little-endian体系结构,所以调转顺序是必需的。
“Y”=0x59,“U”=0x55,“2”=0x32,所以“2YUY”为0x32595559。
在DirectShow中,格式是由一个主类型全局唯一标识符(GUID)和一个子类型GUID标识的。
计算机视频格式的主类型总是MEDIATYPE_Video。
子类型则可以通过将FOURCC码与GUID进行映射的方式来构造,如下所示:
XXXXXXXX-0000-0010-8000-00AA00389B71
其中XXXXXXXX为FOURCC码。
因此,YUY2的子类型GUID为:
32595559-0000-0010-8000-00AA00389B71
很多这样的GUID都已经在头文件Uuids.h中进行了定义。
例如,YUY2子类型被定义为MEDIASUBTYPE_YUY2。
DirectShow基类库还提供了一个帮助器类FOURCCMap,该类可用于将FOURCC码转换为GUID值。
FOURCCMap构造函数采用FOURCC码作为输入参数。
然后,您可以将FOURCCMap对象强制转换为相应的GUID:
FOURCCMapfccMap(FCC('YUY2'));
GUIDg1=(GUID)fccMap;
//Equivalent:
GUIDg2=(GUID)FOURCCMap(FCC('YUY2'));
返回页首
YUV采样
YUV的优点之一是,色度频道的采样率可比Y频道低,同时不会明显降低视觉质量。
有一种表示法可用来描述U和V与Y的采样频率比例,这个表示法称为A:
B:
C表示法:
•
4:
4:
4表示色度频道没有下采样。
•
4:
2:
2表示2:
1的水平下采样,没有垂直下采样。
对于每两个U样例或V样例,每个扫描行都包含四个Y样例。
•
4:
2:
0表示2:
1的水平下采样,2:
1的垂直下采样。
•
4:
1:
1表示4:
1的水平下采样,没有垂直下采样。
对于每个U样例或V样例,每个扫描行都包含四个Y样例。
与其他格式相比,4:
1:
1采样不太常用,本文不对其进行详细讨论。
图1显示了4:
4:
4图片中使用的采样网格。
灯光样例用叉来表示,色度样例则用圈表示。
图1.YUV4:
4:
4样例位置
4:
2:
2采样的这种主要形式在ITU-RRecommendationBT.601中进行了定义。
图2显示了此标准定义的采样网格。
图2.YUV4:
2:
2样例位置
4:
2:
0采样有两种常见的变化形式。
其中一种形式用于MPEG-2视频,另一种形式用于MPEG-1以及ITU-TrecommendationsH.261和H.263。
图3显示了MPEG-1方案中使用的采样网格,图4显示了MPEG-2方案中使用的采样网格。
图3.YUV4:
2:
0样例位置(MPEG-1方案)
图4.YUV4:
2:
0样例位置(MPEG-2方案)
与MPEG-1方案相比,在MPEG-2方案与为4:
2:
2和4:
4:
4格式定义的采样网格之间进行转换更简单一些。
因此,在Windows中首选MPEG-2方案,应该考虑将其作为4:
2:
0格式的默认转换方案。
返回页首
表面定义
本节讲述推荐用于视频呈现的8位YUV格式。
这些格式可以分为几个类别:
•
4:
4:
4格式,每像素32位
•
4:
2:
2格式,每像素16位
•
4:
2:
0格式,每像素16位
•
4:
2:
0格式,每像素12位
首先,您应该理解下列概念,这样才能理解接下来的内容:
•
表面原点。
对于本文讲述的YUV格式,原点(0,0)总是位于表面的左上角。
•
跨距。
表面的跨距,有时也称为间距,指的是表面的宽度,以字节数表示。
对于一个表面原点位于左上角的表面来说,跨距总是正数。
•
对齐。
表面的对齐是根据图形显示驱动程序的不同而定的。
表面始终应该DWORD对齐,就是说,表面中的各个行肯定都是从32位(DWORD)边界开始的。
对齐可以大于32位,但具体取决于硬件的需求。
•
打包格式与平面格式。
YUV格式可以分为打包格式和平面格式。
在打包格式中,Y、U和V组件存储在一个数组中。
像素被组织到了一些巨像素组中,巨像素组的布局取决于格式。
在平面格式中,Y、U和V组件作为三个单独的平面进行存储。
4:
4:
4格式,每像素32位
推荐一个4:
4:
4格式,FOURCC码为AYUV。
这是一个打包格式,其中每个像素都被编码为四个连续字节,其组织顺序如下所示。
图5.AYUV内存布局
标记了A的字节包含alpha的值。
4:
2:
2格式,每像素16位
支持两个4:
2:
2格式,FOURCC码如下:
•
YUY2
•
UYVY
两个都是打包格式,其中每个巨像素都是编码为四个连续字节的两个像素。
这样会使得色度水平下采样乘以系数2。
YUY2
在YUY2格式中,数据可被视为一个不带正负号的char值组成的数组,其中第一个字节包含第一个Y样例,第二个字节包含第一个U(Cb)样例,第三个字节包含第二个Y样例,第四个字节包含第一个V(Cr)样例,如图6所示。
图6.YUY2内存布局
如果该图像被看作由两个little-endianWORD值组成的数组,则第一个WORD在最低有效位(LSB)中包含Y0,在最高有效位(MSB)中包含U。
第二个WORD在LSB中包含Y1,在MSB中包含V。
YUY2是用于MicrosoftDirectX®VideoAcceleration(DirectXVA)的首选4:
2:
2像素格式。
预期它会成为支持4:
2:
2视频的DirectXVA加速器的中期要求。
UYVY
此格式与YUY2相同,只是字节顺序是与之相反的—就是说,色度字节和灯光字节是翻转的(图7)。
如果该图像被看作由两个little-endianWORD值组成的数组,则第一个WORD在LSB中包含U,在MSB中包含Y0,第二个WORD在LSB中包含V,在MSB中包含Y1。
图7.UYVY内存布局
4:
2:
0格式,每像素16位
推荐两个4:
2:
0每像素16位格式,FOURCC码如下:
•
IMC1
•
IMC3
两个FOURCC码都是平面格式。
色度频道在水平方向和垂直方向上都要以系数2来进行再次采样。
IMC1
所有Y样例都会作为不带正负号的char值组成的数组首先显示在内存中。
后面跟着所有V(Cr)样例,然后是所有U(Cb)样例。
V和U平面与Y平面具有相同的跨距,从而生成如图8所示的内存的未使用区域。
图8.IMC1内存布局
IMC3
此格式与IMC1相同,只是U和V平面进行了交换:
图9.IMC3内存布局
4:
2:
0格式,每像素12位
推荐四个4:
2:
0每像素12位格式,FOURCC码如下:
•
IMC2
•
IMC4
•
YV12
•
NV12
在所有这些格式中,色度频道在水平方向和垂直方向上都要以系数2来进行再次采样。
IMC2
此格式与IMC1相同,只是V(Cr)和U(Cb)行在半跨距边界处进行了交错。
换句话说,就是色度区域中的每个完整跨距行都以一行V样例开始,然后是一行在下一个半跨距边界处开始的U样例(图10)。
此布局与IMC1相比,能够更加高效地利用地址空间。
它的色度地址空间缩小了一半,因此整体地址空间缩小了25%。
在各个4:
2:
0格式中,IMC2是第二首选格式,排在NV12之后。
图10.IMC2内存布局
IMC4
此格式与