[英]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_FormatSurface
到MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible
。
The logs will show you the last two buffer cycles .日志将显示最后两个缓冲周期。 I hope you'll see something of value.我希望你能看到有价值的东西。
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)
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.