1

I started seeing runtime exceptions in Redmi mobile running on Android 12 whenever I try to download a video from the app. It is not happening on Samsung, Motorola or Pixel devices. I re-use most of the code from Google grafika. Here is my MediaUtil class that renders the video on a canvas

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) // a method to draw the frame on a canvas
} catch (e: Exception) {
log.error(TAG, e) { "Caught exception while drawing frame" }
} finally {
inputSurface.unlockCanvasAndPost(canvas) //queues the input frame to the encoder
}

drainEncoderToMuxer(encoder, muxer, bufferInfo, trackIndex, true, clock)

        encoder.stop()
        encoder.release()
        inputSurface.release()
        muxer.stop()
        muxer.release()

Reference: https://github.com/google/grafika/blob/master/app/src/main/java/com/android/grafika/VideoEncoderCore.java

Here is my exception,

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)

And here is the log from Samsung mobile running the same code on 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

I tried changing the KEY_COLOR_FORMAT to COLOR_FormatYUV420Flexible and COLOR_FormatYUV422Flexible. Though it avoids crashes, it didn't render the video to the output file.

Madhan
  • 361
  • 4
  • 17

1 Answers1

2

I spent some time debugging this since it was blocking quite a number of users from completing important tasks in our app.

Drawing anything at all using a hardware canvas leads to the crash. Workaround is to replace inputSurface.lockHardwareCanvas() with inputSurface.lockCanvas(null). I check the device Android version and manufacturer, if it's Android 12 and Xiaomi then I apply this workaround.

Jozua
  • 1,274
  • 10
  • 18