音视频编解码概念
音视频格式有很多种,我们所熟知的音频文件有wav、mp3等 ,视频格式有mp4、3gp、rmvb、avi、mov等等。这些格式并不是只是文件的后缀不同,而是文件中的内容有很大的不同,哪怕这个媒体文件播放起来我们看起来觉得它们是一模一样的。
另外,我们看到的电影或者视频片段,它往往是由两个或者两个以上的流组成的,比如声音流、视频流、字幕等。甚至声音也有左声道、右声道什么的。
那么这些东西是怎么串联的呢?编码、解码、混流、解复用、过滤器这些都是些啥?为啥要有这些步骤?
编解码
我们应该都熟悉RGBA的色彩,用红绿蓝再加上透明度可以组成我们人眼可见的各种色彩,但是实际上许多色彩的差异并不是那么明显,就算肉眼去很仔细的比对都不能分辨出来。而通常视频依照24帧每秒的频率存储图像、甚至以30帧每秒的频率存储图像,如果以rgba的格式存储,占用的存储空间是非常庞大的,而且不利于网络传输。而YUV格式,如果一帧RGBA的图像数据占用16份,那么RGB占用12份,而YUV420只占用6份。虽然RGB的图像变为YUV格式质量通常会有损失,但是这个损失通常是可以接受的。
虽然转换成YUV格式,可以节省一些存储空间,但是情况依旧不容乐观。人们又发现对于连续的视频而言,通常连续的帧之间,图像之间存在大量重复的数据,这样,就可以在存储的时候把重复的数据去掉,再需要展示的时候再恢复出来,这样就可以大大节省存储空间,网络传输的之后,也同样把大量重复的去掉,接收端播放的实话再恢复,以达到节省带宽,加快传输速度的目的。这个去除大量重复数据的过程我们可以理解为音视频的编码,把去除的数据恢复回来的过程,我们可以理解为音视频的解码,也就是Codec。
混流、解复用
混流也就是复用,或许更为标准的叫法应该是复用。混流是什么?上面说了,我们看到的视频通常有图像又有声音,这些声音和图像的数据通常是两条不同的流,把这两条流混合在一起的过程就是混流。那么反之,把混合在一起的音视频拆分成各自的音频流、视频流的过程就是解复用。编解码的目的很明确,那么混流和解复用的目的又是什么呢?拿网络传输来说,在线观看视频,总不能先把声音传过去再传图像,或者说先把所有的图像传过去再传声音,而是传一点图像就传一点声音,这就是混流了,也就时Mux,与之对应的就是解复用Demux.
过滤器
我总是觉得这个翻译,对于Filter来说并不好听,我更喜欢翻译它为滤镜,更确切的说,应该可以把它理解为处理器。它并不是真的就是用来过滤,像把浑浊的水过滤成清水那样。比如我们给视频图像加个水印,或者改变视频的声音,让声音变得尖锐或者低沉等等,这些就是滤镜的工作了。
音视频编解码方式
简单的来分,我们可以把音视频的编解码分为软编解码和硬编解码,这里的软就是指软件,硬就是指硬件。所谓的软编解码,就是依赖软件,利用CPU进行编解码。而硬编解码可以理解为使用非CPU进行编解码,更准确的是,依赖音视频编解码模块进行音视频编解码。至于使用时到底是使用硬编解码还是软编解码,还是要依赖需求,根据它们各自的特点进行选择。
通常来说,软编解码实现直接简单,参数调整方便,支持格式广泛,编码视频质量相对硬编码更为清晰。但是软编解码相对硬编解码性能略差,会给CPU带来较重负载。
以Android平台为例,Android硬编解码MediaCodec从Android4.1才开始支持,混流用的MediaMuxer到Android4.3才开始支持。在Android4.1以前,如果开发者想要做视频相关应用通常会选择FFMpeg之类的开源编解码框架进行软编解码。当然,FFMpeg也可以配置选择使用硬编码。一般来说,如果应用只需要支持Android 4.3及以上,只需要做录制视频、播放Mp4文件,硬编解码方案优于软编解码方案。但是如果应用需要支持4.1以前的系统,或者要求支持其他音视频格式,比如rmvb之类的,可能就不得不使用软编方案了。
FFMpeg
上面提到了FFMpeg,那么FFMpeg又是什么呢?从其官网上可以知道,FFMpeg是一个全球领先的多媒体开源框架,用于音视频的编解码、混流、解复用、过滤器、转码以及播放等。它支持多平台、多种音视频格式。而且它便于移植及二次开发,当前有很多软件都用到了FFMpeg。FFMpeg 既有可以直接使用的工具,也有可以供开发人员使用的库。
其工具有:
ffmpeg:一个用于多媒体格式转换的命令行工具
ffserver: 一个用于现场直播的多媒体流服务器
ffplay: 一个基于SDL和FFMpeg库的简单的媒体播放器
ffprobe:一个简单的多媒体分析工具
其开发库有:
libavutil: 包含简化编程功能的库,包括随机数生成器、数据结构、数学相关的程序、核心多媒体框架等等。
libavcodec:包含用于音视频编解码的编码器和解码器的库。
libavformat: 包含多媒体容器格式的解码器和多路复用器的库。
libavdevice: 包含输入输出设备的库,用于从许多常见的多媒体输入输出软件框架中获取和渲染,包括Video4Linux、Video4Linux2、VfW和ALSA。
libavfilter:一个包含媒体过滤器的库。
libswscale:一个执行高度优化的图像缩放和色彩空间/像素格式转换的库。
libswresample:一个执行高度优化的音频重采样、再分频和采样格式转换操作的库。
值得注意的是,FFMpeg并不是直接就可以用于各种视频的编解码工作,它只是一个框架。真正执行编解码工作的通常会用到其它编解码器。比如进行h264的编码,一般会选择FFMpeg配合x264进行使用。
---------------------
作者:湖广午王
来源:CSDN
原文:https://blog.csdn.net/junzia/article/details/78167605
版权声明:本文为博主原创文章,转载请附上博文链接!
reference:
https://blog.csdn.net/zhuweigangzwg/article/details/72481966
https://blog.csdn.net/zhuweigangzwg/article/details/72624857
This post is really interesting and great. I appreciate your work, just keep working like this.
ReplyDeleteFrom team Death Driving