5

I'm working on replacing the audio track of my video with music from another file. So I modified the standard ExtractDecodeEditEncodeTest code (from bigflake) so that the audio MediaExtractor is created from said 'another file'. A strange thing happens when I try to send an EOS buffer into the audio decoder, however, in this line:

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

This netted me an android.media.MediaCodec$CodecException: Error 0xfffffff3.

When I caught it in a try-catch-finally loop, it's apparently an android.media.MediaCodec.error_neg_13 (code: -13). The video still came out seemingly fine, however, with the replaced audio track.

As far as I searched, there is nothing about this error ,not even in the logs. Does anyone know what causes it and how I can prevent it from happening?

Gensoukyou1337
  • 1,507
  • 1
  • 13
  • 31

2 Answers2

9

You get the android.media.MediaCodec.error_neg_13 if the MediaCodec.BUFFER_FLAG_END_OF_STREAM is sent in a buffer that contains data to be processed instead of in an empty buffer.

My solution was to send the MediaCodec.BUFFER_FLAG_END_OF_STREAM in a separate buffer not containing any data.

During my research of this error i did not find any reference to the android.media.MediaCodec.error_neg_13, not even in the libstagefright source code so i'm not sure if this is the only cause.

ChrisBe
  • 878
  • 9
  • 19
  • Apparently it's safer to send the EOS into the Encoder from the Decoder instead of from the Extractor to the Decoder. So I moved that EOS sending thing into the `audioEncoder.queueInputBuffer()` phase instead. – Gensoukyou1337 Jun 06 '18 at 08:23
  • That is true, but if you need only parts of the input file you cant get around signaling the EOS when you need it. BTW, if you find a solution to your problem, post an answer to help others with the same problem – ChrisBe Jun 06 '18 at 08:37
  • 1
    This helped immensely. I came here from https://stackoverflow.com/questions/60307164/why-the-mediacodec-codecexception-in-queueinputbuffer-only-happen-on-android/60571854#60571854, and the way I chose to adapt existing code to use a separate buffer was to add an infinite wait, e.g. `DECODER.dequeueInputBuffer(-1);` – Peter Gaultney Mar 06 '20 at 21:31
1

I managed to avoid the error by sending the EOS flag into the Encoder only after checking the presentationTimeUs in the decoder output buffer info, instead of doing it when queueing the decoder's input buffer.

The code:

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

That code is executed after processing the audio buffer, and presentationTime and size are changed from the original audioDecoderOutputBufferInfo. Basically, between getting the decoder's output buffer and sending the data into the encoder's input buffer - not before sending the extracted data/sample into the decoder's input buffer.

NOTE: Let me know if the full portion of the code is needed.

Gensoukyou1337
  • 1,507
  • 1
  • 13
  • 31