一.硬解码和软解码
http://www.open-open.com/lib/view/open1333418857983.html //播放器生命周期
在手机评测视频播放能力的时候经常会提到“硬解码”和“软解码”,但是很多人不太明白是什么意思,其实问题很简单。大家都知道PC都有CPU和GPU(显卡),在手机上也是有CPU和GPU。
手机和电脑的区别主要在于电脑上的显卡是作为独立出来的一个重要部件而存在的,在手机上GPU和CPU的关系很紧密,在以前的智能机很多GPU的事都是由CPU来完成的,手机发展到如今已经有了独立的GPU。但是还是和CPU封装在一起的,由芯片开发商一起开发的。如今的高通骁龙800处理器采用的是Adreno 330 GPU,在视频和渲染方面有了极大的提升,已经难以置信的支持了4K视频的拍摄和播放。
硬解码:由显卡核心GPU来对高清视频进行解码工作,CPU占用率很低,画质效果比软解码略差一点,需要对播放器进行设置。
优点:播放流畅、低功耗
缺点:受视频格式限制、功耗大、画质没有软解码好
软解码:由CPU负责解码进行播放
优点:不受视频格式限制、画质略好于硬解
缺点:会占用过高的资源、对于高清视频可能没有硬解码流畅(主要看CPU的能力)
就好比两个人一样,一个人有一个袋子,一个人只能用手,在拿东西的时候有袋子的肯定会省力一些。但是在个别情况下袋子不方便装的话可能需要手直接拿着。
谁更好?
软解码是在显卡本身不支持或者部分不支持硬件解码的前提下,将解压高清编码的任务交给CPU,这是基于硬件配置本身达不到硬解压要求的前提下,属于一个折中的无奈之举。那这么说是不是软解压就一无是处了呢?不,这要是情况而定。对于一个不看、或者不经常看高清的用户而言,如果专门为很少用到的功能进行过多支出,那无疑是一种浪费;而在保证正常应用的前提下,还能在偶尔看一下高清的时候自己的电脑配置不至于播放不了,或者播放不流畅,那么这时候一颗性能不算太次的CPU就大有用武之地了,好在现在早已是双核,甚至多核CPU的时代,这个已经不是问题。总结软解码的好处,就是成本低廉,几乎不用二次投入,就可以享受高清带来的乐趣和震撼。
所以硬解码和软解码是相互相成的,没有电脑或者手机只有硬解码,也没有电脑或者手机只有软解码。
二.常用的视频编解码标准
很多视频编解码器可以很容易的在个人计算机和消费电子产品上实现,这使得在这些设备上有可能同时实现多种视频编解码器,这避免了由于兼容性的原因使得某种占优势的编解码器影响其它编解码器的发展和推广。最后我们可以说,并没有那种编解码器可以替代其它所有的编解码器。下面是一些常用的视频编解码器,按照它们成为国际标准的时间排序:
H.261
H.261主要在老的视频会议和视频电话产品中使用。H.261是由ITU-T开发的,第一个使用的数字视频压缩标准。实质上说,之后的所有的标准视频编解码器都是基于它设计的。它使用了常见的YCbCr颜色空间,4:2:0的色度抽样格式,8位的抽样精度,16x16的宏块,分块的运动补偿,按8x8分块进行的离散余弦变换,量化,对量化系数的Zig-zag扫描,run-level符号影射以及霍夫曼编码。H.261只支持逐行扫描的视频输入。
MPEG-1第二部分
MPEG-1第二部分主要使用在VCD上,有些在线视频也使用这种格式。该编解码器的质量大致上和原有的VHS录像带相当,但是值得注意的是VCD属于数字视频技术,它不会像VHS录像带一样随着播放的次数和时间而逐渐损失质量。如果输入视频源的质量足够好,编码的码率足够高,VCD可以给出从各方面看都比VHS要高的质量。但是为了达到这样的目标,通常VCD需要比VHS标准要高的码率。实际上,如果考虑到让所有的VCD播放机都可以播放,高于1150kbps的视频码率或者高于352x288的视频分辨率都不能使用。大体来说,这个限制通常仅仅对一些单体的VCD播放机(包括一些DVD播放机)有效。MPEG-1第三部分还包括了目前常见的*.mp3音频编解码器。如果考虑通用性的话,MPEG-1的视频/音频编解码器可以说是通用性最高的编解码器,几乎世界上所有的计算机都可以播放MPEG-1格式的文件。几乎所有的DVD机也支持VCD的播放。从技术上来讲,比起H.261标准,MPEG-1增加了对半像素运动补偿和双向运动预测帧。和H.261一样,MPEG-1只支持逐行扫描的视频输入。
MPEG-2第二部分
MPEG-2第二部分等同于H.262,使用在DVD、SVCD和大多数数字视频广播系统和有线分布系统(cable distribution systems)中。当使用在标准DVD上时,它支持很高的图像质量和宽屏;当使用在SVCD时,它的质量不如DVD但是比VCD高出许多。但是不幸的是,SVCD最多能在一张CD光盘上容纳40分钟的内容,而VCD可以容纳一个小时,也就是说SVCD具有比VCD更高的平均码率。MPEG-2也将被使用在新一代DVD标准HD-DVD 和 Blu-ray(蓝光光盘)上。从技术上来讲,比起MPEG-1,MPEG-2最大的改进在于增加了对隔行扫描视频的支持。MPEG-2可以说是一个相当老的视频编码标准,但是它已经具有很大的普及度和市场接受度。
H.263
H.263主要用在视频会议、视频电话和网络视频上。在对逐行扫描的视频源进行压缩的方面,H.263比它之前的视频编码标准在性能上有了较大的提升。尤其是在低码率端,它可以在保证一定质量的前提下大大的节约码率。
MPEG-4第二部分
MPEG-4第二部分标准可以使用在网络传输、广播和媒体存储上。比起MPEG-2和第一版的H.263,它的压缩性能有所提高。和之前的视频编码标准的主要不同点在于,“物件導向”(Object-oriented)的编码方法和一些其它并非用于提高通常视频编码压缩率的技术。当然它也引入了一些提高压缩能力的技术,包括一些H.263的技术和1/4像素的运动补偿。和MPEG-2一样,它同时支持逐行扫描和隔行扫描。
MPEG-4第十部分 ( H.264 ) : 性能最优的视频编码标准
MPEG-4第十部分技术上和ITU-T H.264是相同的标准,有时候也被叫做“AVC”)。 这个刚刚制定完成的标准是ITU-T VCEG和ISO/IEC MPEG合作完成的性能最优的视频编码标准,并且在已经得到了越来越多的应用。该标准引入了一系列新的能够大大提高压缩性能的技术,并能够同时在高码率端和低码率端大大超越以前的诸标准。已经使用和将要使用H.264技术的产品包括例如索尼公司的PSP,Nero公司的Nero Digital 产品套装,苹果公司的Mac OS X v10.4,以及新一代DVD标准HD-DVD和蓝光光盘(Blu-ray)。
AVS
AVS是中国制定的音视频压缩编码标准,故准确来说,其不仅仅包括视频编码标准。它最主要的目的是通过采用与H.264不同的专利授权方式,来避免付出大笔的专利授权费用。在技术上,AVS的视频编码部分采用的技术与H.264非常相似,但采取了一些简化措施。这样做,其一可以回避一些非必要专利,另外据称也可以在几乎不影响编码压缩效率的基础上,提高编解码速度。
DivX,XviD和3ivx
DivX,XviD和3ivx视频编解码器基本上使用的都是MPEG-4第二部分的技术,以后缀*.avi, *.mp4, *.ogm 或者 *.mkv 结尾的文件有一部分是使用这些视频编解码器的。
WMV
WMV(Windows Media Video)是微软公司的视频编解码器家族,包括WMV 7、WMV 8、WMV 9、WPV 10。这一族的编解码器可以应用在从拨号上网的窄带视频到高清晰度电视(HDTV)的宽带视频。使用Windows Media Video用户还可以将视频文件刻录到CD、DVD或者其它一些设备上。它也适用于用作媒体服务器。WMV 可以被看作是MPEG-4的一个增强版本。最新的WMV的版本是正在SMPTE制定中的VC-1标准。WMV-9(VC-1,开发代号为“Corona”)刚推出的时候称为VC-9,之后才被电影电视工程师协会(SMPTE)改称为VC-1(VC指Video Codec)。技术上,VC-1也与H.264有诸多相似之处。
RealVideo
RealVideo是由RealNetworks公司开发的视频编解码器。近几年曾经有段时间的低迷,之后又获得市场的青睐。最近尤其在BT电影界格外受宠。
Sorenson 3
Sorenson 3是由苹果公司的软件QuickTime使用的一种编解码器。很多因特网上的QuickTime格式的视频都是这种编解码器压缩的。
Cinepak
Cinepak同样是由苹果公司的软件QuickTime使用的一种很老的编解码器,好处是即使很老的计算机(如486)也都支援并且能顺利播放。
Indeo Video
Indeo Video Indeo Video 是由 Intel 所研發的编解码器。
三.Android MediaPlayer 常用方法介绍
方法:create(Context context, Uri uri)
解释:静态方法,通过Uri创建一个多媒体播放器。
方法:create(Context context, int resid)
解释:静态方法,通过资源ID创建一个多媒体播放器
方法:create(Context context, Uri uri, SurfaceHolder holder)
解释:静态方法,通过Uri和指定 SurfaceHolder 【抽象类】 创建一个多媒体播放器
方法: getCurrentPosition()
解释:返回 Int, 得到当前播放位置
方法: getDuration()
解释:返回 Int,得到文件的时间
方法:getVideoHeight()
解释:返回 Int ,得到视频的高度
方法:getVideoWidth()
解释:返回 Int,得到视频的宽度
方法:isLooping()
解释:返回 boolean ,是否循环播放
方法:isPlaying()
解释:返回 boolean,是否正在播放
方法:pause()
解释:无返回值 ,暂停
方法:prepare()
解释:无返回值,准备同步
方法:prepareAsync()
解释:无返回值,准备异步
方法:release()
解释:无返回值,释放 MediaPlayer 对象
方法:reset()
解释:无返回值,重置 MediaPlayer 对象
方法:seekTo(int msec)
解释:无返回值,指定播放的位置(以毫秒为单位的时间)
方法:setAudioStreamType(int streamtype)
解释:无返回值,指定流媒体的类型
方法:setDataSource(String path)
解释:无返回值,设置多媒体数据来源【根据 路径】
方法:setDataSource(FileDescriptor fd, long offset, long length)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(FileDescriptor fd)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(Context context, Uri uri)
解释:无返回值,设置多媒体数据来源【根据 Uri】
方法:setDisplay(SurfaceHolder sh)
解释:无返回值,设置用 SurfaceHolder 来显示多媒体
方法:setLooping(boolean looping)
解释:无返回值,设置是否循环播放
事件:setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)
解释:监听事件,网络流媒体的缓冲监听
事件:setOnCompletionListener(MediaPlayer.OnCompletionListener listener)
解释:监听事件,网络流媒体播放结束监听
事件:setOnErrorListener(MediaPlayer.OnErrorListener listener)
解释:监听事件,设置错误信息监听
事件:setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)
解释:监听事件,视频尺寸监听
方法:setScreenOnWhilePlaying(boolean screenOn)
解释:无返回值,设置是否使用 SurfaceHolder 显示
方法:setVolume(float leftVolume, float rightVolume)
解释:无返回值,设置音量
方法:start()
解释:无返回值,开始播放
方法:stop()
解释:无返回值,停止播放
这张状态转换图清晰的描述了MediaPlayer的各个状态,也列举了主要的方法的调用时序,每种方法只能在一些特定的状态下使用,如果使用时MediaPlayer的状态不正确则会引发IllegalStateException异常
Idle 状态:当使用new()方法创建一个MediaPlayer对象或者调用了其reset()方法时,该MediaPlayer对象处于idle状态。这两种方法的一个重要差别就是:如果在这个状态下调用了getDuration()等方法(相当于调用时机不正确),通过reset()方法进入idle状态的话会触发OnErrorListener.onError(),并且MediaPlayer会进入Error状态;如果是新创建的MediaPlayer对象,则并不会触发onError(),也不会进入Error状态。
End 状态:通过release()方法可以进入End状态,只要MediaPlayer对象不再被使用,就应当尽快将其通过release()方法释放掉,以释放相关的软硬件组件资源,这其中有些资源是只有一份的(相当于临界资源)。如果MediaPlayer对象进入了End状态,则不会在进入任何其他状态了。
Initialized 状态:这个状态比较简单,MediaPlayer调用setDataSource()方法就进入Initialized状态,表示此时要播放的文件已经设置好了。
Prepared 状态:初始化完成之后还需要通过调用prepare()或prepareAsync()方法,这两个方法一个是同步的一个是异步的,只有进入Prepared状态,才表明MediaPlayer到目前为止都没有错误,可以进行文件播放。
Preparing 状态:这个状态比较好理解,主要是和prepareAsync()配合,如果异步准备完成,会触发OnPreparedListener.onPrepared(),进而进入Prepared状态。
Started 状态:显然,MediaPlayer一旦准备好,就可以调用start()方法,这样MediaPlayer就处于
Started状态,这表明MediaPlayer正在播放文件过程中。可以使用isPlaying()测试MediaPlayer是否处于了Started状态。如果播放完毕,而又设置了循环播放,则MediaPlayer仍然会处于Started状态,类似的,如果在该状态下MediaPlayer调用了seekTo()或者start()方法均可以让MediaPlayer停留在Started状态。
Paused 状态:Started状态下MediaPlayer调用pause()方法可以暂停MediaPlayer,从而进入Paused状态,MediaPlayer暂停后再次调用start()则可以继续MediaPlayer的播放,转到Started状态,暂停状态时可以调用seekTo()方法,这是不会改变状态的。
Stop 状态:Started或者Paused状态下均可调用stop()停止MediaPlayer,而处于Stop状态的MediaPlayer要想重新播放,需要通过prepareAsync()和prepare()回到先前的Prepared状态重新开始才可以。
PlaybackCompleted状态:文件正常播放完毕,而又没有设置循环播放的话就进入该状态,并会触发OnCompletionListener的onCompletion()方法。此时可以调用start()方法重新从头播放文件,也可以stop()停止MediaPlayer,或者也可以seekTo()来重新定位播放位置。
Error状态:如果由于某种原因MediaPlayer出现了错误,会触发OnErrorListener.onError()事件,此时MediaPlayer即进入Error状态,及时捕捉并妥善处理这些错误是很重要的,可以帮助我们及时释放相关的软硬件资源,也可以改善用户体验。通过setOnErrorListener(android.media.MediaPlayer.OnErrorListener)可以设置该监听器。如果MediaPlayer进入了Error状态,可以通过调用reset()来恢复,使得MediaPlayer重新返回到Idle状态。