https://blog.csdn.net/yuyin86/article/details/21164777
一直想写点关于多媒体学习的东西,又感觉自己掌握的东西太浅,太杂,写不出东西。
网络上的资料其实已经很全面了,在学习的过程感觉虽然不少精品,但是却不够精品,而且有些东西也不太适合初学者。
所以决定写点东西,当做自己的学习笔记。把网络上的资料整理一下,也顺便看看自己的理解是否有误,只针对初习者的笔记。
先写提纲
1,视频容器与编解码器的区别
2,视频播放的基本原理
3,颜色空间的概念及转换
4,视频压缩的基本原理,一些常见压缩算法的概念
5,常见容器的解析avi/mp4/mkv/ts/flv
6,render的一些概念和可用库(sdl/directfb/fb/....)
7,一些应该学习的开源框架与库用途和差别(vlc/ffmepg/mplayer/gstreamer/openmax/mpc/ffdshow/directshow...)
8,开源库的编译(vlc/ffmepg/x264/xvid/...)
9,图片解码库的使用(libjpeg/libpng/...)
目前想到的就是这些。以后如果想到新的,再补充。
其实学习这些东西,更多的是开源库的使用,之前学习都比较粗糙,找到相关的代码,然后编译,看结果。就ok了。
对于工作,实际应该是够用了。学习可以更加深入一些。
1.视频容器与编解码器的区别
这基本是一个老生常谈的东西了,但是我仍然是看了很多资料,加上一点点理解才完全明白了其中的差别所在。
这就像上学时的考试大纲,这种东西要求是识记类型的,没有技术门槛,但是只有你把东西都记住之后,才完全知道书上再说什么。
一,容器的概念
什么叫容器,从字面的含义来说,能放东西的东西,就叫容器。
打个比方就像桶,可以装水,可以装油,可以装硫酸,等等。
一部电影,不可能只有图像,还有声音,可能还会有字幕,还会有文件作者,加密信息等等。但是我们又不能把这些东西单独存放,这样太麻烦了。所以发明这样一个“桶”,把图像,声音,字幕等等的东西,一股脑放到一个地方,这个“桶”就叫视频的容器。ps:又叫封装格式。
一般来说,文件的拓展名就是容器名。比如.avi,.mp4,.flv,.mkv等,就是不同的容器。
二,编解码器的概念
通常来说,图像信息和声音都很大,如果不压缩存放,空间浪费太严重,而且也不利传输。
为了解决这个问题,人们发明了编码器,说白了,就是用来压缩这些信息的。
不同的编码方式,就是不同的编码器。例如mpeg-1,mpeg-2,mpeg-4,h.264,以及还是草按的h.265
这个东西之所以有很多种类,多半的原因就是各个大厂商为了保护自己的利益,定义一些标准,然后推广,就可以坐吃专利,一本万利,何乐而不为?
三,常见的容器类型介绍
不准备写太详细,大多数东西只是做一个提示,可以参考维基百科的介绍,写得太多反而会使人迷糊,只写自己知道的,详细的可以参考资料,只是做一个提纲挈领的东西。
avi
(audio video interleave),是微软在1992年推出的一种多媒体文件格式, 比较老了,对目前的基于网络流播放的方式力不从心。
mp4
标准规范是ISO/IEC 14496-14,由mpeg组织规定。youtube的视频很多是这种封装格式。
mkv
一种由开源组织规定的容器类型,链接是http://www.matroska.org/,现在的高清电影一般都采用这个格式。
ts
同样由mpeg组织规定,一般用于数字电视广播中,平时从网络下载来的电影很少用这种格式封装的。标准是13818-1
rmvb/rm
这是一个由商业公司(RealNetworks)自己定义的,网络比较流行,标准不公开,所以播放这种视频只能用专利播放器。
wmv
不多说了,微软定义的封装格式。
flv
视频网站类似优酷,土豆等,都用这个容器来存储视频,很好的保护原始地址,不容易被下载到,从而起到保护版权的作用。由adobe公司开发。
其他的比如3gp,asf,webm,不一一介绍了。
如果想了解更多。
http://zh.wikipedia.org/wiki/MPEG-1,这个链接下面有个表格,里面的东西非常全面。
四,常见编码格式
mpeg-1
mpeg组织最早规定的视频编码格式,标准是iso-11117,主要是vcd在用。
mpeg-2
mpeg组织规定的压缩标准之二,主要用于DVD,数字电视广播(DVD),标准是iso-13818系列。
mpeg-4
mpeg组织规定的压缩标准之三,这里有不少东西要交待,这三个标准其实是随着计算机运算能力越来越强而逐渐产生的,所以压缩的视频质量越来越好,但是算法复杂度却越来越高, 不过计算机能力越来越强,这都不算大问题了。
有一个有意思的事就是,为什么没有mpeg-3呢?其实原本是有mpeg-3的,但是mpeg组织在写标准时发现,mpeg-2实在太优秀的,mpeg-3推出的目标,他都能做到,所以就这个项目砍掉了。所以mpeg系统的标准,从1,2,4,就直接到了7,就是一个权衡。mpeg组织内部有两派,一是按1,2,3,4,5这样来。另外一批人觉得,1,2,4,后面按道理怎么也是8啊。折中一下,就是mpeg-7了。
ps:mp3是指mpeg-1音频压缩的layer 3.
h264/avc/mpeg-4 part 10
大名鼎鼎的264。
由mpeg和itu-t联手组成了一个叫JVT(Joint Video Team)的组织制定的。
这个东西容易使人迷糊,因为他得名子太多了。又叫mpeg-4 part 10,又叫avc,又叫h264,而且实际上,基本就是一个东西的不同名子。
vc-1
微软定义的压缩标准,不过后来开放出来了,由电影及电视学会(SMPTE)组织标准化。
realvideo
私有标准,木办法,这个东西人家就是私有的,在国内喜欢盗版的地方,大家都不介意,所以市场比较大,其实在北美那边,这种东西,不太多。
这里要注意区别,rm/rmvb是容器类似,realvideo是压缩标准。如果说有共同点,那就是:都是由一家公司提供的。呵呵
avs
最后要说的是,国产标准,没太研究过,不知道到底如何,由国内的联合信源公司开发,提交成国家标准。貌似广电总局已经强制机顶盒一定要支持这种压缩格式,以强推这种标准。就像tds-cdma,wapi,还有移动数字电视的方式一样,行政压迫。呵呵。
不好说前景。
同样,更多信息可以参考我前面提供的链接,各种冷门的容器,编码器,维基都介绍,可真谓是知识宝库啊。
ok,终于写完了一篇了,却感觉挂一漏万。唉。想了很多,却总感觉写得极不全面。
先这样,以后如果有需要补充的,再修改。
2.播放器的基本原理
播放器解决了视频播放的问题。通常来说,解决问题最好的办好就是大而化小,小而化无。因为整个播放过程是一个复杂的过程,所以播放器也采用分而治之的办法。
简单来说,这个大问题可以分解为四个小问题。
1,数据接收;2,数据解析;3,数据解码;4,数据输出。
我会对mplayer和vlc这两个开源播放器的代码结构来说明这四个问题。
一,数据接收(access)
自然,我们不能无中生有,要处理数据,总要有数据来源才行。但是数据来源的渠道有很多种。
可能是硬盘文件,可能是dvd光盘,也可能是http/httplive数据包,也可能是rtp数据包(vod),或者ftp,广播电视的ts流等等。
所以第一步我们要处理的问题就是如何把不同的数据来源统一一个接口。这需要不同数据包解析器,也就是实现不同的协议来满足这个需求。
对于mplayer,相关的代码在strearm,
对于vlc,相关的代码在/modules/access
查看代码目录,里面文件名可以和我们前面说的一些数据来源一一对应。所以如果我们需要实现某种协议,大抵是可以从这里获取一些实现思路的。
二,数据解析(demux)
有了数据了,我们还要解析这些数据。
为了方便媒体文件的传输,我们要把音频,图像,同步信息等等一堆信息放到一起(就是上一篇说的容器),这个过程就是mux(multiplex)。
但是为了方便媒体文件的处理,我们又需要解复用demux(Demultiplexer)
container是为了解决的传输而诞生的,demux就是为了解析而诞生的。
不同的容器需要不同的解析器,就是不同的demux接口,为了方便编程,我们同样需要统一接口。我们来看看mplayer和vlc是如何做的。
mplayer把相关代码放在了libmpdemux里面。
vlc把相关代码放在/modules/demux里面。
这两个代码统一各种容器的解析方式(就是我们常见的avi,ts,mkv的解析)。
不过需要注意的是,这些代码很大一部分都是warp的ffmpeg/libavformat里面的代码。
三,解码(decode)
上面那个过程把音视频数据分离,我们得到的数据可能是mpeg-2/h.264压缩的视频,也可能是mp3/aac/ac-3等音频数据。
但是这些数据都是压缩过的,我们知道,屏幕是由一个一个的点结成的,这一个一个点又是由rgb来描述的,声卡是处理一个一个音频帧的。
这个过程我们要解决的问题就是把压缩过的数据还原出来。如何还原?没错,靠我们的解码器。
上一篇说了不同的解码标准,现实中的情况是,我们有了一个标准,但是我们可能根据这个标准来实现不同的解码器。就像我们有一张桌子的草图,但是我们做的桌子却有不同的颜色一个。标准有了,实现可以不同。
mplayer把这块代码放到libmpcodecs里
vlc把这块代码放到/modules/codec里。
不过要指出的是,这两块代码同样大部分是在warp ffmpeg/libavcodec。
ffmpeg真是做为神一样库而存在啊。
四,数据输出(render)
准备好了解码后的数据,就差最好一步输出了。
视频通常会解码为yuv数据,音频通常会解码为pcm数据。然后我们把这些数据分别放到屏幕和声卡里,播放过程就算完成了。
同样,数据输出也有很多渠道,也需要统一。
图像可能会输出到sdl,x11或者framebuffer,或者directfb,也可能是wingdi。
音频可能会出到oss,alsa,等等。
为了统一这些,vlc和mplayer同样warp了一些库,
mplayer放到libvo与libao
vlc放到/modules/audio_out与/modules/video_out。
7.一些应该学习的开源框架与库用途和差别
修bug修得头疼,看看自己的博客,坑挖了一堆,出来混,迟早是要还的,这里先补一个。
刚开始看多媒体这块时,总是发现有新框架,新平台,新名词弄得云山雾绕,为了避免重复google/wiki,我尝试做个总节吧。
之前写过codec与container的区别,这里就不多说了,更近应用层的东西。
这些东西大概有:vlc/ffmepg/mplayer/gstreamer/openmax/mpc/ffdshow/directshow...
这些软件,所涉及的层面和针对的应用场景,系统各不相同,按层次分别说一下。
一.播放器层次
这个层次上,是直接可以用的软件,已经做完了一切工作,如果我们需要用他们,是不需要写一行代码的,编译通过就可以拿来使用了,对于国内这些山寨公司来说,基本就是拿来就可以骗钱的档次了。
包括 vlc/mplayer/mpc,这里我只是简介一下,我就不费劲从维基和官网复制东西了,貌似网上其他文章也都是从这两个地方复制了点东西,毫无营养。
其中vlc与mplayer都是跨平台的,都是起源于linux界的大佬,后来逐渐发展到跨平台了。
vlc,插件机制的播放器,非常灵活,但是总觉得这货速度太慢,不过可移植平台比较多,ios/android/win8。。。。等等都有他的身影。
维基:http://zh.wikipedia.org/wiki/Vlc
mplayer,单线程,状态机机制的播放器,比较古老,代码有些凌乱。
官网:http://www.mplayerhq.hu/design7/news.html
维基: https://zh.wikipedia.org/wiki/MPlayer
mpc,是windows平台上的开源播放器,基于filter机制,像qq影音/射手播放器/百度影音/.......一系列windows上的播放器,都是脱胎于这个软件。
这套软件不太爽的一点是,只能在windows上运行,不能移植到其他平台,原因是他的使用了windows的directshow框架。
维基:http://zh.wikipedia.org/wiki/Media_Player_Classic
这里有篇文章,是讲述这些播放器的架构与应用的,非常经典。来自射手播放器的博客
二.框架层次
主要包括gsteamer/directshow/openmax
1.gstreamer是基于gnome的基础类库gobject所写的一套,开源多媒体框架。主要针对于linux,当然windows上也可以使用。
基本设计思路类似于directshow,区别只是
gstreamer基本部件是component(组件,demux/codec/access/等,都可以当成一个组件),对directshow来说,对应的概念是filter。
gstreamer各个组件的链接是pipe(管道,组件间传递数据,通信的机制),对directshow来说,对应的概念是pin。
对于这个框架一些比较典型应用就是meego/tizen手机平台上的媒体框架。
2.directshow是微软的推出的windows平台上的媒体框架
详细请戳:http://zh.wikipedia.org/wiki/DirectShow
应用比较广泛,像视频监控上位机,也就是pc端,基本上都得用这个了。另外windows平台的播放器,也基本遵行这个框架的一些概念空间。
xvid/x264两个组织,都把自己的算法库给封装了一套filter,方便兼容到这个平台上。
3.openmax
层次比较gstreamer与directshow低一些,主要用来封装解码库,基本的概念空间也是组件,不过通信方式叫什么tunels(隧道)
典型应用就是android手机平台了,呵呵。(好牛b啊)
对这些框架来说,都是为了方便开发应用准备的,与第一个层次区别就是,第一个层次就是一个单纯的应用,而这个层次,只是提供了一些机制,你可以用这些机制做任何你想要的东西
另外觉得这些开源的家伙太能捣腾了,基本类似的概念空间组合来组合去。让我们这些小菜学得学得头大。
三.库
首先要明确的是,库与框架的区别。
一般来说,框架只用写一些回调函数,应用就能跑起来,类似于mfc的button响应,android的oncreate之流。
库,只是一些功能,你需要自己调用起这些功能。
(一个简单的区别方法是,你用不用自己写main函数,呵呵,相当不科学,不过一般是准确的)
好吧,我觉得我也没说清,呵呵。
ffmpeg/ffshow基本属于这个概念层次的。
ffmpeg是上面介绍的东西的老祖宗,软件/框架,都是依赖这个库来实做的,ffmpeg提供了万能解复用,解码功能,他们只是调用这个库,进行自己需要的封装。
ffshow与ffmpeg的关系更暧昧。对directshow的filter概念空间来说,很多filter要自己写,所以有人就站出来做了这事,开源了,ffshow就是这样的东西。
一句话,用ffmpeg与了一堆filter.
人们设定了不同的视频文件格式来把视频和音频放在一个文件中,以方便同时回放,实际上都是一个容器里面 包裹着不同的轨道。容器是用来区分不同文件的数据类型的,而编码格式则由音视频的压缩算法决定,我们一般所说的文件格式或者是后缀名指的就是文件的容器。对于一种容器,可以包含不同编码格式的一种视频和音频。
文件格式(容器):
AVI (*.avi)
其含义是Audio Video Interactive,就是把视频和音频编码混合在一起储存,最常见的音频视频容器。支持的视频音频编码也是最多的。AVI也是最长寿的格式,已存在10余年了,虽然发布过改版(V2.0于1996年发布),但已显老态。
MPG (*.mpg/*.mpeg/*.dat)
MPEG编码采用的音频视频容器,具有流的特性。里面又分为 PS,TS 等,PS 主要用于 DVD 存储,TS 主要用于 HDTV。
VOB (*.vob)
DVD采用的音频视频容器格式(即视频MPEG-2,音频用AC3或者DTS),支持多视频多音轨多字幕章节等。
MP4
MPEG-4编码采用的音频视频容器,基于 QuickTime MOV 开发,具有许多先进特性。
3GP
3GPP视频采用的格式,主要用于流媒体传送。
ASF (*.wmv/*.asf)
Advanced Systems Format,Windows Media 采用的音频视频容器,能够用于流传送,还能包容脚本等。 ASF封装的WMV视频具有“数位版权保护”功能。
RM (*.rm/*.rmvb)
RealMedia 采用的音频视频容器,用于流传送。 由RealNetworks开发的一种容器,它通常只能容纳Real Video和Real Audio编码的媒体。可变比特率的RMVB格式,体积很小,非常受到网络下载者的欢迎。
MOV (*.mov)
QuickTime 的音频视频容器,恐怕也是现今最强大的容器,甚至支持虚拟现实技术,Java 等,它的变种 MP4,3GP都没有这么厉害。
MKV
Matroska, MKV 它能把 Windows Media Video,RealVideo,MPEG-4 等视频音频融为一个文件,而且支持多音轨,支持章节字幕等。 开放标准,开源。
WAV
一种音频容器(注意:只是音频),大家常说的 WAV 就是没有压缩的 PCM 编码,其实 WAV 里面还可以包括 MP3 等其他 ACM 压缩编码。
TS
MPEG-2 transport stream,用于数字广播等非可靠传输领域,也被蓝光采用。
目前常见的音视频编码有以下几类
MPEG系列:(由ISO[国际标准组织机构]下属的MPEG[运动图象专家组]开发 )
视频编码方面主要是Mpeg1(vcd用的就是它)、Mpeg2(DVD使用)、Mpeg4(现在的DVDRIP使用的都是它的变种,如:divx,xvid等)、Mpeg4 AVC(现在正热门);
音频编码方面主要是MPEG Audio Layer 1/2、MPEG Audio Layer 3(大名鼎鼎的mp3)、MPEG-2 AAC 、MPEG-4 AAC等等。 注意:DVD音频没有采用Mpeg的
H.26X系列:(由ITU[国际电传视讯联盟]主导,侧重网络传输,注意:只是视频编码)
包括H261、H262、H263、H263+、H263++、H264(就是MPEG4 AVC-合作的结晶)
微软windows media系列:(牛X公司,能自己定标准啊...)
视频编码有Mpeg-4 v1/v2/v3(基于MPEG4,DIVX3的来源,呵呵)、Windows Media Video 7/8/9/10
音频编码有Windows Media audeo v1/v2/7/8/9
Real Media系列:(注意,这里说的Real的编码,可不是rm、rmvb文件,呵呵)
视频编码有RealVideo G2(早期)、RealVideo 8/9/10
音频编码有RealAudio cook/sipro(早期)、RealAudio AAC/AACPlus等
QuickTime系列:(是一个平台,有很多编码器)
视频编码有Sorenson Video 3(用于QT5,成标准了)、Apple MPEG-4、Apple H.264
音频编码有QDesign Music 2、Apple MPEG-4 AAC (这个不错)
其它,如:Ogg、On2-vpx、flash vidio:不详述啦。
特殊说明的,是DVD这种媒介的音频编码,采用了相对独立的几种,就列2个常见的吧:AC3(杜比公司开发)、DTS