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 图像格式数据排列 : 以
像素的图片为例 , 其有
个 Y 数据 , UV 数据只有
组 , 共
个 ;
① 数据的排列格式如下矩阵 :
② 内存中的数据表示 : 这也是 NV21 数据中的数组排列方式 , 每个 YUV 数据各占
字节 , 如
个 Y 数据占
字节 ;
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 ,
}
③ 数据使用情况 :
I420 图像格式数据排列 : 以
像素的图片为例 , 其有
个 Y 数据 , UV 数据只有
组 , 共
个 ;
① 数据的排列格式如下矩阵 :
② 内存中的数据表示 : 这也是 NV21 数据中的数组排列方式 , 每个 YUV 数据各占
字节 , 如
个 Y 数据占
字节 ;
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
}
③ 数据使用情况 :
NV21 格式与 I420 格式对比 :
① 数据量 : 相同像素点数的图像 , 其数据大小是相同的 ;
② Y 灰度值排列 : 其灰度值排列方式是相同的 , 都是在 1 ~ 16 位置依次排列 16 个像素点数 ;
③ UV 色彩值排列 : 其色彩值排列是不同的 ,
个 u 先排列 , 然后排
个 v 数据 , u1 , u2 , u3 , u4 , v1 , v2 , v3 , v4 ;
NV21 与 I420 图像大小 :
① 推导过程 :
像素值数据 :
个像素值 , 有
个 Y 灰度数据 , 占
字节 ;
个 Y 和
个 U 数据 , 占
字节 ;
像素值数据大小 :总共有
字节 ;
个像素对应
个字节 ;
个像素对应
个字节数据 ;
② 计算公式为 : 已知图像像素的宽度和高度 ;
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 数组 , 最终就得到了
个数组 , 即 Y 数组 , U 数组 , V 数组 ;