Android 12红米设备MediaCodec原生崩溃问题求助
问题:Android 12红米设备视频编码崩溃,其他品牌设备正常
现象
运行Android 12的红米设备在应用内生成视频时触发运行时崩溃,三星、摩托罗拉、Pixel等品牌同版本Android设备无此问题。代码基于Google Grafika项目实现,核心编码逻辑如下:
val encoder = MediaCodec.createEncoderByType("video/avc") val format = MediaFormat.createVideoFormat("video/avc", width, height) format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface) format.setInteger(MediaFormat.KEY_BIT_RATE, 100000) format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate) format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2) encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) val inputSurface: Surface try { inputSurface = encoder.createInputSurface() } catch (ise: IllegalStateException) { // catch exception } encoder.start() val muxer = MediaMuxer(outputFile.toString(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) val bufferInfo = MediaCodec.BufferInfo() trackIndex = drainEncoderToMuxer(encoder, muxer, bufferInfo, trackIndex, false, clock) val canvas = inputSurface.lockHardwareCanvas() try { drawFrame(canvas, frameIndex, frameCount) // 在画布上绘制帧的方法 } catch (e: Exception) { log.error(TAG, e) { "Caught exception while drawing frame" } } finally { inputSurface.unlockCanvasAndPost(canvas) // 将输入帧提交给编码器 } drainEncoderToMuxer(encoder, muxer, bufferInfo, trackIndex, true, clock) encoder.stop() encoder.release() inputSurface.release() muxer.stop() muxer.release()
崩溃日志
2022-07-27 10:59:42.475 14534-14971/com.app.debug W/OMXUtils: do not know color format 0x7f000789 = 2130708361 2022-07-27 10:59:42.511 14534-14971/com.app.debug I/ACodec: Need to setDefaultCodecColorAspectsIfNeeded 2022-07-27 10:59:42.591 14534-14772/com.app.debug D/MPEG4Writer: PreAllocation disabled. fallocate : Operation not supported on transport endpoint, 95 2022-07-27 10:59:42.670 14534-14534/com.app.debug I/PlayButtonView: [PlayButton] called Play with indicator:false, looping:false 2022-07-27 10:59:42.853 14534-14637/com.app.debug A/HidlStatus: Status.cpp:143] Failed HIDL return status not checked. Usually this happens because of a transport error (error parceling, binder driver, or from unparceling). If you see this in code calling into "Bn" classes in for a HAL server process, then it is likely that the code there is returning transport errors there (as opposed to errors defined within its protocol). Error is: Status(EX_TRANSACTION_FAILED): 'DEAD_OBJECT: ' 2022-07-27 10:59:42.853 14534-14971/ccom.app.debug E/ACodec: OMX/mediaserver died, signalling error! 2022-07-27 10:59:42.854 14534-14971/com.app.debug E/ACodec: signalError(omxError 0x8000100d, internalError -32) 2022-07-27 10:59:42.854 14534-14970/com.app.debug E/MediaCodec: Codec reported err 0xffffffe0, actionCode 0, while in state 6/STARTED 2022-07-27 10:59:43.059 14534-14637/com.app.debug: runtime.cc:669] Runtime aborting... runtime.cc:669] Dumping all threads without mutator lock held runtime.cc:669] All threads: runtime.cc:669] DALVIK THREADS (104): runtime.cc:669] "RenderThread" prio=10 tid=54 Runnable runtime.cc:669] | group="" sCount=0 ucsCount=0 flags=0 obj=0x15fc90c8 self=0xb400007480344000 runtime.cc:669] | sysTid=14637 nice=-10 cgrp=system sched=0/0 handle=0x73ef42fcb0 runtime.cc:669] | state=R schedstat=( 2482457056 440300499 3164 ) utm=160 stm=87 core=6 HZ=100 runtime.cc:669] | stack=0x73ef338000-0x73ef33a000 stackSize=991KB runtime.cc:669] | held mutexes= "abort lock" "mutator lock"(shared held) runtime.cc:669] native: #00 pc 0000000000460620 /apex/com.android.art/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+120) runtime.cc:669] native: #01 pc 00000000006ffed0 /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+252) runtime.cc:669] native: #02 pc 00000000007079a8 /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+304) runtime.cc:669] native: #03 pc 000000000031b7dc /apex/com.android.art/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+628) runtime.cc:669] native: #04 pc 00000000006e6eb4 /apex/com.android.art/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool)+476) runtime.cc:669] native: #05 pc 00000000006d8200 /apex/com.android.art/lib64/libart.so (art::AbortState::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+204) runtime.cc:669] native: #06 pc 00000000006d7fa8 /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+1672)
三星Android 12设备正常日志
:59.672 30929-31816/com.app.debug W/OMXUtils: do not know color format 0x7f000789 = 2130708361 2022-07-27 16:28:59.697 30929-31816/com.app.debug I/ACodec: [OMX.qcom.video.encoder.avc] Now Loaded->Idle 2022-07-27 16:28:59.725 30929-31815/com.app.debug I/MediaCodec: setCodecState state(0), called in 6 2022-07-27 16:28:59.725 30929-31816/com.app.debug I/ACodec: [OMX.qcom.video.encoder.avc] Now Idle->Executing 2022-07-27 16:28:59.730 30929-31816/com.app.debug I/ACodec: [OMX.qcom.video.encoder.avc] Now Executing 2022-07-27 16:28:59.748 30929-31452/com.app.debug D/MPEG4Writer: PreAllocation disabled. fallocate : Operation not supported on transport endpoint, 95 2022-07-27 16:28:59.770 30929-31313/com.app.debug D/OpenGLRenderer: eglCreateWindowSurface 2022-07-27 16:28:59.784 30929-30929/com.app.debug I/PlayButtonView: [PlayButton] called Play with indicator:false, looping:false 2022-07-27 16:28:59.806 30929-31816/com.app.debug D/ACodec: dataspace changed to 0x10c10000 (R:2(Limited), P:3(BT601_6_625), M:3(BT601_6), T:3(SMPTE170M)) (R:2(Limited), S:2(BT601_625), T:3(SMPTE_170M)) 2022-07-27 16:28:59.807 30929-31313/com.app.debug E/FrameEvents: updateAcquireFence: Did not find frame. 2022-07-27 16:28:59.833 30929-31313/com.app.debug E/FrameEvents: updateAcquireFence: Did not find frame. 2022-07-27 16:28:59.835 30929-31452/com.app.debug D/MPEG4Writer: fpathconf _PC_FILESIZEBITS:64 2022-07-27 16:28:59.835 30929-31452/com.app.debug D/MPEG4Writer: File size limit set to 4503599627370495 bytes implicitly 2022-07-27 16:28:59.835 30929-31452/com.app.debug D/MPEG4Writer: MP4WtrCtrlHlpLooper Started 2022-07-27 16:28:59.837 30929-31815/com.app.debug I/MediaCodec: setCodecState state(1), called in 6 2022-07-27 16:28:59.838 30929-31829/com.app.debug I/MPEG4Writer: setStartTimestampUs: 0 from Video track 2022-07-27 16:28:59.838 30929-31829/com.app.debug I/MPEG4Writer: Earliest track starting time: 0
已尝试的方案
- 将
KEY_COLOR_FORMAT改为COLOR_FormatYUV420Flexible和COLOR_FormatYUV422Flexible,可避免崩溃,但无法生成有效视频文件。
解决方案
1. 分离编码线程与RenderThread
崩溃发生在RenderThread,推测是线程资源冲突导致OMX服务崩溃。所有MediaCodec、MediaMuxer相关操作必须放在独立的后台线程执行,禁止在UI线程或RenderThread中处理编码逻辑。
2. 替换Canvas渲染为EGL OpenGL流程
部分设备的硬件编码器对lockHardwareCanvas()兼容性较差,改用Grafika标准的EGL渲染方案:
- 创建EGLContext关联编码器的InputSurface
- 使用OpenGL ES API绘制帧内容
- 绘制完成后调用
eglSwapBuffers()提交帧到编码器
3. 补充颜色空间配置参数
红米设备编码器可能需要明确的颜色空间参数,在配置MediaFormat时添加:
format.setInteger(MediaFormat.KEY_COLOR_STANDARD, MediaFormat.COLOR_STANDARD_BT601) format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, MediaFormat.COLOR_TRANSFER_SMPTE_170M) format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED)
4. 优化编码器数据导出逻辑
确保drainEncoderToMuxer方法处理逻辑正确:
- 等待编码器输出有效数据后,再将轨道添加到MediaMuxer
- 处理EOS信号时,确保所有编码器缓存数据都写入Muxer
- 避免在编码器未输出任何数据时调用
muxer.stop()
5. 动态验证编码器格式支持
提前校验编码器对Surface格式的支持,避免硬编码格式导致兼容性问题:
val codecInfo = MediaCodecList(MediaCodecList.REGULAR_CODECS).findEncoderForFormat(format) val capabilities = codecInfo.getCapabilitiesForType("video/avc") if (!capabilities.colorFormats.contains(MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)) { // 降级到编码器支持的其他格式 }
内容的提问来源于stack exchange,提问作者Madhan
相关产品推荐
相关产品推荐

