概述
在安卓平台为了实现h264视频编码,我们通常可以使用libx264, ffmpeg等第三方视频编码库,但是如果对编码的速度有一定的要求,要实现实时甚至超实时的高速视频编码,我们并没有太多选项,只能使用Android提供的MediaCodec硬编码模块。
MediaCodec模块在实际使用中会遇到很多问题,本文主要讨论使用MediaCodec来对OpenGL渲染的画面进行编码视频时,如何达到速度快和画面清晰的均衡。
注意,本文将默认你已经熟悉使用MediaCodec,配合SurfaceTexture进行OpenGL画面编码的基本流程
分析
影响编码速度的因素
出去设备硬件的因素,影响MediaCodec对视频画面进行编码的速度的其他因素并不多,我们实践探索下来主要发现以下几点:
-
画面尺寸
画面尺寸就是要编码的视频画面的宽高了,它直接定义了每一帧要编码的画面数据的大小,所以它也主要决定了Mediacodec在进行每帧编码时的任务量。这个很容易理解。 -
帧速率
帧速率指的是每一秒时长的视频所包含的静止画面的帧数。由于Mediacodec在编码时是以帧为单位,对每一个静止帧画面进行编码,所以,帧速率直接决定了MediaCodec在编码固定时长的视频时需要编码的画面数量。
比如,同样编码一段10秒钟的视频,在不考虑画面内容和其他因素的影响下,如果帧速率是30帧每秒,那么MediaCodec的编码工作量大致就是帧速率15帧每秒的情况的2倍,所以其耗时也大致是其2倍。 -
同步模式下的Time Out设置
MediaCodec有两种工作模式,同步模式和异步模式,其中异步模式只有在Android 5.0以上的系统才支持。如果要兼容5.0以下的系统,那么就必须用到同步模式,而网上流传的众多对MediaCodec的编码流程讲解(比如经典的bigflake)也都是基于同步模式的。
那么在这些文档和案例指导下,大家在使用MediaCodec进行编码时,也都使用着大致相同的设置。
其中,同步模式下,在编码流程中,我们需要调用MediaCodec的dequeueOutputBuffer
接口来从队列里获取编码输出缓冲区的