Why the “MediaCodec CodecException” in “queueInputBuffer” only happen on Android API 29?

此生再无相见时 提交于 2020-06-17 06:28:07

问题


Basic Info

targetSdkVersion 28

Goal: The objective of the class is to resize a video before sending to my server.

Problem: The app crashes only on API 29, whether with real devices or using AVD. For example, the code works fine on Pixel 2 API 28, but not on Pixel 2 API 29

Source Code: I use mostly the sample code from bigflake.com.

Error message (detailed log are atteched below):

E/AndroidRuntime: FATAL EXCEPTION: Thread-20
    Process: com.myapp.myapp, PID: 9189
    android.media.MediaCodec$CodecException: Error 0xfffffff3
        at android.media.MediaCodec.native_queueInputBuffer(Native Method)
        at android.media.MediaCodec.queueInputBuffer(MediaCodec.java:2450)

What I have tried Due to the limited log info of MediaCodec$CodecException, I tried with no success changing from MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface to MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible.


The logs will show you the last two buffer cycles. I hope you'll see something of value.

Log of the one NOT working on *Pixel 2 API 29*

D/VideoResolutionChanger: no audio encoder output buffer
D/VideoResolutionChanger: loop: V(true){extracted:49(done:false) decoded:45(done:false) encoded:43(done:false)} A(true){extracted:45(done:false) decoded:44(done:false) encoded:1(done:false) pending:-1} muxing:true(V:0,A:1)
D/VideoResolutionChanger: video decoder: returned input buffer: 3
    video extractor: returned buffer of size 31007
    video extractor: returned buffer for time 4448177
D/VideoResolutionChanger: audio decoder: returned input buffer: 1
    audio extractor: returned buffer of size 32
    audio extractor: returned buffer for time 900000
D/VideoResolutionChanger: video decoder: returned output buffer: 5
    video decoder: returned buffer of size 1382400
    video decoder: returned buffer for time 4132500
D/VideoResolutionChanger: output surface: await new image
D/VideoResolutionChanger: output surface: draw image
D/VideoResolutionChanger: input surface: swap buffers
D/VideoResolutionChanger: video encoder: notified of new frame
    audio decoder: returned output buffer: 0
    audio decoder: returned buffer of size 320
D/VideoResolutionChanger: audio decoder: returned buffer for time 880000
    audio decoder: output buffer is now pending: -1
    audio decoder: attempting to process pending buffer: 0
D/VideoResolutionChanger: audio encoder: returned input buffer: 0
    audio decoder: processing pending buffer: 0
    audio decoder: pending buffer of size 320
    audio decoder: pending buffer for time 880000
D/VideoResolutionChanger: should have added track before processing output true
    video encoder: returned output buffer: 0
    video encoder: returned buffer of size 8234
    video encoder: returned buffer for time 3954177
D/VideoResolutionChanger: no audio encoder output buffer
D/VideoResolutionChanger: loop: V(true){extracted:50(done:false) decoded:46(done:false) encoded:44(done:false)} A(true){extracted:46(done:false) decoded:45(done:false) encoded:1(done:false) pending:-1} muxing:true(V:0,A:1)
D/VideoResolutionChanger: video decoder: returned input buffer: 4
    video extractor: returned buffer of size 30897
    video extractor: returned buffer for time 4519077
D/VideoResolutionChanger: video extractor: EOS
D/VideoResolutionChanger: releasing extractor, decoder, encoder, and muxer
D/SurfaceUtils: disconnecting from surface 0xc94d8008, reason disconnectFromSurface
D/MPEG4Writer: Video track stopping. Stop source
    Video track source stopping
    Video track source stopped
I/MPEG4Writer: Received total/0-length (44/0) buffers and encoded 44 frames. - Video
W/MPEG4Writer: 0-duration samples found: 1
I/MPEG4Writer: Received total/0-length (1/0) buffers and encoded 1 frames. - Audio
    Audio track drift time: 0 us
D/MPEG4Writer: Video track stopped. Stop source
D/MPEG4Writer: Audio track stopping. Stop source
    Audio track source stopping
    Audio track source stopped
    Audio track stopped. Stop source
    Duration from tracks range is [241451, 3994621] us
    Stopping writer thread
D/MPEG4Writer: 0 chunks are written in the last batch
D/MPEG4Writer: Writer thread stopped
I/MPEG4Writer: Ajust the moov start time from 0 us -> 0 us
D/MPEG4Writer: Video track stopping. Stop source
D/MPEG4Writer: Audio track stopping. Stop source
E/AndroidRuntime: FATAL EXCEPTION: Thread-20
    Process: com.myapp.myname, PID: 9189
    android.media.MediaCodec$CodecException: Error 0xfffffff3
        at android.media.MediaCodec.native_queueInputBuffer(Native Method)
        at android.media.MediaCodec.queueInputBuffer(MediaCodec.java:2450)
        at com.myapp.myname.utils.VideoResolutionChanger.doExtractDecodeEditEncodeMux(VideoResolutionChanger.java:543)

Log of the one working on *Pixel 2 API 28*

D/VideoResolutionChanger: no audio encoder output buffer
    loop: V(true){extracted:39(done:true) decoded:39(done:true) encoded:39(done:true)} A(true){extracted:147(done:false) decoded:146(done:false) encoded:5(done:false) pending:-1} muxing:true(V:0,A:1)
    audio decoder: returned input buffer: 3
    audio extractor: returned buffer of size 32
    audio extractor: returned buffer for time 2940000
D/VideoResolutionChanger: audio decoder: returned output buffer: 2
    audio decoder: returned buffer of size 320
    audio decoder: returned buffer for time 2920000
    audio decoder: output buffer is now pending: -1
    audio decoder: attempting to process pending buffer: 2
    audio encoder: returned input buffer: 2
    audio decoder: processing pending buffer: 2
    audio decoder: pending buffer of size 320
    audio decoder: pending buffer for time 2920000
D/VideoResolutionChanger: no audio encoder output buffer
D/VideoResolutionChanger: loop: V(true){extracted:39(done:true) decoded:39(done:true) encoded:39(done:true)} A(true){extracted:148(done:false) decoded:147(done:false) encoded:5(done:false) pending:-1} muxing:true(V:0,A:1)
D/VideoResolutionChanger: audio decoder: returned input buffer: 0
    audio extractor: returned buffer of size -1
    audio extractor: returned buffer for time -1
    audio extractor: EOS
D/VideoResolutionChanger: audio decoder: returned output buffer: 3
    audio decoder: returned buffer of size 320
    audio decoder: returned buffer for time 2940000
    audio decoder: output buffer is now pending: -1
    audio decoder: attempting to process pending buffer: 3
D/VideoResolutionChanger: audio encoder: returned input buffer: 3
    audio decoder: processing pending buffer: 3
    audio decoder: pending buffer of size 320
    audio decoder: pending buffer for time 2940000
D/VideoResolutionChanger: no audio encoder output buffer
D/VideoResolutionChanger: loop: V(true){extracted:39(done:true) decoded:39(done:true) encoded:39(done:true)} A(true){extracted:149(done:true) decoded:148(done:false) encoded:5(done:false) pending:-1} muxing:true(V:0,A:1)
    audio decoder: returned output buffer: 0
    audio decoder: returned buffer of size 0
    audio decoder: returned buffer for time 2880000
    audio decoder: output buffer is now pending: -1
    audio decoder: attempting to process pending buffer: 0
D/VideoResolutionChanger: audio encoder: returned input buffer: 0
    audio decoder: processing pending buffer: 0
    audio decoder: pending buffer of size 0
    audio decoder: pending buffer for time 2880000
D/VideoResolutionChanger: audio decoder: EOS
D/VideoResolutionChanger: should have added track before processing outputtrue
    audio encoder: returned output buffer: 0
    audio encoder: returned buffer of size 761
    audio encoder: returned buffer for time 2801451
    audio encoder: EOS
    encoded and decoded video frame counts should match39 39
    decoded frame count should be less than extracted frame count39 39
D/VideoResolutionChanger: no frame should be pending -1 -1
    releasing extractor, decoder, encoder, and muxer
D/SurfaceUtils: disconnecting from surface 0xd8b50808, reason disconnectFromSurface
D/MPEG4Writer: Video track stopping. Stop source
I/MPEG4Writer: Received total/0-length (6/0) buffers and encoded 6 frames. - Audio
D/MPEG4Writer: Video track source stopping
I/MPEG4Writer: Audio track drift time: 0 us
D/MPEG4Writer: Video track source stopped
I/MPEG4Writer: Received total/0-length (38/0) buffers and encoded 38 frames. - Video
D/MPEG4Writer: Video track stopped. Stop source
D/MPEG4Writer: Audio track stopping. Stop source
    Audio track source stopping
    Audio track source stopped
    Audio track stopped. Stop source
    Duration from tracks range is [3060067, 3302540] us
    Stopping writer thread
D/MPEG4Writer: 0 chunks are written in the last batch
D/MPEG4Writer: Writer thread stopped
I/MPEG4Writer: Ajust the moov start time from 0 us -> 0 us
D/MPEG4Writer: Video track stopping. Stop source
D/MPEG4Writer: Audio track stopping. Stop source

回答1:


I have also used the Bigflake code and ran into this with Android 10 (API 29).

The other linked issues are helpful, but don't directly answer the question as regards how to modify the Bigflake code. After spending a couple of hours, this is what I came up with.

For both video and audio, within doExtractDecodeEditEncodeMux, prior to where

                 xxxxxDecoder.queueInputBuffer(
                            decoderInputBufferIndex,
                            0,
                            0,
                            0,
                            MediaCodec.BUFFER_FLAG_END_OF_STREAM);

is called, you want to add the following line of code, which ensures that you use an empty buffer to send the EOS.

                    // wait forever for a new buffer
                    decoderInputBufferIndex = xxxxxDecoder.dequeueInputBuffer(-1);

There are two such instances, and the resulting code for video looks like this, with most of the context given:

                videoExtractorDone = !videoExtractor.advance();
                if (videoExtractorDone) {
                    if (VERBOSE) {
                        final String log = "Video extractor: EOS";
                        Log.d(TAG, log);
                        emitLog(log);
                    }
                    Log.i(TAG, "WAITING indefinitely until an input video buffer for EOS is available");
                    // wait forever for a new buffer
                    decoderInputBufferIndex = videoDecoder.dequeueInputBuffer(-1); // this is the actually important line
                    videoDecoder.queueInputBuffer(
                            decoderInputBufferIndex,
                            0,
                            0,
                            0,
                            MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                            Log.i(TAG, "Successfully sent video EOS");
                }

Hopefully that helps anyone else stumbling into this.




回答2:


I met the same problem and finally solved it. I used the asynctaskMode and codec callback.

while (!mAudioExtractorDone) {
                    int size = mAudioExtractor.readSampleData(decoderInputBuffer, 0);
                    long presentationTime = mAudioExtractor.getSampleTime();
                    MLog.i(TAG, "audio extractor: ronInputBufferAvailable() presentationTime = " + presentationTime);
                    if (size >= 0) {
                        codec.queueInputBuffer(index, 0, size, presentationTime, mAudioExtractor.getSampleFlags());
                    }else {
                        Log.e(TAG, "onInputBufferAvailable: " + "size < 0 = " + size);
                        codec.queueInputBuffer(index, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                        mAudioExtractorDone = true;
                    }
                    mAudioExtractor.advance();
                    mAudioExtractedFrameCount++;
                    logState();

Send the BUFFER_FLAG_END_OF_STREAM when the size is below zero. Note the marker bits of the loop (mAudioExtractorDone).



来源:https://stackoverflow.com/questions/60307164/why-the-mediacodec-codecexception-in-queueinputbuffer-only-happen-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!