一、视频文件
1、视频格式
常见格式:mp4、mkv、flv
封装的数据:音频码流、视频码流
常用工具: [FFmpeg下载]:https://ffmpeg.org/download.html
下载、安装并配置环境变量
ffmpeg.exe 视频编解码
ffplay.exe 播放器库
ffprobe.exe 音视频分析工具
2、视频播放—cmd命令
ffplay -i 视频文件目录
回车后开始播放视频
返回信息包含内部包含视频或者音频信息
默认播放Stream #0:0 视频或音频
例如下图:包含两条视频信息(显示Video),无音频信息
如果想播放第二条视频(Stream #0:1),可执行命令:
ffplay -i 视频目录 -vst 1
3、视频编码
视频就是连续的图像序列,不经过编码的连续图像数据数据量太大。
各种编码方式目的都是为了压缩,使体积更小,便于存储和传输,编码的核心思想就是去除冗余信息。
(1)空间冗余:图像内部相邻像素之间存在较强的相关性多造成的冗余
(2)时间冗余:视频图像序列中的不同帧之间的相关性所造成的冗余
(3)视觉冗余:人眼不能感知或者不敏感的那部分图像
(4)信息熵冗余:也称编码冗余,人们用于表达某一信息的比特数总比理论上表示该信息所需要的最少比特数要大,他们之间的差距就是信息熵冗余,或称编码冗余
熵编码例子:
11112222 8
4142 转换为4个1个2 4 省一半空间
(5)知识冗余:是指在有些图像中还包含与某些验证知识有关的信息
4、H.264码流分析
H.264码流文件分为两层
(1)VCL:视频编码层
负责高效的视频内容表示,VCL数据即编码处理的输出,表示被压缩编码后的视频数据序列。
(2)NAL:网络提取层
负责以网络所需求的恰当的方式对数据进行打包和传送,是传输层,不管在本地播放还是网络播放,都是需要这一层来传输。
VCL就是压缩编码后的原始数据。
VCL数据封装到NAL单元后,才可用于传输或存储
类比:VCL像JavaBean,NAL像Json序列化,经过包装后才能进行数据的传输
.h264文件
一般H.264编码器输出:起始码+NALU(NAL)单元
起始码为:0x00000001或者0x000001
起始码作用:区分每个单元的开头
起始码后面跟的第1个字节是NAL的Header信息,这个字节的低5位表示NALU类型。
5、片、宏块
一帧图片经过编码器之后,就被编码成一个或多个片,每片包含整数个宏块,NAL单元中就是装载着这些片的载体。
二、直播推流实践
1、图像采集
Camera
Camera2
CameraX
NDKCamera
步骤
(1)构建预览布局 SurfaceView或者TextureView,相当于画布来显示摄像头数据
(2)打开相机 Camera.open
(3)设置参数 Camera.Parameters
(4)设置预览数据回调 PreviewCallback
(5)设置预览画布并启动 setPreviewTexture/startPreview
(6)释放相机 stopPreview/release
2、YUV数据
YUV主要应用于优化彩色视频信号的传输,与RGB相比,YUV只需要占用极少的频宽,RGB则需要三个独立频道的信号同时传输。
YUV中Y代表明亮度,也称灰阶值,UV表示的则是色度(色调饱和度)也叫YCbCr
如果只有Y数据的图像就是黑色的,加上UV数据图像就显示成彩色的了。
编码使用YUV而不是RGB的原因:
使用YUV格式才能极大的去除冗余信息,人眼对亮点信息更敏感,对色度敏感度不高。也就是说,可以压缩UV数据,而人眼难以发现。所以压缩算法的第一步就是先把RGB数据转换为YUV数据,对Y少压缩一点,对UV压缩多一点,以平衡图像效果和压缩率
NV21与I420
YUV因为采样和数据排列方式的不同,分为不同的存储方式。
一般摄像头输出为NV21格式,而I420格式则是绝大多数编解码器默认输入输出格式。
NV21数据量的大小是widthheight3/2
NV21数据转I420数据:
3、MediaCodec
可以访问Android底层的多媒体编解码器,例如:编码器/解码器组件