iOS音视频采集与格式转换(yuv转rgb)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS音视频采集与格式转换(yuv转rgb)相关的知识,希望对你有一定的参考价值。

参考技术A 基本流程
1.初始化输入设备
2.初始化输出设备
3.创建AVCaptureSession,用来管理视频与数据的捕获
4.创建预览视图

前面介绍了如何通过相机实时获取音视频数据,我们接下来就需要了解获取到的数据到底是什么样的,使用系统提供的接口获取到的音视频数据都保存在CMSampleBufferRef中,这个结构在ios中表示一帧音频/视频数据,它里面包含了这一帧数据的内容和格式,我们可以把它的内容取出来,提取出/转换成我们想要的数据。
代表视频的CMSampleBufferRef中保存的数据是yuv420格式的视频帧(因为我们在视频输出设置中将输出格式设为:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)。
在下面的回调中,可以拿到最终的CMSampleBufferRef数据

视频是由一帧一帧的数据连接而成,而一帧视频数据其实就是一张图片。
yuv是一种图片储存格式,跟RGB格式类似。
RGB格式的图片很好理解,计算机中的大多数图片,都是以RGB格式存储的。
yuv中,y表示亮度,单独只有y数据就可以形成一张图片,只不过这张图片是灰色的。u和v表示色差(u和v也被称为:Cb-蓝色差,Cr-红色差),
为什么要yuv?
有一定历史原因,最早的电视信号,为了兼容黑白电视,采用的就是yuv格式。
一张yuv的图像,去掉uv,只保留y,这张图片就是黑白的。
而且yuv可以通过抛弃色差来进行带宽优化。
比如yuv420格式图像相比RGB来说,要节省一半的字节大小,抛弃相邻的色差对于人眼来说,差别不大。
一张yuv格式的图像,占用字节数为 (width * height + (width * height) / 4 + (width * height) / 4) = (width * height) * 3 / 2
一张RGB格式的图像,占用字节数为(width * height) * 3
在传输上,yuv格式的视频也更灵活(yuv3种数据可分别传输)。
很多视频编码器最初是不支持rgb格式的。但是所有的视频编码器都支持yuv格式。
我们这里使用的就是yuv420格式的视频。
yuv420也包含不同的数据排列格式:I420,NV12,NV21.
其格式分别如下,
I420格式:y,u,v 3个部分分别存储:Y0,Y1...Yn,U0,U1...Un/2,V0,V1...Vn/2
NV12格式:y和uv 2个部分分别存储:Y0,Y1...Yn,U0,V0,U1,V1...Un/2,Vn/2
NV21格式:同NV12,只是U和V的顺序相反。
综合来说,除了存储顺序不同之外,上述格式对于显示来说没有任何区别。
使用哪种视频的格式,取决于初始化相机时设置的视频输出格式。
设置为kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange时,表示输出的视频格式为NV12;
设置为kCVPixelFormatType_420YpCbCr8Planar时,表示使用I420。
设置为kCVPixelFormatType_32RGBA时,表示使用BGRA。

GPUImage设置相机输出数据时,使用的就是NV12.
为了一致,我们这里也选择NV12格式输出视频。

libyuv是Google开源的实现各种YUV与RGB之间相互转换、旋转、缩放的库。它是跨平台的,可在Windows、Linux、Mac、android等操作系统,x86、x64、arm架构上进行编译运行,支持SSE、AVX、NEON等SIMD指令加速.

导入libyuv库,并设置头文件搜索路径,不然会报错

文章只介绍了使用AVFoundation进行视频采集和使用libyuv进行格式转换,音视频相关的知识还有很多,这里不再做详细介绍了。

像素格式

参考技术A 介绍略

(YCrCb)是指将亮度参量Y和色度参量U/V分开表示的像素格式,主要用于优化彩色视频信号的传输。
YUV像素格式来源于RGB像素格式,通过公式运算,YUV三分量可以还原出RGB,YUV转RGB的公式如下

一般,将RGB和YUV的范围均限制在[0, 255]间,则有如下转换公式:

YUV相比于RGB格式最大的好处是可以做到在保持图像质量降低不明显的前提下,减小文件大小。YUV格式之所以能够做到,是因为进行了采样操作。

YUV码流的存储格式与其采样方式密切相关,主流的采样方式有三种:YUV4:4:4(YUV444),YUV4:2:2(YUV422),YUV4:2:0(YUV420)。

YUV4:4:4采样,每一个Y对应一组UV分量。
YUV4:2:2采样,每两个Y共用一组UV分量。
YUV4:2:0采样,每四个Y共用一组UV分量。

YUV存储可以分为两种:packed(打包)和planar(平面);
packed:Y、U、V分量穿插着排列,三个分量存在一个Byte型数组里;
planar:Y、U、V分量分别存在三个Byte型数组中;

这四种格式每一种又可以分为2类(packed和planar),以YUYV为例,一个6*4的图像的存储方式如下:

YUV420p: I420、YV12
YUV420sp: NV12、NV21
同样,对于一个6*4的图像,这四种像素格式的存储方式如下:

I420、YV12三个分量均为平面格式,即分别存在三个Byte型数组中;
NV12、NV21的存储格式为Y平面,UV打包,即Y信息存储在一个数组中,UV信息存储在一个矩阵中。

参考 https://blog.csdn.net/cgwang_1580/article/details/79595958

以上是关于iOS音视频采集与格式转换(yuv转rgb)的主要内容,如果未能解决你的问题,请参考以下文章

iOS视频推流格式转换

如何将rgb 模式转换成 yuv 模式

图像RGB2YUV与YUV2RGB格式互转介绍

怎么将图像YUV格式转成RGB格式(C++)

走进音视频的世界——RGB与YUV格式

rgb颜色 红色 转换成yuv颜色空间是啥