【问题标题】:MediaCodec - strange error when sending EOS buffer into audio decoderMediaCodec - 将 EOS 缓冲区发送到音频解码器时出现奇怪的错误
【发布时间】:2026-01-13 20:20:03
【问题描述】:

我正在努力用另一个文件中的音乐替换我视频的音轨。所以我修改了标准ExtractDecodeEditEncodeTest 代码(来自bigflake),以便音频MediaExtractor 是从所说的“另一个文件”创建的。当我尝试将 EOS 缓冲区发送到音频解码器时,发生了一件奇怪的事情,然而,在这一行中:

this.audioDecoder.queueInputBuffer(decoderInputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

这让我获得了android.media.MediaCodec$CodecException: Error 0xfffffff3

当我在 try-catch-finally 循环中捕获它时,它显然是 android.media.MediaCodec.error_neg_13(代码:-13)。然而,视频仍然看起来不错,但音轨被替换了。

据我搜索,没有任何关于此错误的信息,甚至在日志中也没有。有谁知道是什么原因造成的以及如何防止它发生?

【问题讨论】:

  • 你最后是怎么解决这个问题的?

标签: android android-mediacodec


【解决方案1】:

如果MediaCodec.BUFFER_FLAG_END_OF_STREAM 在包含要处理的数据的缓冲区而不是空缓冲区中发送,您将获得android.media.MediaCodec.error_neg_13

我的解决方案是在不包含任何数据的单独缓冲区中发送MediaCodec.BUFFER_FLAG_END_OF_STREAM

在我研究这个错误的过程中,我没有找到任何对 android.media.MediaCodec.error_neg_13 的引用,甚至在 libstagefright 源代码中也没有,所以我不确定这是否是唯一的原因。

【讨论】:

  • 显然,将 EOS 从解码器发送到编码器比从提取器发送到解码器更安全。所以我把那个 EOS 发送的东西移到了audioEncoder.queueInputBuffer() 阶段。
  • 确实如此,但如果您只需要输入文件的一部分,您就无法在需要时向 EOS 发出信号。顺便说一句,如果您找到解决问题的方法,请发布答案以帮助其他有同样问题的人
  • 这帮助很大。我从*.com/questions/60307164/… 来到这里,我选择调整现有代码以使用单独的缓冲区的方式是添加无限等待,例如DECODER.dequeueInputBuffer(-1);
【解决方案2】:

我只在检查解码器输出缓冲区信息中的presentationTimeUs 后才通过将 EOS 标志发送到编码器来避免错误,而不是在解码器的输入缓冲区排队时这样做。

代码:

if(presentationTime < totalTime) {                            
    audioEncoder.queueInputBuffer(encoderInputBufferIndex, 0, size, presentationTime, audioDecoderOutputBufferInfo.flags);
} else {
    audioEncoder.queueInputBuffer(encoderInputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); }

该代码在处理完音频缓冲区后执行,presentationTimesize 由原来的 audioDecoderOutputBufferInfo 更改。基本上,在获取解码器的输出缓冲区和将数据发送到编码器的输入缓冲区之间——而不是在将提取的数据/样本发送到解码器的输入缓冲区之前。

注意:如果需要完整的代码部分,请告诉我。

【讨论】: