资讯详情

【Android RTMP】Android Camera 视频数据采集预览 ( NV21 图像格式 | I420 图像格式 | NV21 与 I420 格式...

文章目录

  • 安卓直播推广专栏博客总结
  • 一、 NV21 与 I420 数据格式转换
  • 二、 NV21 数据格式
  • 三、 I420 数据格式
  • 四、 NV21 格式与 I420 格式对比
  • 五、 NV21 与 I420 图像大小
  • 六、 NV21 格式转为 I420 格式算法

安卓直播推广专栏博客总结


  • 资源下载地址 , 服务器搭建 , x264 , faac , RTMPDump , 源代码及交叉编译库 , 本专栏 Android 流源码直播 ;
  • han1202012 / RTMP_Pusher

  • 【Android RTMP】RTMP 搭建直播推流服务器 ( Ubuntu 18.04.4 虚拟机 )

编码器 , 和 RTMP 开源库数据包装包装 :

  • 【Android RTMP】RTMPDumb 源码导入 Android Studio ( 交叉编译 | 配置 CMakeList.txt 构建脚本 )

  • 【Android RTMP】Android Studio 集成 x264 开源库 ( Ubuntu 交叉编译 | Android Studio 导入函数库 )

  • 【Android RTMP】RTMP 数据格式 ( FLV 视频格式分析 | 文件头 Header 分析 | 标签 Tag 分析 | 视频标签 Tag 数据分析 )

  • 【Android RTMP】RTMP 数据格式 ( FLV 视频格式分析 | AVC 序列头格式分析 )

  • 【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 相机预览数据回调接口 )

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

  • 【Android RTMP】Android Camera 视频数据采集预览 ( 设置图像传感器的方向 | Camera 使用流程 | 申请动态权限 )

  • 【Android RTMP】x264 编码器的初始化和设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )

  • 【Android RTMP】x264 图像数据编码 ( Camera 图像数据采集 | NV21 图像数据传输 Native 处理 | JNI 传输字节数组 | 局部引用变量处理 | 线程互斥 )

  • 【Android RTMP】x264 图像数据编码 ( NV21 格式中的 YUV 数据排列 | Y 复制灰度数据 | U 复制颜色值数据 | V 饱和度数据复制 | 图像编码操作 )

  • 【Android RTMP】RTMPDump 封装 RTMPPacket 数据包 ( 封装 SPS / PPS 数据包 )

  • 【Android RTMP】RTMPDump 封装 RTMPPacket 数据包 ( 关键帧数据格式 | 非关键帧数据格式 | x264 编码后的数据处理 | 封装 H.264 视频数据帧 )

  • 【Android RTMP】RTMPDump 推流过程 ( 独立线程推流 | 创建推流器 | 初始化操作 | 设置推流地址 | 启用写出 | 连接 RTMP 服务器 | 发送 RTMP 数据包 )

  • 【Android RTMP】RTMP 直播推流 ( 购买阿里云服务器 | 远程服务器控制 | 搭建 RTMP 服务器 | 服务器配置 | 推广软件配置 | 直播软件配置 | 推流直播效果展示 )

  • 【Android RTMP】RTMP 总结直播推广阶段 ( 搭建服务器端 | Android 手机编码推流 | 电脑端观看直播 | 查看服务器状态 )

  • 【Android RTMP】NV21 图像旋转处理 ( 问题描述 | 图像顺时针旋转 90 度方案 | YUV 图像旋转细节 | 手机屏幕旋转方向 )

  • 【Android RTMP】NV21 图像旋转处理 ( 图像旋转算法 | 后置摄像头顺时针旋转 90 度 | 顺时针旋转前置摄像头 90 度 )

  • 【Android RTMP】NV21 图像旋转处理 ( 快速搭建 RTMP 服务器 Shell 脚本 | 创建 RTMP 服务器镜像 | 浏览器观看直播 | 前置 / 后置摄像头图像旋转效果显示 )

  • 【Android RTMP】采集音频数据编码 ( 采集音频数据编码 | AAC 高级音频编码 | FAAC 编码器 | Ubuntu 交叉编译 FAAC 编码器 )

  • 【Android RTMP】采集音频数据编码 ( FAAC 头文件和静态库复制 AS | CMakeList.txt 配置 FAAC | AudioRecord 音频采样 PCM 格式 )

  • 【Android RTMP】音频数据采集编码 ( AAC 音频格式分析 | FLV 音频数据标签分析 | AAC 音频数据标签头 | 配置信息的音频解码 )

  • 【Android RTMP】采集音频数据编码 ( FAAC 设置音频编码参数 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )

  • 【Android RTMP】采集音频数据编码 ( FAAC 编码器编码 AAC 音频解码信息 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )

  • 【Android RTMP】采集音频数据编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )


手机收集视频 / 音频数据 , 使用视频数据 H.264 编码 , 音频数据使用 AAC 编码 , 最后,将音视频数据全部打包 RTMP 数据包中 , 使用 RTMP 协议上传到 RTMP 服务器中 ;/font>

Android 端中主要完成手机端采集视频数据操作 , 并将视频数据传递给 JNI , 在 NDK 中使用 x264 将图像转为 H.264 格式的视频 , 最后将 H.264 格式的视频打包到 RTMP 数据包中 , 上传到 RTMP 服务器中 ;

本篇博客中主要讲解 Android 端数据采集 , Camera 摄像头获取 NV21 数据后 , 将 NV21 数据转为 x264 需要的 I420 数据 , 然后将 I420 数据编码成 H.264 格式的数据 ;

一、 NV21 与 I420 数据格式转换


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

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

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

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

NV21 图像格式I420 图像格式都属于 YUV420 图像格式的分支 ;

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

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

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

二、 NV21 数据格式


以 4 × 4 4 \times 4 4×4 像素的图片为例 , 其有 16 16 16 个 Y 数据 , UV 数据只有 4 4 4 组 , 共 8 8 8 个 ;

[ y 1 y 2 y 3 y 4 y 5 y 6 y 7 y 8 y 9 y 10 y 11 y 12 y 13 y 14 y 15 y 16 v 1 u 1 v 2 u 2 v 3 u 3 v 4 u 4 ] \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} ⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡​y1y5y9y13v1v3​y2y6y10y14u1u3​y3y7y11y15v2v4​y4y8y12y16u2u4​⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤​

这也是 NV21 数据中的数组排列方式 , 每个 YUV 数据各占 1 1 1 字节 , 如 1 1 1 个 Y 数据占 1 1 1 字节 ;

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 数据格式


以 4 × 4 4 \times 4 4×4 像素的图片为例 , 其有 16 16 16 个 Y 数据 , UV 数据只有 4 4 4 组 , 共 8 8 8 个 ;

[ y 1 y 2 y 3 y 4 y 5 y 6 y 7 y 8 y 9 y 10 y 11 y 12 y 13 y 14 y 15 y 16 u 1 u 2 u 3 u 4 v 1 v 2 v 3 v 4 ] \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} ⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡​y1y5y9y13u1v1​y2y6y10y14u2v2​y3y7y11y15u3v3​y4y8y12y16u4v4​⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤​

这也是 NV21 数据中的数组排列方式 , 每个 YUV 数据各占 1 1 1 字节 , 如 1 1 1 个 Y 数据占 1 1 1 字节 ;

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 格式对比


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

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

其色彩值排列是不同的 ,

  • , UV 色彩值是交替排序的 , ;

  • , UV 色彩值是 4 4 4 个 u 先排列 , 然后排 4 4 4 个 v 数据 , ;

五、 NV21 与 I420 图像大小


  • 4 4 4 像素值数据 : 4 4 4 个像素值 , 有 4 4 4 个 Y 灰度数据 , 占 4 4 4 字节 ; 1 1 1 个 Y 和 1 1 1 个 U 数据 , 占 2 2 2 字节 ;

  • 4 4 4 像素值数据大小 :总共有 4 + 1 + 1 = 6 4 + 1 + 1 = 6 4+1+1=6 字节 ;

  • 4 4 4 个像素对应 6 6 6 个字节 ;

  • 归纳 : n n n 个像素对应 n × 3 2 \cfrac{n \times 3}{2} 2n×3​ 个字节数据 ;

已知图像像素的宽度和高度 ;

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

六、 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 3 3 个数组 , 即 Y 数组 , U 数组 , V 数组 ;

标签: 连接器y16h

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台