Android编码器性能优化实战:从MediaCodec到硬件加速

1次阅读
没有评论

共计 1592 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

背景痛点

在 Android 音视频开发中,编码器性能不足常常导致以下典型问题:

Android 编码器性能优化实战:从 MediaCodec 到硬件加速

  • 主线程阻塞:同步调用 MediaCodec API 可能导致 UI 卡顿
  • 内存溢出(OOM):未及时释放输入 / 输出缓冲区引发内存泄漏
  • 设备发热:软件编码 CPU 占用率高导致功耗飙升
  • 编码延迟:复杂场景下帧处理时间超过 33ms(30FPS 要求)

技术方案对比

方案类型 延迟水平 功耗表现 兼容性范围
MediaCodec 软件 高(50ms+) 全平台支持
FFmpeg 软件 中(30ms) 需 NDK 集成
硬件加速 低(<20ms) 需 API>=21

核心实现

MediaCodec 基础配置

  1. 初始化编码器(以 H.264 为例):

    val codec = MediaCodec.createEncoderByType("video/avc")
    val format = MediaFormat.createVideoFormat("video/avc", width, height).apply {setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)
        setInteger(MediaFormat.KEY_BIT_RATE, bitrate)
        setInteger(MediaFormat.KEY_FRAME_RATE, fps)
        setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameInterval)
    }
    codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)

  2. Surface 输入模式关键代码

    // 创建输入 Surface(带行号示例)val inputSurface = codec.createInputSurface()
    
    // 启动编码线程
    val outputThread = HandlerThread("EncoderOutput").apply {start() }
    codec.setCallback(object : MediaCodec.Callback() {override fun onInputBufferAvailable(codec: MediaCodec, index: Int) {// 通常 Surface 模式不需要手动处理输入缓冲区}
    
        override fun onOutputBufferAvailable(
            codec: MediaCodec,
            index: Int,
            info: MediaCodec.BufferInfo
        ) {val outputBuffer = codec.getOutputBuffer(index)
            // 处理编码后的数据
            codec.releaseOutputBuffer(index, false)
        }
    }, Handler(outputThread.looper))

性能优化

码率模式对比测试

BITRATE_MODE 画质稳定性 带宽占用
BITRATE_MODE_CBR 恒定
BITRATE_MODE_VBR 波动
BITRATE_MODE_CQ 不可控

异步模式线程安全

  1. 确保所有 MediaCodec 调用在同一个 Looper 线程
  2. 输出缓冲区处理完成后必须调用 releaseOutputBuffer()
  3. 避免在 Callback 中执行耗时操作

避坑指南

  1. 编码器复用崩溃 :调用 reset() 后必须重新 configure()
  2. 分辨率对齐要求:部分硬件要求 16 像素对齐(如高通方案)
  3. CSD 数据缺失:需在第一个关键帧前发送 csd-0/csd- 1 格式数据

动手实验

使用以下命令采集编码性能数据:

adb shell am profile start <process> systrace.py --time=10 -o trace.html

分析重点指标:
– 单帧编码耗时
– GPU 拷贝时间
– 缓冲区等待时间

正文完
 0
评论(没有评论)