Java 使用MediaCodec编码数据获取BufferOverflowException

Java 使用MediaCodec编码数据获取BufferOverflowException,java,android,android-mediacodec,Java,Android,Android Mediacodec,我使用Camera2API从相机获取数据,然后使用图像读取器,OnImageAvailableListener实现,我将相机数据插入队列,然后使用新的MediaCodec.Callback实现我想对数据进行编码 这是我初始化编解码器的方式: MediaCodecInfo codecInfo = selectCodec(MIMETYPE_VIDEO_AVC); MediaFormat format = MediaFormat.createVideoFormat(MIMETYPE_VIDEO_AVC

我使用
Camera2
API从相机获取数据,然后使用图像读取器,
OnImageAvailableListener
实现,我将相机数据插入队列,然后使用新的
MediaCodec.Callback
实现我想对数据进行编码

这是我初始化编解码器的方式:

MediaCodecInfo codecInfo = selectCodec(MIMETYPE_VIDEO_AVC);
MediaFormat format = MediaFormat.createVideoFormat(MIMETYPE_VIDEO_AVC, cameraRawData.getSize().getWidth(), cameraRawData.getSize().getHeight());
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
format.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
format.setLong(MediaFormat.KEY_MAX_INPUT_SIZE, Long.MAX_VALUE);
try {
    encoder = MediaCodec.createByCodecName(codecInfo.getName());
} catch (IOException e) {
    Log.e(TAG, "error creating encoder", e);
    throw new RuntimeException(e);
}
onInputBufferAvailable
实现:

ByteBuffer inputBuffer = codec.getInputBuffer(index);
ImageData imageData = imageDataQueue.poll();

if (imageData != null) {
    if (inputBuffer != null) {
        Log.i(TAG, "onInputBufferAvailable: " + imageData.getBuffer().length);
        inputBuffer.clear();
        byte[] bytes = imageData.getBuffer();
        try {
            Log.w(TAG, "before failure, the limit is: " + inputBuffer.limit());
            Log.w(TAG, "before failure, the byte array size is: " + bytes.length);
            inputBuffer.put(bytes);
        } catch (Exception e) {
            Log.e(TAG, "error", e);
        }
        codec.queueInputBuffer(index,
                0,
                imageData.getBuffer().length,
                imageData.getPresentationTimeUs(),
                0);
    }
} else {
    codec.queueInputBuffer(index,
            0,
            0,
            0,
            0);
}
最后,我收到了一个例外:

java.nio.BufferOverflowException
        at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:298)
        at java.nio.ByteBuffer.put(ByteBuffer.java:732)

一些附加信息,ByteBuffer限制设置为12。

调试数小时后,问题是颜色格式错误。 而不是:

format.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatSurface);
应该是:

format.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUV420Flexible);

将您的答案标记为有效,它解决了问题并将帮助未来用户,不要害羞;)