简单了解 iOS CVPixelBuffer (中)

489 篇文章 14 订阅
464 篇文章 13 订阅

1、前言:

「简单了解 iOS CVPixelBuffer (上)」中,我们了解了CVPixelBuffer如何创建、修改、以及检查CVPixelBuffer相关的参数。在上篇文末我们有讲到在这篇文章中,我们将了解颜色空间RGB和YUV的区别以及相关的背景知识,然后回过头来再看CVPixelBuffer中的kCVPixelFormatType相关的类型。

相信大家对于RGB都不陌生吧,那么YUV大家是否了解呢,它为我们做了些什么?

在开篇我先提出一个问题:为什么要使用YUV呢? 这个问题在我们了解了颜色空间之后,相信大家心中就已经有了答案。接下来开始我们的正文。

2、颜色空间

颜色空间一词源于英文的Color Space,在色彩学中,人们建立了多种颜色模型,以一维、二维、三维甚至四维空间坐标来表示某一色彩,这种用坐标系统来定义的颜色范围即颜色空间。

我们经常用到的颜色空间主要有RGB、YUV、CMYK、HSB、HSL等,其中RGBYUV是视频中使用较多的两种色彩空间。

2.1 RGB

RGB 是由红(Red)、绿(Green)、蓝(Blue)三种颜色组成,我们称为三原色。每个颜色可以取值不同,将三种颜色相混合后,会组成其他的不同的颜色。使用 RGB 表示的图像中,每个像素都有红、绿、蓝三种颜色,每个颜色占8 bit,即1 byte。所以一个像素占用3 byte

红、绿、蓝三个颜色通道每种颜色各分为256阶亮度,取值为0-255

在存储时,我们常常以R G B或者B G R的顺序进行排列,所以在前文中,我们有看到pixelFormatType有kCVPixelFormatType_32RGBAkCVPixelFormatType_32BGRA两种相似的类型(这里的A指的是AlphaAlpha 通道一般用作不透明度参数),其实这两个类型只是它们的编码上的顺序不同;

接下来我们熟悉下另一个颜色空间。

【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发

【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~

2.2 YUV

YUV 是 Y’UV、YUV、YCbCr、YPbPr 等色彩空间的统称

YUV是由 YUV组成,前者表示明亮度 (Luminance、Luma),后者表示色度(Chrominance、Chroma),色度包括两个⽅面:色调、饱和度

使用YUV的图像,每个像素点都包含 Y、U、V 分量,YUV分量是分离的,如果只有Y没有UV,那么图像就像以前的黑白电视机一样。为了兼容老式电视机,彩色电视机采用的也是 YUV 的颜色空间,不过UV是存在的。

2.2.1 采样格式

YUV采样格式是个重点,YUV采样格式有三种:

  • YUV 4:4:4

  • YUV 4:2:2

  • YUV 4:2:0

YUV444

YUV444代表每个Y分量分别对应一个U分量和一个V分量。 以4个像素为例: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] 存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3

YUV422

YUV422代表每两个Y分量分别共用一个U分量和一个V分量。 以4个像素为例: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] 存放的码流为: Y0 U0 Y1 V1 Y2 U2 Y3 V3 映射出像素点为: [Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]

YUV420

YUV420代表每四个Y分量分别共用一个U分量和一个V分量。 以8个像素为例: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] [Y5 U5 V5] [Y6 U6 V6] [Y7 U7 V7] [Y8 U8 V8] 存放的码流为: Y0 U0 Y1 Y2 U2 Y3 Y5 V5 Y6 Y7 V7 Y8 映射出像素点为: [Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7] [Y5 U0 V5] [Y6 U0 V5] [Y7 U2 V7] [Y8 U2 V7]

综上来看,YUV444的存储的数据量和RGB相同,YUV422是RGB的2/3,YUV420是RGB的1/2。

2.2.2 存储方式

YUV有两种存储方式,一种是打包(packed),一种是平面(planar).

  • packed: 先连续存储所有Y分量,然后交叉存储U、V分量;

  • planar:先连续存储所有Y分量,然后在连续存储U、V分量(保证了每个区块连续);

在懂得这些颜色空间的编码格式以及存储方式之后,我们再来看上文中的这些类型的定义,就可以依据这些理论推导出来这些类型代表什么了;

比如说: 444、422、420 表示不同的采样格式(压缩比) 8、10、16 表示bit位数 Planar、BiPlanar 表示平面、双平面 VideoRange、FullRange 其意义是YUV颜色空间中亮度部分 Y 的取值范围,fullRange的取值范围为luma=[0,255] chroma=[1,255],而videoRange的取值范围为luma=[16,235] chroma=[16,240]

 kCVPixelFormatType_422YpCbCr8     = '2vuy',     /* Component Y'CbCr 8-bit 4:2:2, ordered Cb Y'0 Cr Y'1 */
  kCVPixelFormatType_4444YpCbCrA8   = 'v408',     /* Component Y'CbCrA 8-bit 4:4:4:4, ordered Cb Y' Cr A */
  kCVPixelFormatType_4444YpCbCrA8R  = 'r408',     /* Component Y'CbCrA 8-bit 4:4:4:4, rendering format. full range alpha, zero biased YUV, ordered A Y' Cb Cr */
  kCVPixelFormatType_4444AYpCbCr8   = 'y408',     /* Component Y'CbCrA 8-bit 4:4:4:4, ordered A Y' Cb Cr, full range alpha, video range Y'CbCr. */
  kCVPixelFormatType_4444AYpCbCr16  = 'y416',     /* Component Y'CbCrA 16-bit 4:4:4:4, ordered A Y' Cb Cr, full range alpha, video range Y'CbCr, 16-bit little-endian samples. */
  kCVPixelFormatType_444YpCbCr8     = 'v308',     /* Component Y'CbCr 8-bit 4:4:4 */
  kCVPixelFormatType_422YpCbCr16    = 'v216',     /* Component Y'CbCr 10,12,14,16-bit 4:2:2 */
  kCVPixelFormatType_422YpCbCr10    = 'v210',     /* Component Y'CbCr 10-bit 4:2:2 */
  kCVPixelFormatType_444YpCbCr10    = 'v410',     /* Component Y'CbCr 10-bit 4:4:4 */
  kCVPixelFormatType_420YpCbCr8Planar = 'y420',   /* Planar Component Y'CbCr 8-bit 4:2:0.  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrPlanar struct */
  kCVPixelFormatType_420YpCbCr8PlanarFullRange    = 'f420',   /* Planar Component Y'CbCr 8-bit 4:2:0, full range.  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrPlanar struct */
  kCVPixelFormatType_422YpCbCr_4A_8BiPlanar = 'a2vy', /* First plane: Video-range Component Y'CbCr 8-bit 4:2:2, ordered Cb Y'0 Cr Y'1; second plane: alpha 8-bit 0-255 */
  kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v', /* Bi-Planar Component Y'CbCr 8-bit 4:2:0, video-range (luma=[16,235] chroma=[16,240]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
  kCVPixelFormatType_420YpCbCr8BiPlanarFullRange  = '420f', /* Bi-Planar Component Y'CbCr 8-bit 4:2:0, full-range (luma=[0,255] chroma=[1,255]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */ 
  kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange = '422v', /* Bi-Planar Component Y'CbCr 8-bit 4:2:2, video-range (luma=[16,235] chroma=[16,240]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
  kCVPixelFormatType_422YpCbCr8BiPlanarFullRange  = '422f', /* Bi-Planar Component Y'CbCr 8-bit 4:2:2, full-range (luma=[0,255] chroma=[1,255]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
  kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange = '444v', /* Bi-Planar Component Y'CbCr 8-bit 4:4:4, video-range (luma=[16,235] chroma=[16,240]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
  kCVPixelFormatType_444YpCbCr8BiPlanarFullRange  = '444f', /* Bi-Planar Component Y'CbCr 8-bit 4:4:4, full-range (luma=[0,255] chroma=[1,255]).  baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
  kCVPixelFormatType_422YpCbCr8_yuvs = 'yuvs',     /* Component Y'CbCr 8-bit 4:2:2, ordered Y'0 Cb Y'1 Cr */
  kCVPixelFormatType_422YpCbCr8FullRange = 'yuvf', /* Component Y'CbCr 8-bit 4:2:2, full range, ordered Y'0 Cb Y'1 Cr */

3、写在最后

看到这里,为什么要使用YUV呢? 我想每个人心中都已经有了答案。 YUV的优势基本上也已经一目了然,因为压缩率比RGB要高很多,所占的数据存储量相对较小,所以适用于内存中传输视频数据或者处理图像等等一系列的操作。

原文链接:简单了解 iOS CVPixelBuffer (中) - 掘金

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值