Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ExoPlayer漫谈之解码器复用

ExoPlayer漫谈之解码器复用

作者头像
马上就说
发布于 2021-01-21 14:59:31
发布于 2021-01-21 14:59:31
2.4K00
代码可运行
举报
文章被收录于专栏:码上就说码上就说
运行总次数:0
代码可运行

播放器性能的极致优化,就是要发现播放流程中一点一滴的耗时,然后分析这些耗时,并提出有效的方式解决这些耗时.了解过ExoPlayer播放器的同学们都知道ExoPlayer的解码是依赖Android系统提供的原生的解码模块,即MediaCodec来实行视频和音频解码的.

基于我们对MediaCodec使用方式和原理的熟悉,我们在使用MediaCodec的时候,首先要初始化,codec configure, codec start等流程,经过这些流程,codec分配内存来存储input buffer 和 output buffer

这块耗时对视频播放而言是无法避免的,不管是网络视频还是本地视频, codec 初始化--->configure ---> start ---> 上屏这部分的耗时都是无法避免的.

我们抓一下一个1080P的本地视频的systrace, 显示如下:

可以发现: video decoder和audio decoder创建/configure/start耗时了170ms, 直接占用了绝大部分耗时, 确实是耗时的大头.

目前ExoPlayer最新的版本是2.12.2, 而且保持着凉州一个小版本, 两个月一个大版本的更新节奏, google的工作效率还是比较高的. 针对codec 复用, 在2.10版本之前和2.10之后的版本, 使用方式和原理还是有所不同的.

ExoPlayer 2.10版本之前的codec复用

  • disabled状态, 在此状态下, 渲染器没有要播放的媒体流并且不保存解码器实例。
  • enabled状态, 在此状态下,渲染器可以播放媒体流,并在可能的情况下(例如,在读取流的格式之后)获取解码器实例。
  • started状态, 在此状态下,渲染器使用持有的解码器实例来播放视频

在2.10之前的版本中,只要视频渲染器保持在启用和启动状态,ExoPlayer就会尽可能重复使用视频解码器。特别是,这意味着从播放列表中的一种媒体过渡到另一种媒体时,视频解码器将被重用。在渲染列表过渡到禁用状态时,音频解码器不会在此类播放列表过渡中重用,视频或音频解码器也不会重用。重要的是,重新准备播放器以播放其他MediaSource会导致这种类型的状态转换,因此在这种情况下不会重复使用解码器。

一句话, 想复用codec实例,不能调用stop方法,不能将codec置为disabled状态

ExoPlayer 2.10版本之后的codec复用

2.10版本可以保证在播放新的视频源的时候复用播放器解码器资源.即使当前的渲染器持有的解码器实例已经被置为disabled状态

复用解码器实例可以减少多个视频源之间切换导致的丢帧的问题,更加可以节省时间.下面是复用解码器实例之后的systrace耗时:

解码器实例复用要求

解码器实例可以复用,肯定是有条件的,例如上一个视频播放的是VP9的视频,下一个视频播放的是H265的视频,那么解码器实例肯定不能复用. 具体是什么条件了,我们还是查看源码确认一下: MediaCodecRenderer.java有两个子类, MediaCodecVideoRenderer.java和MediaCodecAudioRenderer.java

MediaCodecVideoRenderer.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

  @Override
  protected DecoderReuseEvaluation canReuseCodec(
      MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) {
    DecoderReuseEvaluation evaluation = codecInfo.canReuseCodec(oldFormat, newFormat);

    @DecoderDiscardReasons int discardReasons = evaluation.discardReasons;
    if (newFormat.width > codecMaxValues.width || newFormat.height > codecMaxValues.height) {
      discardReasons |= DISCARD_REASON_VIDEO_MAX_RESOLUTION_EXCEEDED;
    }
    if (getMaxInputSize(codecInfo, newFormat) > codecMaxValues.inputSize) {
      discardReasons |= DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED;
    }

    return new DecoderReuseEvaluation(
        codecInfo.name,
        oldFormat,
        newFormat,
        discardReasons != 0 ? REUSE_RESULT_NO : evaluation.result,
        discardReasons);
  }
  • 首先当前的视频的最大分辨率不能超过codec支持的最大解码分辨率
  • 其次视频的输入size不能超过codec的input buffer size

MediaCodecAudioRenderer.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
  protected DecoderReuseEvaluation canReuseCodec(
      MediaCodecInfo codecInfo, Format oldFormat, Format newFormat) {
    DecoderReuseEvaluation evaluation = codecInfo.canReuseCodec(oldFormat, newFormat);

    @DecoderDiscardReasons int discardReasons = evaluation.discardReasons;
    if (getCodecMaxInputSize(codecInfo, newFormat) > codecMaxInputSize) {
      discardReasons |= DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED;
    }

    return new DecoderReuseEvaluation(
        codecInfo.name,
        oldFormat,
        newFormat,
        discardReasons != 0 ? REUSE_RESULT_NO : evaluation.result,
        discardReasons);
  }
  • 音频的输入size不能超过codec的input buffer size
我们如何复用解码器

  • 保证你播放的视频的格式是相同的,例如短视频信息流都是H264/AAC编码格式
  • 如果使用ExoPlayer播放器,最好使用同一个ExoPlayer实例,因为codec实例是封装在ExoPlayer实例中的
  • 当重新prepare新的视频时,在调用prepare之前不能调用stop函数,因为stop函数会释放解码器实例
  • 如果你要调用stop函数的情况下还想保持解码器实例不被释放,你需要调用setForegroundMode(...)函数,这个函数的使用方式是比较复杂的,不能误用

https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/ExoPlayer.html#setForegroundMode-boolean-

打开了ForegroundMode模式,意味着解码器资源在调用stop的时候都不会被释放,当然这是在复用解码器资源的场景下使用的,使用的时候要小心一些,在最终的时候还是要记得释放资源的,不然会出现问题.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 音视频平凡之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ExoPlayer 漫谈之解码器复用
播放器性能的极致优化,就是要发现播放流程中一点一滴的耗时,然后分析这些耗时,并提出有效的方式解决这些耗时.了解过ExoPlayer播放器的同学们都知道ExoPlayer的解码是依赖Android系统提供的原生的解码模块,即MediaCodec来实行视频和音频解码的.
码上就说
2021/01/12
2.9K0
看点视频秒开优化:解码器复用优化方案篇
随着短视频的流行,用户在碎片化场景下消费的视频内容越来越多。短视频本身时长较短,首帧体验尤为重要。随着预加载、预下载、IP直通车等传统优化手段使用,首帧体验有了明显提升。但经过进一步的数据分析,在手Q中长尾中低端机上,首帧表现依然不够理想。首帧优化已经进入深水区,受Google ExoPlayer切换清晰度方案(不用重启解码器)的启发,我们探索出一种适合短视频场景的,基于Android平台的跨播放器解码器复用方案,对中低端机首帧性能提升明显。本文是对整体方案的介绍,希望能帮助大家在首帧优化方向上提供新的思
腾讯VTeam技术团队
2020/10/14
6.3K0
ExoPlayer 自适应流切换分析
自适应流切换属于多路流切换的方式中的一种,ExoPlayer作为MediaCodec使用的集大成者,不仅具备通过MergingMediaSource实现不同流的组合切换,同样也具备基于MGEG-DASH、HLS、smoothing-stream 协议的的自适应流切换。当然,在项目中每种方案的选型都要充分考虑团队条件。
QQ音乐技术团队
2023/10/23
2.1K0
ExoPlayer 自适应流切换分析
ExoPlayer 多路流切换
国内互联网的发展的过程中,无论是3G、4G还是5G时代,甚至是在可见的未来nG时代,音视频领域一直自始至终参与其中,编解码标准也升级了一版又一版,和音视频的相关应用领域从传统的播放转为互动直播。从另一个方面,伴随中国的互联网发展的每一个过程,从高昂且卡慢流量资费到VIP、SVIP、SSVIP......,再到即将到来的人工智能和Web 3.0 ,必然也少不了音视频。接下来需要考虑你的钱包还能支撑多久,是不是已经准备好了?
QQ音乐技术团队
2023/09/19
1.7K0
ExoPlayer 多路流切换
Android ExoPlayer 音画同步代码分析
音画同步旨在通过时钟参考的方式,将音频、视频、歌词等播放时间对应起来,确保画面和声音同步。音视频播放器开发中,音画同步是一项非常重要的工作,直接影响用户的视听体验。
QQ音乐技术团队
2023/08/16
1.9K0
Android ExoPlayer 音画同步代码分析
ExoPlayer 漫谈之提升渲染性能
熟悉MediaCodec解码原理的肯定知道, MediaCodec提供了同步模式和异步模式两种模式:
码上就说
2021/01/12
1.4K0
Ijkplayer、ExoPlayer、VLC播放器综合比较
VLC 是VideoLAN 计划所研发的工程,最早预1996年开始,是一个完全的跨平台播放器,适合Windows、Mac OS、Linux、Android、iOS等系统,目前完全的跨平台播放器很少,VLC是最受欢迎的一种播放器;目前累计下载13亿次,是真真正正的全球播放器;
马上就说
2020/12/11
9.1K0
Ijkplayer、ExoPlayer、VLC播放器综合比较
ExoPlayer播放音视频的使用介绍
本文翻译自:https://google.github.io/ExoPlayer/guide.html#mediasource
AWeiLoveAndroid
2021/04/07
6.9K0
ijkplayer 源码分析
ijkplayer 是一款比较出众的开源 Android/iOS 跨平台播放器,基于 ffplay,API 易于集成,可定制编译控制体积。
字节流动
2021/06/09
2.2K0
ijkplayer 源码分析
Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)
好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明:
音视频牛哥
2024/09/11
2.7K0
Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)
视频播放优化浅析
随着移动终端的普及和网络的提速,以短视频为媒介的内容成了大家普遍接受和喜欢的内容消费形式。但是短视频是如何从一个视频地址到我们能看见的音视频内容呢?我们都知道播放器就是用来完成视频从地址解析到视频渲染这个流程的集合。那在我们Android平台上播放器的发展和演进过程中,有哪些实现方式?他们背后都有些什么优缺点呢?对于一个内容消费者来说,在浏览短视频的过程中,哪些性能指标是影响用户体验的呢?技术人员对于这些性能指标有哪些可做的优化?以及在快速的版本迭代中如何保证海量用户的播放体验呢?带着这些问题,本文尝试从
微信终端开发团队
2021/06/02
4.7K0
基于 ffmpeg 的跨平台播放器实现
许斌盛
2017/02/10
7.3K0
基于 ffmpeg 的跨平台播放器实现
4款知名播放器比较:ijkPlayer、VLC、SmartPlayer、ExoPlayer
ijkPlayer是BiliBili公司维护的一个开源工程,基于ffmpeg开发的一个播放器软件,支持Android和iOS平台,整个ijkplayer就是以ffplay为基础,如果只是使用它进行播放,集成也较为简单,使用也和MediaPlayer差不多,但是要定制化需求,就有一定的门槛高度。支持软硬编解码,支持倍速播放,可以定制化集成需要的功能,集成占用体积也很小,更详细的解释参看下面官方介绍:
音视频牛哥
2021/03/18
9.3K0
Android主流播放器比较
本篇文章主要介绍 Android 原生 VideoView,Google 开源视频播放框架 ExoPlayer,Vitamio 视频播放框架以及 Bilibili 开源视频播放框架 ijkplayer 的使用方法和优缺点。
蜻蜓队长
2018/08/03
3.2K0
一文掌握直播技术:实时音视频采集、编码、传输与播放
从游戏、教育、电商到娱乐,直播技术的应用场景无处不在。随着移动端的网速越来越快,直播技术的普及和发展将更加迅速。
陆业聪
2024/08/19
1.3K0
一文掌握直播技术:实时音视频采集、编码、传输与播放
【Android 音视频开发打怪升级:音视频硬解码篇】三、音视频播放:音视频同步
在上一篇文章定义的解码流程框架基类中,预留了几个虚函数,留给子类初始化自己的东西,本篇,就来看看如何实现。
开发的猫
2020/04/01
2.6K0
【Android 音视频开发打怪升级:音视频硬解码篇】三、音视频播放:音视频同步
IJKPlayer问题集锦之不定时更新
1、IJKPlayer 不像系统播放器会给你旋转视频角度,所以你需要通过onInfo的what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED去获取角度,自己旋转画面;或者开启硬解硬解码,不过硬解码容易造成黑屏无声,诸位慎重啊O__O "…。
GSYTech
2018/08/22
4K0
IJKPlayer问题集锦之不定时更新
基于ExoPlayer的ExoPlayerVideoView
在Android设备中,播放视频和音乐是非常普遍的。Android框架提供了一个对于媒体的操作的最省代码的解决方案:MediaPlayer。它提供了低等级的媒体API,例如:MediaCodec,AudioTrack,MediaDrm,可以用于建立自定义媒体播放的解决方案。 但是MediaPlayer的api实在是但太难用了,扩展性也不好。所以我们可以用诸如ijkplayer,VLC以及ExoPlayer。本文并不是讲述ExoPlayer如何使用的,而是一款基于ExoPlayer的VideoView。ExoPlayerVideoView旨在提供一个快捷的视频播放布局的解决方案。
JarvanMo
2018/09/06
4.2K0
基于ExoPlayer的ExoPlayerVideoView
【Android 音视频开发:FFmpeg音视频编解码篇】三、Android FFmpeg视频解码播放
本文很长,因为可能有比较多的小伙伴对 JNI C/C++ 不是很熟悉,所以本文比较详细的对 FFmpeg 用到的代码进行讲解,完整的演示了一遍 FFmpeg 的解码和渲染过程,并且对解码过程进行了封装。
开发的猫
2020/04/01
3.3K0
视频直播技术干货(十二):从入门到放弃,快速学习Android端直播技术
从游戏、教育、电商到娱乐,直播技术的应用场景无处不在。随着移动端的网速越来越快,直播技术的普及和发展将更加迅速。
JackJiang
2024/10/17
3360
视频直播技术干货(十二):从入门到放弃,快速学习Android端直播技术
推荐阅读
相关推荐
ExoPlayer 漫谈之解码器复用
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验