【干货】关于软解(ffmpeg)和硬解(MediaCodec、MediaPlayer)以及底层(OpenMax)的那点事 |
您所在的位置:网站首页 › 分离视频和音频的区别在哪 › 【干货】关于软解(ffmpeg)和硬解(MediaCodec、MediaPlayer)以及底层(OpenMax)的那点事 |
现在各种视频软件上都有硬解软解这两个选择,但它们有什么区别呢?用哪个好呢?今天就跟随小编一起了解了解吧。 首先,了解下播放视频的基本流程: 解封装:就是将输入的封装格式的数据,分离成为音频流压缩编码数据和视频流压缩编码数据。如上图,将MP4和FLV格式解封装成视频数据H264、MPEG2和音频数据AAC、MP3格式。 解码:就是将视频/音频压缩编码数据,解码成为非压缩的视频/音频原始数据。如上图,将视频数据解码成YUV格式和音频数据解码成PCM格式。 视音频同步:就是根据解封装模块处理过程中获取到的参数信息,同步解码出来的视频和音频数据,并将视频音频数据送至系统的显卡和声卡播放出来。 所谓的软解硬解也就是在解码方式上的区别。下面我们说说软件硬解到底是什么,各有什么优缺点。 概述软件解码:即通过软件让CPU来对视频进行解码处理; 硬件解码:是将原来全部交由CPU来处理的视频数据的部分交由GPU来做。 优缺点硬解码效率非常高,这样不但能够减轻CPU的负担,还有着低功耗,发热少等特点。但是,由于硬解码起步比较晚,软件和驱动对他的支持度很低,往往会出现兼容性不好的问题。此外,硬解码的滤镜、字幕、画质方面都做的不够理想。 软解码需要对大量的视频信息进行运算,所以对CPU处理性能的要求非常高。巨大的运算量就会造成转换效率低,发热量高等问题。不过,软解码不需要过多的硬件支持,兼容性非常高。而且软解码拥有丰富的滤镜,字幕,画面处理优化等效果,只有你CPU够强悍,就能够实现更加出色的画面效果。 实现方式 软解码我们最最常见的视频软解码开源库就是FFmpeg。目前基于FFmpeg的开源播放器有B站的ijkplayer。 ijkplayer的开源地址 : https://github.com/bilibili/ijkplayer 从下图中可以看到,ijkplayer内部利用了ffmpeg解码库。 MediaCodec是安卓自带的视频编解码接口,由于使用的是硬解码,其效率相对FFMPEG高出来不少。而MediaCodec就很好拓展,我们可以根据流媒体的协议和设备硬件本身来自定义硬件解码,代表播放器就是Google的ExoPlayer。 ExoPlayer的开源地址 : https://github.com/google/ExoPlayer 基本流程: 1.创建和配置MediaCodec对象2.进行以下循环: 如果一个输入缓冲区准备好: 读取部分数据,复制到缓冲区 如果一个输出缓冲区准备好: 复制到缓冲区3.销毁MediaCodec对象接口如下: //根据视频编码创建解码器,这里是解码AVC编码的视频 MediaCodec mediaCodec =MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC); //创建视频格式信息 MediaFormat mediaFormat = MediaFormat.createVideoFormat(mimeType, width, height); //配置 mediaCodec.configure(mediaFormat, surfaceView.getHolder().getSurface(), null, 0); mediaCodec.start(); //停止解码,此时可以再次调用configure()方法 mediaCodec.stop(); //释放内存 mediaCodec.release(); //一下是循环解码接口 getInputBuffers:获取需要编码数据的输入流队列,返回的是一个ByteBuffer数组 queueInputBuffer:输入流入队列 dequeueInputBuffer:从输入流队列中取数据进行编码操作 getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个ByteBuffer数组 dequeueOutputBuffer:从输出队列中取出编码操作之后的数据 releaseOutputBuffer:处理完成,释放ByteBuffer数据用MediaCodec来实现的话,代码中主要通过上面的接口实现了媒体的播放过程。 实例可以参考: https://blog.csdn.net/u014653815/article/details/81084161
下图是MediaCodec调用createDecoderByType创建过程。 由上图可知,MediaCodec并不是真正的codec,真正codec是在openMax。 OpenMax是一个多媒体应用程序的框架标准,通过使媒体加速组件能够在开发、集成和编程环节中实现跨多操作系统和处理器硬件平台,提供全面的流媒体编解码器和应用程序便携化。Android的多媒体引擎OpenCore和StageFright都可以使用OpenMax作为插件,主要用于编解码(Codec)处理。
下面我来看看硬件厂商又是如何将自己硬解码代码加载到OpenMax框架中的? 在加载软解码库的代码中,可以看到有加载libstagefrighthw.so的代码,其是加载硬件解码plugin,每个平台都有自己libstagefrighthw.so的实现,以实现硬编解码。 MediaPlayerMediaPlayer是Android中的一个多媒体播放类,我们能通过它控制音视频流或本地音视频资源的播放过程。 以下是mediaPlayer接口: MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(url); mediaPlayer.prepare(); // might take long! (for buffering, etc) mediaPlayer.start();用MediaPlayer来实现的话,代码中主要通过5个步骤实现了媒体的播放功能。底层是如何实现的呢?下面我们就来看看。 不同的平台,硬件厂商也会实现自己的播放器。下图是MediaPlayer框架图: MediaPlayer通过Binder通信,最后调用到MediaPlayerService(由于篇幅问题,其过程这里就不展开讲了,可以参考小编的另一篇文章:【android系统】binder通信机制--记一次项目开发中用到的实例)。这里以Hiplayer为例,展开说明下厂商是如何在android 的 mediaplayer中注入自己播放器的。 从上图中可以看到,海思自己实现了一个HiMediaPlayerManage,然后实现了HiMediaPlayerFactory来创建HiMediaPlayerManage,HiMediaPlayerFactory是在MediaPlayerFactory中被注册进去的。这样就完成了厂商自己播放器注入到android框架中去。 MediaPlayerFactory也是使用了android设计模式中经典的工厂模式(如果有兴趣关注我们,回复"android设计模式")。 HiMediaPlayerFactory都实现了IFactory的接口,其中最重要的是ScoreFactory和CreatePlayer。其中ScoreFactory是根据播放类型参数来选择播放方式,CreatePlayer创建播放器。 HiMediaPlayerManage就是播放器的具体实现了,用来对接Android标准的MediaPlayer接口。 结束语在Android设备硬件支持的情况下优先使用Android设备的硬件解码,减少CPU的占用,更加省电。 在Android设备硬解不支持的情况下选择使用软解码,不管怎么样,视频至少能够播放,具有更好的适应性,但是增加了CPU的占用,更加费电,软硬结合才是王道,根据实际情况合理选择。 读完了这篇文章,是否对视频应用的软解硬解有了了解呢?赶紧去试下软解硬解功能吧,你更喜欢哪一个?欢迎大家扫描关注下方二维码和我分享交流吧!也欢迎大家下方留言评论,谢谢! - END - 干货满满!关注一下呗~ |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |