FFmpeg及视频简介


一、音视频的应用场景

互动直播系统
娱乐直播系统
音视频特效
音视频剪辑

二、ffmpeg简介

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。前面的"FF"代表"Fast Forward"。 FFmpeg编码库可以使用GPU加速。

1.ffmpeg命令

ffmpeg:编解码,音频处理,特效;可以推流至流媒体服务器;
ffplay:播放器,依赖于ffmpeg;从流媒体服务器拉取音视频流;支持本地流播放;
vlc:依赖域ffmpeg,也支持使用rtmp协议从流媒体服务拉流

2.ffmpeg编译目录介绍

bin文件夹下:
ffmpeg命令:推送,音视频处理
ffplay命令:拉流
ffprole:侦测多媒体文件,文件信息等

include文件夹:
libavcodec:编解码
libavfilter:滤镜 特效
libavutil:基本工具
libswresample:音频重采样
libavdevice:管理设备
libavformat:文件格式处理
libpostproc:
libswscale:视频的缩放等处理
lib文件夹:
包含静态和动态库,与include一样

share文件夹:
文档相关内容,使用手册等

三、视频简介

1.视频基础知识

1.1 视频图像要素

视频是由有一组图像组成,为了传输被压缩,最终在显示设备上显示
图像是由像素组成,像素由RGB组成
分辨率:横向的像素点,纵向的像素点
位深:每一个像素占用的位数(最常见24位,RGB888,每个颜色都是8位
32位,RGBA,其中A表示alpha,表示透明度)
帧率:每秒钟播放的图像

1.2 屏幕显示原理

每个像素都由三原色组成
在这里插入图片描述
屏幕指标:
PPI:屏幕的质量,一寸长的空间放了多少像素点
DPI:每英寸的点数,基本上 DPI == PPI
PPI>300就属于视网膜级别,人眼区分不出来,认为是一体的

1.3 视频码流的计算

一.分辨率
1.分辨率:x像素个数 * y像素个数
2.常见的宽高比16:9和4:3。现在基本都是16:9
对于非标准的分辨率需要转换为16:9或4:3,否则在渲染时容易出错
3.360P(640360)/720P(1280720)/1K/2K.这些分辨率都是16:9的.
4:3常见的是640*480

二.帧率
每秒钟播放图像的个数
常见帧率:15,30,60帧/s
实时通信一般是15帧/s(帧率越大,占用的传输带宽就越大)
录课一般30帧/s能够满足需求;
电影一般在60帧/s;

要求的平滑度越高,帧率就越大。
要求的清晰度越高,分辨率就要越高。

三.码流计算方式
RGB码流=分辨率3Byte帧率
假设当前的分辨率 宽为1920 高为1080 像素深度为RGB三原色3Byte 帧率为1秒25帧 那么该每秒产生的RGB码流计算公式为:RGB码流=分辨率宽高像素深度每秒帧率 例如:192010803*25=155520000约155M。

1.4 什么是YUV数据

yuv也称YCbCr:Y表示明亮度,UV的作用是描述影像色彩和饱和度。其中,Cr是GB输入信号的红色部分和RGB信号的亮度的差异。而Cb反映的是RGB输入信号的蓝色部分和RGB的信号亮度值之间的差异。
广泛使用的原因:1.电视机最初用的就是YUV,为了保证兼容 2.数据量比RGB小
在这里插入图片描述
在这里插入图片描述
U分量,Cb分量 蓝色
在这里插入图片描述
V分量,Cr分量 红色
在这里插入图片描述

1.5 YUV与RGB之间的关系

手机,显示屏用的是RGB格式
电视是用的YUV格式
RGB与YUV的关系:
RGB用于屏幕图像的展示
YUV用于采集与编码
在这里插入图片描述
G’是失误
采集到数据想让其播放出来,需要转为RGB
在这里插入图片描述

1.6 YUV的常见格式

YUV4:4:4就是RGB格式,一副图像的数据量就是分辨率*3byte
在这里插入图片描述
在这里插入图片描述
YUV4:2:0是YUV格式中最标准的,是应用最广泛的格式,所有播放器都要支持该模式
在这里插入图片描述
在这里插入图片描述

1.7 YUV的存储格式

在这里插入图片描述
上述存储格式,可以保证彩色电视和黑白电视的兼容,对于黑白电视只要读取Y分量即可。
存储格式又可以细分为:
在这里插入图片描述
以上两个的主要区别是现存U还是现存V。IOS是YV12格式存储的;android系统一般都是NV21存储。
YUV的参考资料:
https://en.wikipedia.org/wiki/YUV

2.视频采集

2.1 ffmpeg命令行采集YUV数据

从设备采集

ffmpeg -f video4linux2 -s 640x480 -pix_fmt yuyv422 -i /dev/video0 out.yuv

从媒体文件采集

ffmpeg -i input.mp4 -an -c:v rawvideo -pix_fmt yuv420p out.yuv

-i:输入文件
-an:没有音频,去除音频
-c:v:表示视频编码器,使用rawvideo编码器做处理
-pix_fmt:指定YUV的存储格式yuv420p
播放YUV

ffplay -pix_fmt yuv420p -s 608*368 out.yuv(分辨率和yuv格式一定要正确,可以用过播放mp4文件获得)

播放Y分量

ffplay -pix_fmt yuv420p -s 1360*768 -vf extractplanes='y' out.yuv 

-vf:简单滤波(滤波器的一种)
提取各分量
在这里插入图片描述
-filter_complex:复杂滤波器
[y]是y分量数据的别名,最终分别生成三个yuv文件(上述引号为双引号)
播放分量:
ffplay -s 分辨率 -pix_fmt gray y.yuv(需要携带pix_fmt gray否则会按yuv格式读取数据,数据异常)
ffplay -s 分辨率(宽高除以2,因为是420格式) -pix_fmt gray u.yuv(需要携带pix_fmt gray否则会按yuv格式读取数据,数据异常)

2.2 api采集YUV数据

av_read_frame函数采集的pkt数据的size要注意
应该为:分辨率宽 * 高 *(1.5:yuv420,2:yuv422,3:yuv444)
uyuv的格式如何,可以查阅:
https://www.fourcc.org/yuv.php

3.H.264编码原理

3.1 GOP介绍

在这里插入图片描述
一组强相关的一组帧数据(group of picture)
在这里插入图片描述
从而达到更高的压缩比

3.2 H264中的I/P/B帧

GOP中的第一组数据可以称为I帧,IDR帧属于I帧。帧内压缩技术是指单独编码,不依赖其他帧
在这里插入图片描述
解码顺序:I,P,B
虽然B帧压缩率高,但占用CPU耗时高,对于实时通讯有影响,因此使用较少
音视频服务时,用B帧较多;直播时用P帧较多,因为对实时性有要求。
IDR帧与I帧的区别与联系
在这里插入图片描述
IDR帧的作用是防止错误传递
帧与分组的关系
在这里插入图片描述
当I和P解码后,才能解码B,B帧之间是没有参考关系的。
当所有帧都解码完成后,再按帧顺序进行播放。

3.3 SPS与PPS帧

序列参数集:GOP的参数设置
图像参数集:对GOP中每个图像的参数约束
在这里插入图片描述

3.4 H.264压缩技术

**压缩技术涉及:**帧内压缩、帧间压缩、整数离散余弦变换、CABAC压缩
**有损压缩:**帧内压缩、帧间压缩
**无损压缩:**DCT、CABAC压缩

3.4.1 压缩技术的基础——宏块

什么是宏块
宏块是H264压缩技术的基础知识点,无论是帧内压缩和帧间压缩技术,都是以宏块为单位的
在这里插入图片描述
宏块划分
将上述切换为一个个宏块,如下,左上角切为88的像素,可称为一个宏块(宏块的大小不是限制死为88的)。
每个像素都有一定的值,每个值都有特定的颜色,即如下图所示
在这里插入图片描述
当原始图片全部宏块化后,得到下图,宏块非常小,压缩时控制力更强,压缩率高;宏块特别大,处理速度特别快。
对于没有太多细节的图像部分,宏块可以划分的大些
在这里插入图片描述
宏块的尺寸
H264的宏块尺寸如下
在这里插入图片描述

3.4.2 帧内压缩技术

帧内压缩技术针对I帧和IDR帧使用。
涉及的理论基础

相邻像素差别不大,所以可以进行宏块预测
人们对亮度的敏感度超过色度
YUV很容易将亮度与色度分开
帧内预测
H264提供9种预测模式,推算宏块。右图为每个宏块的预测是采用了哪种模式
在这里插入图片描述
当行列的数值固定时,9种模式是如何对4*4的栅格进行预测的
在这里插入图片描述
在这里插入图片描述
预测图像与原始图像还是会存在偏差,我们可以将两者进行比对,得到残差值
在这里插入图片描述
将预测模式信息与残差值进行压缩,解码时,依据预测模式与预测图像,与残差值,还原图像

3.4.3 帧间压缩技术

帧间压缩技术针对P帧和B帧使用
涉及的理论基础
在一个GOP内,后面的帧参考参考帧进行压缩;
运动估计:通过宏块匹配的方法找到运动矢量;
运动补偿:就是指解码时找到残差值,在解码时补偿上去;

参考帧
红色为参考帧,望远镜为宏块,后面的帧只需要记录望远镜宏块的运动矢量即可。
在这里插入图片描述
运动估计
将一张图划分成多个宏块,同一个GOP中有很多相似帧,抽出相邻两帧,进行遍历匹配宏块,找到台球宏块的运动矢量。
遍历匹配宏块涉及宏块查找算法,如三步搜索、二维对数搜索、四步搜索和钻石搜索。

运动补偿
在这里插入图片描述
在进行宏块查找时,宏块的匹配相似度无法做到100%,在生成运动矢量后,还要计算根据运动矢量推算出的帧与原始帧的残差值

视频花屏和卡顿原因
在这里插入图片描述
在这里插入图片描述
花屏与卡顿无法同时兼顾
帧间压缩比要比帧内压缩比高

3.4.4 无损压缩技术

H264经过有损后,还要进行无损压缩
DCT变换
在这里插入图片描述
经过有损压缩后,数据在表中较分散,经过DCT变换后,对数据进行滤波,所有数据更加集中,便于进行压缩
宏块转化为数组,经过DCT转化后变为如下
在这里插入图片描述
当数据DCT后,进行无损压缩
第一种方法VLC,另一种是CABAC
VLC方法:
在这里插入图片描述
VLC是可变长的编码,如A-Z,常用的用短的编码,不常用的用长的编码
CABAC方法:
在这里插入图片描述
CABAC是上下文适配的二进制算术编码,上图为VLC与CBC对比图。VLC属于MPEG2,CABAC属于H264
CABAC由于有上下文,后续的块会非常小

3.4.5 H.264编解码流程

编码流程:
在这里插入图片描述
图中,Fn为需要进行编码的帧,F’n-1是参考帧,F’n为编码后再经过解码后的帧。

帧内压缩(Intra):Fn如果是IDR帧,首先选择帧内预测模式,进行帧内预测,然后进行残差值计算(得到Dn),将预测数据+残差值,经过T和Q的转换量化(即无损编码技术),然后进行拆包,打成NAL头,分发数据出去

帧间压缩(Inter):Fn如果是P帧或B帧,首先Fn-1与Fn经过运动评估ME,拿到运动矢量MC,推算出Fn的值,再与Fn的真实值进行残差计算,经过T和Q的转换量化(即无损编码技术),然后进行拆包,打成NAL头,分发数据出去

解码流程:
在这里插入图片描述
帧内压缩(Intra)
帧间压缩(Inter)

H.264参考资料
在这里插入图片描述
第一个是H264的白皮书,介绍H264
第二个是H264的具体实现编码器,x264编码器实现的功能最全

4.H.264重要参数介绍

4.1 H.264的码流结构

分层存储
NAL层:Network Abstraction Layer,视频数据网络抽象层。解决丢包,乱序,重传问题
VCL层:Video Coding Layer,视频数据编码层
在这里插入图片描述
上半部分是编码后的视频帧,每个视频帧由多个slice组成(方便传输,灵活度高),通常是1个
每个slice由多个宏块组成,宏块又分成子块

码流基本概念
SODB(String Of Data Bits):原始数据比特流,长度不一定是8的倍数,故需要补齐,它是由VCL层产生的。
RBSP(Raw Byte Sequence Payload):SODB + trailing bits,trailing bits是指如果SODB最后一个字节不对齐,则补1和多个0.
NALU:NAL Header(1B) + RBSP

下图实例为一个NAL单元,其中一个图像可以包含多个Slice DATA(但通常仅包含以一个Slice DATA)
在这里插入图片描述

在这里插入图片描述
Slice结构
在这里插入图片描述
mb_type:预测类型,mb_pred:预测值,coded_residual:残差值

整体码流结构
整个串起来,H264码流通常为两种格式Annexb和RTP。Annexb常为文件中的格式
startcode为起始码,固定为00000001。网络传输时使用RTP,没有startCode
在这里插入图片描述

4.2 H.264的SPS、PPS和Slice结构

在H.264标准协议中规定了多种不同的NAL Unit类型,类型值为7时,携带的为SPS;类型值为8时,携带的为PPS。

4.2.1 SPS

SPS中的重要参数
profile:对视频压缩特性的描述,Profile越高,就说明采用了越高级的压缩特性。(描述如何压缩,包括那些压缩技术)
在这里插入图片描述
CONSTRAINED BASELINE是基础
压缩率MAIN大于CONSTRAINED BASELINE
下图中每一层都增加了新的压缩特性,使得压缩比更高
在这里插入图片描述

level:Level是对视频的描述,Level越高,视频的码率、分辨率、fps越高(对视频规格的描述,对哪些视频规格进行编码)
在这里插入图片描述
分辨率相关参数
拿到前两个属性就可以计算出视频的宽和高分辨率,宽+1,乘以16
如果图像是否需要裁减为1,则关注灰色字段
在这里插入图片描述
帧相关参数
帧数:一个GOP中解码的帧号的最大帧数,如果帧数为0,则log2(max_frame_num)- 4 = 0,则max_frame_num = 16,帧号范围是0~15一个循环
sliceheader中有frameNumber就是帧号
参考帧数:解码时,参考帧的缓冲队列是多大数量
显示帧序号:将数据解码后,在GOP中显示顺序的计算方式:0,1,2三个值
帧率相关参数:
在这里插入图片描述

4.2.2 PPS

参数2:一帧中有多少个分片
在这里插入图片描述

4.2.3 Slice Header

如果只有I和P帧不需要关注解码帧序号,有B帧才需要关注
在这里插入图片描述

4.2 H.264的分析工具

前两者收费
在这里插入图片描述
在这里插入图片描述

5.H.264编码ffmpeg实战

基本编码步骤
1.打开编码器:使用什么编码器,GOP参数,码流大小,分辨率
2.转换NV12(设备采集到的格式)到YUV420P
3.准备编码数据AVFrame
4.H264编码

猜你喜欢

转载自blog.csdn.net/weixin_39736022/article/details/120603776