ffmpeg概念
Fmpeg的名称来自MPEG视频编码标准,前面的“FF”代表“Fast Forward”,FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换组成.
ffmpeg:是一个命令行工具,用来对视频文件转换格式,也支持对电视卡实时编码libavformat:用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能,包含demuxers和muxer库;libavcodec:用于各种类型声音/图像编解码;libavfilter:滤镜库libavutil:包含一些公共的工具函数;libswscale:用于视频场景比例缩放、色彩映射转换;libpostproc:用于后期效果处理;ffsever:是一个HTTP多媒体实时广播流服务器,支持时光平移;ffplay:是一个简单的播放器,使用ffmpeg 库解析和解码,通过SDL显示;(一般编译完没有带ffplay,新版本版本依赖于sd-2.0,需要安装sdl-2.0才能生成ffplay)术语
容器(Container): 容器就是一种文件格式,比如flv,mkv等。包含下面5种流以及文件头信息。
流(Stream): 是一种视频数据信息的传输方式,5种流:音频(a)、附件(t)、数据(d)、字幕(s)和视频(v)。
帧(Frame): 帧代表一幅静止的图像,分为I帧,P帧,B帧。
编解码器(Codec): 是对视频进行压缩或者解压缩,CODEC =COde (编码) +DECode(解码)
复用/解复用(mux/demux): 把不同的流按照某种容器的规则放入容器,这种行为叫做复用(mux)把不同的流从某种容器中解析出来,这种行为叫做解复用(demux);
播放原理
封装格式作用:视频码流和音频码流按照一定的格式储存在一个文件汇总
视频编码数据作用:将视频像素数据(RGB,YUV等)压缩成为视频码流,从而降低视频的数据量
音频编码数据作用:将音频采样数据(PCM等)压缩成为音频码流,从而降低音频的数据量
视频像素数据作用:保存了屏幕上每一个像素点的像素值格式:常见的像素数据格式有RGB24, RGB32, YUV420P,YUV422P,YUV444P等。
压缩编码中一般使用的是YUV格式的像素数据,最为常见的格式为YUV420P。特点:视频像素数据体积很大
音频采样数据作用:保存了音频中每个采样点的值。特点:音频采样数据体积很大
码流 kb/s
码流(DataRate)是指视频图像经过编码压缩后在单位时间内的数据流量,也叫码率,一般我们用的单位是kb/s或者Mb/s。是视频编码中画面质量控制中最重要的部分。同样分辨率下,压缩比越小,视频图像的码率就越大,画面质量就越高,文件体积也越大
其计算公式是文件体积=时间X码率/8。
采样率 Hz
采样率(也称为采样速度或者采样频率)定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。采样率是指将模拟信号转换成数字信号时的采样频率,也就是单位时间内采样多少点。一个采样点数据有多少个比特
比特率 bps
比特率是指每秒传送的比特(bit)数。单位为bps(BitPerSecond),比特率越高,传送的数据越大。比特率表示经过编码(压缩)后的音、视频数据每秒钟需要用多少个比特来表示,而比特就是二进制里面最小的单位,要么是0,要么是1。比特率与音、视频压缩的关系,简单的说就是比特率越高,音、视频的质量就越好,但编码后的文件就越大;如果比特率越少则情况刚好相反。比特率是指将数字声音、视频由模拟格式转化成数字格式的采样率,采样率越高,还原后的音质、画质就越好。
比特率是决定整体音频或视频质量的参数。 它规定了每时间单位处理的位数,在FFmpeg中,位速率以每秒位数表示。比特率决定了存储1秒编码流的位数
比特率 =采样率 x 采用位数 x声道数.
VBR(Variable Bitrate)动态比特率 也就是没有固定的比特率,压缩软件在压缩时根据音频数据即时确定使用什么比特率,这是以质量为前提兼顾文件大小的方式,推荐编码模式;
ABR(AverageBitrate)平均比特率是VBR的一种插值参数。LAME针对CBR不佳的文件体积比和VBR生成文件大小不定的特点独创了这种编码模式。ABR在指定的文件大小内,以每50帧(30帧约1秒)为一段,低频和不敏感频率使用相对低的流量,高频和大动态表现时使用高流量,可以做为VBR和CBR的一种折衷选择。
CBR(Constant Bitrate),常数比特率 指文件从头到尾都是一种位速率。相对于VBR和ABR来讲,它压缩出来的文件体积很大,而且音质相对于VBR和ABR不会有明显的提高。
帧速率
帧速率是编码成视频文件的每秒帧数(FPS或fps),人眼需要至少约15 fps来观看连续运动。 帧率也称为帧频,其单位是赫兹(Hz),LCD显示器通常具有60 Hz的频率。有两种帧速率 - 隔行(在FPS编号后表示为i)和逐行(在FPS编号后表示为p)。越高的帧速率可以得到更流畅、更逼真的动画。每秒钟帧数(FPS)越多,所显示的动作就会越流畅。
I、P、B 帧
在视频编码序列中,主要有三种编码帧:I帧、P帧、B帧,如下图所示。
● I帧即Intra-coded picture(帧内编码图像帧),不参考其他图像帧,只利用本帧的信息进行编码 ● P帧即Predictive-codedPicture(预测编码图像帧),利用之前的I帧或P帧,采用运动预测的方式进行帧间预测编码 ● B帧即Bidirectionallypredicted picture(双向预测编码图像帧),提供最高的压缩比,它既需要之前的图像帧(I帧或P帧),也需要后来的图像帧(P帧),采用运动预测的方式进行帧间双向预测编码
在视频编码序列中,GOP即Group ofpicture(图像组),指两个I帧之间的距离,Reference(参考周期)指两个P帧之间的距离(如下图3.1)。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧(如下图所示)。 I 帧、P 帧、B 帧的区别在于:
I 帧(Intracoded frames):I 帧图像采用帧内编码方式,即只利用了单帧图像内的空间相关性,而没有利用时间相关性。I帧使用帧内压缩,不使用运动补偿,由于 I 帧不依赖其它帧,所以是随机存取的入点,同时是解码的基准帧。I帧主要用于接收机的初始化和信道的获取,以及节目的切换和插入,I 帧图像的压缩倍数相对较低。I帧图像是周期性出现在图像序列中的,出现频率可由编码器选择。
P 帧(Predictedframes):P 帧和 B 帧图像采用帧间编码方式,即同时利用了空间和时间上的相关性。P 帧图像只采用前向时间预测,可以提高压缩效率和图像质量。P 帧图像中可以包含帧内编码的部分,即 P帧中的每一个宏块可以是前向预测,也可以是帧内编码。
B 帧(Bi-directionalpredicted frames):B 帧图像采用双向时间预测,可以大大提高压缩倍数。值得注意的是,由于 B 帧图像采用了未来帧作为参考,因此 MPEG-2 编码码流中图像帧的传输顺序和显示顺序是不同的。
也就是说,一个 I 帧可以不依赖其他帧就解码出一幅完整的图像,而 P 帧、B 帧不行。P 帧需要依赖视频流中排在它前面的帧才能解码出图像。B帧则需要依赖视频流中排在它前面或后面的帧才能解码出图像。
三种帧的说明
1、I帧
I帧:帧内编码帧 ,I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)
I帧特点:
它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;解码时仅用I帧的数据就可重构完整图像;I帧描述了图像背景和运动主体的详情;I帧不需要参考其他画面而生成;I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;I帧不需要考虑运动矢量;I帧所占数据的信息量比较大。2、P帧 P帧:前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)
P帧的预测与重构:P帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一起传送。在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,从而可得到完整的P帧。
P帧特点:
P帧是I帧后面相隔1~2帧的编码帧;P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;由于P帧是参考帧,它可能造成解码错误的扩散;由于是差值传送,P帧的压缩比较高。3、B帧
B帧:双向预测内插编码帧。B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况,但我这样说简单些),换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。
B帧的预测与重构
B帧以前面的I或P帧和后面的P帧为参考帧,“找出”B帧“某点”的预测值和两个运动矢量,并取预测差值和运动矢量传送。接收端根据运动矢量在两个参考帧中“找出(算出)”预测值并与差值求和,得到B帧“某点”样值,从而可得到完整的B帧。
B帧特点 1)B帧是由前面的I或P帧和后面的P帧来进行预测的; 2)B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量; 3)B帧是双向预测编码帧; 4)B帧压缩比最高,因为它只反映丙参考帧间运动主体的变化情况,预测比较准确; 5)B帧不是参考帧,不会造成解码错误的扩散。
GOP
GOP即Group ofpicture(图像组),指两个I帧之间的距离,Reference(参考周期)指两个P帧之间的距离。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧。所以在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference越大,B帧的数量越多,同理也更容易获得较好的图像质量。需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。同时,由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使编码效率降低。另外,过长的GOP还会影响Seek操作的响应速度,由于P、B帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,解码某一个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,seek响应的时间也越长。
“在H264的概念中有一个帧称为IDR帧”
“那么IDR帧与I帧的区别是什么呢?首先来看一下IDR的英文全称instantaneous decoding refreshpicture,因为H264采用了多帧预测,所以I帧之后的P帧有可能会参考I帧之前的帧,这就使得在随机访问的时候不能以找到I帧作为参考条件,因为即使找到I帧,I帧之后的帧还是有可能解析不出来,而IDR帧就是一种特殊的I帧,即这一帧之后的所有参考帧只会参考到这个IDR帧,而不会再参考前面的帧。在解码器中,一旦收到一个IDR帧,就会立即清理参考帧缓冲区,并将IDR帧作为被参考的帧。”
DTS、PTS 的概念
DTS、PTS 的概念如下所述:
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
需要注意的是:虽然 DTS、PTS 是用于指导播放端的行为,但它们是在编码的时候由编码器生成的。
当视频流中没有 B 帧时,通常 DTS 和 PTS 的顺序是一致的。但如果有 B 帧时,就回到了我们前面说的问题:解码顺序和播放顺序不一致了。
比如一个视频中,帧的显示顺序是:I B B P,现在我们需要在解码 B 帧时知道 P 帧中信息,因此这几帧在视频流中的顺序可能是:I P B B,这时候就体现出每帧都有 DTS 和 PTS 的作用了。DTS 告诉我们该按什么顺序解码这几帧图像,PTS告诉我们该按什么顺序显示这几帧图像。顺序大概如下:
PTS: 1 4 2 3 DTS: 1 2 3 4 Stream: I P B B
音视频的同步
上面说了视频帧、DTS、PTS 相关的概念。我们都知道在一个媒体流中,除了视频以外,通常还包括音频。音频的播放,也有 DTS、PTS的概念,但是音频没有类似视频中 B 帧,不需要双向预测,所以音频帧的 DTS、PTS 顺序是一致的。
音频视频混合在一起播放,就呈现了我们常常看到的广义的视频。在音视频一起播放的时候,我们通常需要面临一个问题:怎么去同步它们,以免出现画不对声的情况。
要实现音视频同步,通常需要选择一个参考时钟,参考时钟上的时间是线性递增的,编码音视频流时依据参考时钟上的时间给每帧数据打上时间戳。在播放时,读取数据帧上的时间戳,同时参考当前参考时钟上的时间来安排播放。这里的说的时间戳就是我们前面说的PTS。实践中,我们可以选择:同步视频到音频、同步音频到视频、同步音频和视频到外部时钟。
PAR —— Pixel Aspect Ratio 像素横纵比。表示每个像素的宽度与长度的比值。可以认为每个像素不是正方形的。 DAR —— Display Aspect Ratio 显示横纵比。最终显示的图像在长度单位上的横纵比。 SAR —— Sample Aspect Ratio 采样横纵比。表示横向的像素点数和纵向的像素点数的比值。
视频转换流程解析
代码转换过程中,ffmpeg在libavformat库中调用demuxers来读取输入,并从数据包中获取编码数据。如果有更多的输入,ffmpeg可以通过跟踪任何活动输入流的最低时间戳来保持它们的同步。然后解码器从编码的数据包中生成未压缩的帧,在可选的过滤后,帧被发送到编码器。编码器产生新的编码包,它被发送到muxer并写入到输出。 流拷贝
流拷贝是对指定数据流仅仅进行复制,这种情况下不会进行编码解码,仅仅是分离和混合数据包,所以特别快,也不会造成质量损失,这也导致这种模式不适用复杂的滤镜处理等,这种模式常用于文件包格式或者修改部分元数据信息。
ffmpeg滤镜(Filters, filterchains,filtergraphs)
滤镜(Filters):在编码前,对原音视频使用libavfilter库中的滤镜进行处理,FFmpeg内置了许多多媒体过滤器,可以通过多种方式组合它们。
分为两种滤镜:简单滤镜和复合滤镜
简单滤镜:
简单滤镜就是只有1个输入和输出的滤镜,使用-vf和-af分别对应视频和音频
复合滤镜:
复合滤镜就是那些不能简单的描述为一个线性处理过程应用到一个流的情况,例如包含多个输入输出。
复合滤镜使用-filter_complex进行设置
滤镜的使用一般是 滤镜名=由于冒号(:)隔开各个参数
滤镜链图(filtergraphs)是连接滤镜的有向图,它可以包含循环动作,也可以在多个滤镜间形成链路,每个链接都有一个连接到滤镜的输入和一个连接到滤镜的输出
一个滤镜链(filterchains)包含序列链接起来的滤镜,这个序列由“,"分隔各个滤镜
一个滤镜链图(filtergraphs)包含序列滤镜链,这个序列由“;”分隔各个滤镜链
同一路的滤镜间用逗号(,)进行分割,不同路的滤镜间用分号进行分割(;)