H.265安卓视频转MP4实战:编解码优化与性能调优指南
作为一名安卓开发者,最近在处理H.265视频转码时踩了不少坑。今天就把我的实战经验整理成笔记,分享给同样被兼容性问题困扰的小伙伴们。
为什么需要转码?
H.265(HEVC)虽然压缩率高,但在安卓生态里简直是「兼容性地狱」:
- 约30%的安卓设备无法硬解H.265
- 微信等社交平台直接拒绝HEVC格式上传
- 低端设备解码时CPU占用率轻松突破80%

技术方案选型
测试了三套方案在骁龙865上的表现:
| 方案 | 1080P转码耗时 | CPU占用峰值 | 内存峰值 | |-------------------|---------------|-------------|----------| | FFmpeg纯软解 | 42s | 95% | 380MB | | MediaCodec硬解 | 15s | 30% | 210MB | | 混合方案(本文推荐)| 18s | 45% | 250MB |
推荐混合方案:用MediaCodec解码H.265,FFmpeg做后处理(如滤镜),最后MediaMuxer封装MP4。
核心代码实现
1. 解码流水线搭建
关键点在于正确配置ColorFormat,这里用YUV420Flexible保证兼容性:
MediaFormat inputFormat = MediaFormat.createVideoFormat("video/hevc", width, height);
MediaCodec decoder = MediaCodec.createDecoderByType("video/hevc");
decoder.configure(inputFormat, surface, null, 0);
// 关键:设置自适应YUV格式
inputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
2. 编码参数优化
比特率设置建议采用动态码率(VBR):
MediaFormat outputFormat = MediaFormat.createVideoFormat("video/avc", width, height);
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, width * height * 3); // 经验值
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
3. 线程安全封装
用双缓冲队列避免阻塞:
// 解码线程
synchronized (frameQueue) {
frameQueue.offer(frameData);
frameQueue.notifyAll();
}
// 编码线程
while (frameQueue.isEmpty()) {
frameQueue.wait();
}
ByteBuffer frame = frameQueue.poll();

性能优化实战
内存控制技巧
测试不同分辨率下的内存占用:
| 分辨率 | 纯软解内存 | 硬解内存 | |---------|------------|----------| | 720p | 180MB | 90MB | | 1080p | 380MB | 210MB | | 4K | 1.2GB | 650MB |
优化建议: 1. 大视频分片处理 2. 及时releaseOutputBuffer 3. 禁用不必要的帧重排序
首帧加速方案
通过预热编解码器,首帧延迟从800ms降到200ms:
- 提前初始化Codec但不传递数据
- 保持解码器常驻内存(注意OOM风险)
- 使用温启动池管理实例
避坑指南
Android 8.0以下兼容性: - 遇到COLOR_FormatYUV420Flexible不支持时,回退到COLOR_FormatYUV420Planar - 需要额外做色彩空间转换
内存泄漏预防:
// 必须按顺序释放
surface.release();
decoder.stop();
decoder.release();
延伸实验
尝试调整CRF参数(18-28区间): - CRF每+6,文件体积减半 - CRF>24时明显出现块状伪影
完整代码示例已上传Gist:点击查看
推荐进一步学习: 1. Android MediaCodec官方文档 2. FFmpeg硬件加速编译指南 3. OpenGL ES视频后处理
希望这篇笔记能帮你少走弯路,如果有更好的方案欢迎交流讨论!
更多推荐


所有评论(0)