前言
通过我的上一篇文章,实时采集视频的LocalSocket方式在新的Android SDK上是跑不通的,那么便只剩下Camera了。本文将利用Camera
来进行实时采集视频,MediaCodec
进行硬编码来输出yuv、h264文件。
YUV
通过Camera采集到的原始数据是YUV(NV21)格式的,何为YUV?
YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。YUV是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。
YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0。
- YUV 4:4:4采样,每一个Y对应一组UV分量。
- YUV 4:2:2采样,每两个Y共用一组UV分量。
- YUV 4:2:0采样,每四个Y共用一组UV分量。
这里只抛出这样一个概念,详情请参见文末的参考
。
H264
H264作为当前最火热的编码方式,它有着特殊的分层结构。
H.264 的功能分为两层:视频编码层(VCL, Video Coding Layer)和网络提取层(NAL, Network Abstraction Layer)。VCL 数据即编码处理的输出,它表示被压缩编码后的视频数据 序列。在 VCL 数据传输或存储之前,这些编码的 VCL 数据,先被映射或封装进 NAL 单元中。每个 NAL 单元包括一个原始字节序列负荷(RBSP, Raw Byte Sequence Payload)、一组对应于视频编码的 NAL 头信息。RBSP 的基本结构是:在原始编码数据的后面填加了结尾比特。一个bit“1”若干比特“0”,以便字节对齐。
在H264中,无论是SPS、PPS或者是slice data,都是由一个NAL unit所组成。
NALU头结构:NALU类型(5bit)、重要性指示位(2bit)、禁止位(1bit)。
- NALU类型:1~12由H.264使用,24~31由H.264以外的应用使用。
- 重要性指示:标志该NAL单元用于重建时的重要性,值越大,越重要。
- 禁止位:网络发现NAL单元有比特错误时可设置该比特为1,以便接收方丢掉该单元。
这里依然是抛出这样一个概念,详情请参见文末的参考
。(因为我自己也没怎么弄懂,哈哈哈~)
实例
下面直接结合Camera
与MediaCodec
来实现视频采集与编码,并且输出yuv、h264文件。
初始化MediaCodec:
1 | private void initMediaCodec() { |
获取Camera:
1 | private boolean createCamera(SurfaceHolder surfaceHolder) { |
采集并编码:
1 | Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() { |
获取摄像头支持的分辨率代码:
1 | public static void determineClosestSupportedResolution(Camera.Parameters parameters) { |
后面运行,点击开始
进行录制,再次点击结束录制,会在sdcard上生成2个文件test_1280x720.yuv
、test_1280x720.h264
。
下载工具后进行查看文件便能看到录制的视频了。
YUV工具我是用的雷神改作的一个:修改了一个YUV/RGB播放器。
H264工具则是用的VLC。
Tip:Camera采集默认是横屏,所以竖屏采集输出的图像需要旋转90度,解决方法参见参考
即demo中的代码。
参考
Camera的简单使用浅析
Android Camera原始帧格式转换 —— 获取Camera图像(一)
直播必备之YUV使用总结 —— Android常用的几种格式:NV21/NV12/YV12/YUV420P的区别
Camera
MediaCodec
Video Rendering with 8-Bit YUV Formats
YUV420SP图像的旋转
图文详解YUV420数据格式
Android 实时视频采集—Cameara预览采集
H.264中如何判斷某一段是否為SPS(Sequence Parameter Set)或PPS(Picture Parameter Set)
EasyPusher安卓Android手机直播推送之MediaCodec 硬编码H264格式
Android屏幕直播方案