XorOrNor
XorOrNor

Reputation: 8978

MediaCodec outputBuffer is always empty

I have a problem with the outputBuffer inside my onOutputBufferAvailable() callback method. Everytime this callback method is called I check the outputBuffer using outputBuffer.hasRemaining method and this is always return false.

        codec.setCallback(new MediaCodec.Callback() {

            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {

                ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
                int rounds = extractor.readSampleData(inputBuffer,0);

                if(rounds > 0) {
                    long currentT = extractor.getSampleTime();
                    Log.i("CurrentT", String.valueOf(currentT/(1000*1000)));
                    codec.queueInputBuffer(inputBufferId, 0, rounds, 0, 0);
                     extractor.advance();


                } else {
                    // EOS
                    codec.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                    Log.i("EOS","=-1");


                }


            }

            @Override
            public void onError(@NonNull MediaCodec mediaCodec, @NonNull MediaCodec.CodecException e) {
                Log.i("error", "e");
            }
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, MediaCodec.BufferInfo info) {
                ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);

                Log.i("has", String.valueOf(outputBuffer.hasRemaining()));
                if (outputBuffer.hasRemaining()) {

                    b = outputBuffer.get();
                    Log.i("i", String.valueOf(b));
                    BAOS.write(b);
                    outputBuffer.clear();

                } else {

                    array= BAOS.toByteArray();
                    codec.stop();
                    codec.release();

                }
                 codec.releaseOutputBuffer(outputBufferId, false);

            }


            @Override
            public void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
                // Subsequent data will conform to new format.
                // Can ignore if using getOutputFormat(outputBufferId)
               // mOutputFormat = format; // option B
            }
        });

Upvotes: 0

Views: 2271

Answers (2)

XorOrNor
XorOrNor

Reputation: 8978

The main reason of the problem was wrong MediaCodec mode; wasMediaCodec.createByCodecName(...), should be codec = MediaCodec.createDecoderByType("audio/mpeg"). After unsuccesfull tries getting byte using get() I finally ended up with get(byte[] dst) method. Working code below.

            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, MediaCodec.BufferInfo info) {
                ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);

                    byte[] b = new byte[outputBuffer.remaining()];
                    outputBuffer.get(b);

                    for(i=0;i< b.length;i++) {
                        BAOS.write(b[i]);
                    }
                    outputBuffer.clear();

                codec.releaseOutputBuffer(outputBufferId, false);

                if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
                    array=BAOS.toByteArray();
                    Log.i("array", String.valueOf(array.length));
                    FileTools fl = new FileTools();
                    fl.WriteFile(array);
                    codec.stop();
                    codec.release();
                }
            }

Upvotes: 0

mstorsjo
mstorsjo

Reputation: 13317

The position/limit markers on the ByteBuffers aren't updated by MediaCodec, you need to check the MediaCodec.BufferInfo object that you got to know the position and length of the actual payload data.

Upvotes: 1

Related Questions