【Android RTMP】Android Camera 视频数据采集预览 ( NV21 图像格式 | I420 图像格式 | NV21 与 I420 格式对比 | NV21 转 I420 算法 )

2023-03-27 21:16:47 浏览数 (2)

文章目录

  • 一、 NV21 与 I420 数据格式转换
  • 二、 NV21 数据格式
  • 三、 I420 数据格式
  • 四、 NV21 格式与 I420 格式对比
  • 五、 NV21 与 I420 图像大小
  • 六、 NV21 格式转为 I420 格式算法

一、 NV21 与 I420 数据格式转换


1 . 采集数据 :

① Camera 采集的数据 : 上面讲解了 Camera 摄像头采集图像数据之后 , 会回调 PreviewCallback 接口的 onPreviewFrame 方法 , onPreviewFrame 方法的 byte[] data 参数 , 就是 Camera 采集的图像数据 ;

② 采集的数据格式 : Camera 采集的图像数据是 NV21 格式的 ;

2 . x264 接收的格式 :

① RTMP 推流过程 : 在 RTMP 推流过程中 , 手机 Camera 采集到数据后 , 需要先使用 x264 将数据编码成 H.264 格式的 , 然后将 H.264 数据打包成 RTMP 数据 ;

② x264 接收格式 : x264 开源库的输入数据类型必须是 I420 格式 , 这里就涉及到了将 Camera 采集的 NV21 格式的数据 , 转为 x264 开源库需要的 I420 格式的数据 ;

3 . YUV420 格式 :

① 两个分支格式 : NV21 图像格式 和 I420 图像格式都属于 YUV420 图像格式的分支 ;

② YUV 说明 : YUV 各种中的 Y 表示明亮度和灰度 , UV 表示色度和饱和度 ;

③ 黑白图片 : 如果只有 Y 数据 , 那么就是灰度图片 , 这张图片是黑白的 ; UV 数据表示的是图像的色彩 ;

④ 存储原理 : 灰度数据 Y 保证全部满足 , 多个灰度数据公用 UV 色彩数据 , 这样就可以减少图像数据的大小 ;

二、 NV21 数据格式


NV21 图像格式数据排列 :

4 times 4

像素的图片为例 , 其有

16

个 Y 数据 , UV 数据只有

4

组 , 共

8

个 ;

① 数据的排列格式如下矩阵 :

begin{bmatrix} y1 & y2 & y3 & y4 \\ y5 & y6 & y7 & y8 \\ y9 & y10& y11& y12 \\ y13& y14& y15& y16 \\ v1 & u1 & v2 & u2 \\ v3 & u3 & v4 & u4\ end{bmatrix}

② 内存中的数据表示 : 这也是 NV21 数据中的数组排列方式 , 每个 YUV 数据各占

1

字节 , 如

1

个 Y 数据占

1

字节 ;

代码语言:javascript复制
byte[] data = {
	y1 , y2 , y3 , y4 ,
	y5 , y6 , y7 , y8 ,
	y9 , y10, y11, y12,
	y13, y14, y15, y16,
	v1 , u1 , v2 , u2 , 
	v3 , u3 , v4 , u4 , 
}

③ 数据使用情况 :

  • 灰度数据 y1 , y2 , y5 , y6 使用的是 v1 , u1 色彩数据 ;
  • 灰度数据 y3 , y4 , y7 , y8 使用的是 v2 , u2 色彩数据 ;
  • 灰度数据 y9 , y10, y13, y14 使用的是 v3 , u3 色彩数据 ;
  • 灰度数据 y11, y12, y15, y16 使用的是 v4 , u5 色彩数据 ;

三、 I420 数据格式


I420 图像格式数据排列 :

4 times 4

像素的图片为例 , 其有

16

个 Y 数据 , UV 数据只有

4

组 , 共

8

个 ;

① 数据的排列格式如下矩阵 :

begin{bmatrix} y1 & y2 & y3 & y4 \\ y5 & y6 & y7 & y8 \\ y9 & y10& y11& y12 \\ y13& y14& y15& y16 \\ u1 & u2 & u3 & u4 \\ v1 & v2 & v3 & v4\ end{bmatrix}

② 内存中的数据表示 : 这也是 NV21 数据中的数组排列方式 , 每个 YUV 数据各占

1

字节 , 如

1

个 Y 数据占

1

字节 ;

代码语言:javascript复制
byte[] data = {
	y1 , y2 , y3 , y4 ,
	y5 , y6 , y7 , y8 ,
	y9 , y10, y11, y12,
	y13, y14, y15, y16,
	u1 , u2 , u3 , u4 , 
	v1 , v2 , v3 , v4
}

③ 数据使用情况 :

  • 灰度数据 y1 , y2 , y5 , y6 使用的是 v1 , u1 色彩数据 ;
  • 灰度数据 y3 , y4 , y7 , y8 使用的是 v2 , u2 色彩数据 ;
  • 灰度数据 y9 , y10, y13, y14 使用的是 v3 , u3 色彩数据 ;
  • 灰度数据 y11, y12, y15, y16 使用的是 v4 , u5 色彩数据 ;

四、 NV21 格式与 I420 格式对比


NV21 格式与 I420 格式对比 :

① 数据量 : 相同像素点数的图像 , 其数据大小是相同的 ;

② Y 灰度值排列 : 其灰度值排列方式是相同的 , 都是在 1 ~ 16 位置依次排列 16 个像素点数 ;

③ UV 色彩值排列 : 其色彩值排列是不同的 ,

  • NV21 格式中 , UV 色彩值是交替排序的 , v1 , u1 , v2 , u2 , v3 , u3 , v4 , u4 ;
  • I420 格式中 , UV 色彩值是
4

个 u 先排列 , 然后排

4

个 v 数据 , u1 , u2 , u3 , u4 , v1 , v2 , v3 , v4 ;

五、 NV21 与 I420 图像大小


NV21 与 I420 图像大小 :

① 推导过程 :

4

像素值数据 :

4

个像素值 , 有

4

个 Y 灰度数据 , 占

4

字节 ;

1

个 Y 和

1

个 U 数据 , 占

2

字节 ;

4

像素值数据大小 :总共有

4 1 1 = 6

字节 ;

4

个像素对应

6

个字节 ;

  • 归纳 :
n

个像素对应

cfrac{n times 3}{2}

个字节数据 ;

② 计算公式为 : 已知图像像素的宽度和高度 ;

图像大小 ( 字节 ) = cfrac{宽度 times 高度 times 3}{2}

六、 NV21 格式转为 I420 格式算法


NV21 格式与 I420 格式的区别只是 UV 色彩值的排列方式不一样 , NV21图像转为 I420 图像 , 只需要将 NV21 格式图像交替排列的 UV 数据 , 按照 I420 格式图像的先 U 后 V 的顺序重新进行排列即可完成图像格式转换 ;

先将 NV21 格式数据中的 Y 灰度数据拷贝出来放在一个数组中 , 再将 NV21 数据中的 V 数据 , 和 U 数据分别拷贝出来 , 这里得到三个数组 , 分别存储 Y 数据 , U 数据 , V 数据 ;

将 NV21 数据中的 V 数据 , 和 U 数据分别拷贝出来的方式时 , 读取 Y 数据完毕后 , 取下一个数据就是 V 数据 , 放入 V 数组 , 再取下一个数据就是 U 数据 , 放入 U 数组 , 之后继续获取数据 , 交替放入 V 数组 / U 数组 , 最终就得到了

3

个数组 , 即 Y 数组 , U 数组 , V 数组 ;

0 人点赞