简体   繁体   English

为什么“queueInputBuffer”中的“MediaCodec CodecException”只发生在 Android API 29 上?

[英]Why the "MediaCodec CodecException" in "queueInputBuffer" only happen on Android API 29?

Basic Info基础信息

targetSdkVersion 28目标SDK版本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.问题:该应用程序仅在 API 29 上崩溃,无论是使用真实设备还是使用 AVD。 For example, the code works fine on Pixel 2 API 28 , but not on Pixel 2 API 29例如,代码在Pixel 2 API 28上运行良好,但在Pixel 2 API 29上不起作用

Source Code : I use mostly the sample code from bigflake.com .源代码:我主要使用来自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 .我曾尝试由于有限的日志信息MediaCodec$CodecException ,我尝试没有成功改变从MediaCodecInfo.CodecCapabilities.COLOR_FormatSurfaceMediaCodecInfo.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*不在 *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*在 *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

I think the correct way to go about it is to let it go another loop after xxxxExtractor.advance() returns false.我认为解决它的正确方法是在xxxxExtractor.advance()返回 false 后xxxxExtractor.advance()

I modified my code to only mark an extractor done after the size returned by xxxxExtractor.readSampleData returns -1 That way you know the buffer you are sending to queueInputBuffer is empty.我修改了我的代码,只在xxxxExtractor.readSampleData返回的大小返回-1之后才标记一个提取器完成这样你就知道你发送到 queueInputBuffer 的缓冲区是空的。

So: xxxxExtractorDone = !xxxxExtractor.advance();所以: xxxxExtractorDone = !xxxxExtractor.advance(); -> xxxxExtractorDone = !xxxxExtractor.advance() && size == -1; -> xxxxExtractorDone = !xxxxExtractor.advance() && size == -1;

I have also used the Bigflake code and ran into this with Android 10 (API 29).我还使用了 Bigflake 代码并在 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.其他链接问题很有帮助,但不要直接回答有关如何修改 Bigflake 代码的问题。 After spending a couple of hours, this is what I came up with.花了几个小时后,这就是我想出的。

For both video and audio, within doExtractDecodeEditEncodeMux , prior to where对于视频和音频,在doExtractDecodeEditEncodeMux ,在 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.被调用时,您要添加以下代码行,以确保您使用空缓冲区来发送 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.希望这可以帮助其他人绊倒这一点。

I met the same problem and finally solved it.我遇到了同样的问题,终于解决了。 I used the asynctaskMode and codec callback.我使用了asynctaskMode和编解码器回调。

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.当大小小于零时发送BUFFER_FLAG_END_OF_STREAM Note the marker bits of the loop ( mAudioExtractorDone ).请注意循环的标记位 ( mAudioExtractorDone )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 解码H264视频时Android MediaCodec releaseOutputBuffer抛出MediaCodec.CodecException - Android MediaCodec releaseOutputBuffer throws MediaCodec.CodecException when decoding H264 video Samsung Galaxy Note 4中的MediaCodec CodecException - MediaCodec CodecException in Samsung galaxy note 4 MediaCodec API android中的timeUs - timeoutUs in MediaCodec API android 为什么 android:requestLegacyExternalStorage=“true” 在 Android 10 - API 29 中不起作用 - Why android:requestLegacyExternalStorage=“true” not working in Android 10 - API 29 Android MediaCodec api压缩视频 - Android MediaCodec api compress video E/LoadedApk:无法仅在 Android Q (API 29) 上实例化 appComponentFactory - E/LoadedApk: Unable to instantiate appComponentFactory only on Android Q (API 29) 为什么文件访问方法 getExternalStorageDirectory() 在 Android 10 (API 29) 上不起作用 - why file accessing method getExternalStorageDirectory() is not working on Android 10 (API 29) 为什么 API 29 中缺少 ViewPropertyAnimatorRT? - Why are ViewPropertyAnimatorRT missing in API 29? 通知未显示 android API 29 - Notifications not showing android API 29 调用 mediaCodec.configure 时手机崩溃,出现错误 MediaCodec$CodecException: Error 0x80001001 - Phone crashes when calling mediaCodec.configure with error MediaCodec$CodecException: Error 0x80001001
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM