Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android MediaCodec将原始视频编码为h264_Android_Encoding_H.264_Android Mediacodec - Fatal编程技术网

Android MediaCodec将原始视频编码为h264

Android MediaCodec将原始视频编码为h264,android,encoding,h.264,android-mediacodec,Android,Encoding,H.264,Android Mediacodec,我正在尝试将手机摄像头输出转换为.h264 es格式,但MediaCodec编码器仍处于启用状态,请稍后在第一帧后重试输出缓冲区状态。摄像头预览设置为NV21 这里是摄像机到编码器: mCamera.setPreviewCallback(new Camera.PreviewCallback() { private long timestamp=0; @Override public void onPreviewFra

我正在尝试将手机摄像头输出转换为.h264 es格式,但MediaCodec编码器仍处于启用状态,请稍后在第一帧后重试输出缓冲区状态。摄像头预览设置为NV21

这里是摄像机到编码器:

    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);
            }
        });
编码器初始化:

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();
    }
和编码器本身:

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);
    }

为什么输出缓冲区阻塞?请稍后重试(-1)?所有输入数据似乎都有效(来自摄像头)

您可以在bigflake()和Grafika()中找到一些示例。如果您选择使用YUV数据缓冲区,则可能需要执行颜色转换()。@fadden,我正在研究此链接中的源代码,但确定我的方法也没有完全错误(不完全错误,因为它只在第一帧上工作,没有其他帧)。另外,我没有找到如何将纹理传递到MediaCodec或从纹理获取表面。