6

I'm trying to convert my phone camera output to .h264 es format but MediaCodec encoder stuck on TRY_AGAIN_LATER output buffer state after first frame.Camera preview is setted to NV21.

Here is camera-to-encoder:

    mCamera.setPreviewCallback(new Camera.PreviewCallback() {
            private long timestamp=0;
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                byte[] buffer = new byte[data.length];
                encode(data);
            }
        });

Encoder init:

private void initCodec() {
        try {
            mBufferInfo = new MediaCodec.BufferInfo();
            mMediaCodec = MediaCodec.createEncoderByType("video/avc");
        } catch (IOException e) {
            e.printStackTrace();
        }
        MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc",
                1920,
                1080);
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000);
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
             MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
        mMediaCodec.configure(mediaFormat,
                null,
                null,
                MediaCodec.CONFIGURE_FLAG_ENCODE);
        mMediaCodec.start();
    }

And encoder itself:

private synchronized void encode(byte[] data) {
        inputBuffers = mMediaCodec.getInputBuffers();// here changes
        outputBuffers = mMediaCodec.getOutputBuffers();

        int inputBufferIndex = mMediaCodec.dequeueInputBuffer(-1);
        if (inputBufferIndex >= 0) {
            ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
            inputBuffer.clear();
            inputBuffer.put(data);
            mMediaCodec.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
        } else {
            return;
        }

        int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(mBufferInfo, 10000);
        do {
            if (outputBufferIndex >= 0) {
                ByteBuffer outBuffer = outputBuffers[outputBufferIndex];
                System.out.println("buffer info-->" + mBufferInfo.offset + "--"
                        + mBufferInfo.size + "--" + mBufferInfo.flags + "--"
                        + mBufferInfo.presentationTimeUs);
                byte[] outData = new byte[mBufferInfo.size];
                outBuffer.get(outData);
                if (mBufferInfo.offset != 0) {
                    byte[] offsettedData;
                    offsettedData = Arrays.copyOfRange(outData, mBufferInfo.offset, outData.length-1);
                    pushFrame(offsettedData, offsettedData.length);
                } else {
                    pushFrame(outData, outData.length);
                }
                mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
                outputBufferIndex = mMediaCodec.dequeueOutputBuffer(mBufferInfo,
                        0);

            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                outputBuffers = mMediaCodec.getOutputBuffers();
            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                MediaFormat format = mMediaCodec.getOutputFormat();
            }
        } while (outputBufferIndex >= 0);
    }

Why output buffers stucked on try_again_later (-1)? All input data seems to be valid (from camera).

Max Plakhuta
  • 310
  • 2
  • 14
  • You can find some examples on bigflake (http://bigflake.com/mediacodec/) and in Grafika (https://github.com/google/grafika). If you choose to work with buffers of YUV data it may be necessary to perform a color conversion (http://stackoverflow.com/questions/13703596/mediacodec-and-camera-colorspaces-dont-match). – fadden May 16 '16 at 20:16
  • @fadden, I was studying sources from this link but decided that my approach is also not completely wrong (not completely, because it works on very first frame and no others). Alsi i didn't find out how to pass texture to the MediaCodec or get surface from texture. – Max Plakhuta May 16 '16 at 21:18

0 Answers0