Android Camera2管道:如何使用MediaCodec从输入Surface编码h.264单位?

问题描述 投票:0回答:1

我有一个使用Camera2 API的Android应用程序。最终目标是使h264单元写入流。到目前为止,我有

  1. 成功创建了一个捕获会话,并可以通过以下方式写入预览,本地记录和流媒体表面:
    session.device.createCaptureRequest(CameraDevice.TEMPLATE_RECORD).run {
                    addTarget(previewSurface)
                    addTarget(recorder.surface)
                    addTarget(streamer.surface)
                    set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, Range(args.fps, args.fps))
                    build()
                }
  1. [设置MediaCodec以对上方的streamer.suface参数中的数据进行编码,其中,表面是通过如下创建的MediaCodec对mediaCodec.createInputSurface的调用而派生的]
    internal fun streamingCodec(args: CameraFragmentArgs): MediaCodec {
        val mediaFormat = MediaFormat.createVideoFormat("video/avc", args.width, args.height).apply {
            setInteger(MediaFormat.KEY_BIT_RATE, 2000 * 1024)
            setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2)
            setInteger(MediaFormat.KEY_FRAME_RATE, args.fps)
            setInteger(
                MediaFormat.KEY_COLOR_FORMAT,
                MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface
            )
        }

        val encoderName = MediaCodecList(MediaCodecList.REGULAR_CODECS).findEncoderForFormat(mediaFormat)

        return MediaCodec.createByCodecName(encoderName).apply {
            configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
        }
    }
  1. [当上面的surface中包含信息时使用异步回调
ByteBuffer

我的困惑是,private class StreamingCallBack) : MediaCodec.Callback() { override fun onInputBufferAvailable(codec: MediaCodec, index: Int) = Unit override fun onOutputBufferAvailable(codec: MediaCodec, index: Int, info: BufferInfo) { val byteBuffer = codec.getOutputBuffer(index) // Is the data in the buffer properly encoded as h.264 here? Did I need to use MediaExtractor? } override fun onOutputFormatChanged(codec: MediaCodec, format: MediaFormat) = Unit override fun onError(codec: MediaCodec, e: MediaCodec.CodecException) { Log.i("TEST", "onError in codec") } } 中的值是否正确编码?我需要使用ByteBuffer清理从输入MediaExtractor输入的数据,然后再将其传递给Surface进行编码吗?管道足够干净,但是我不确定是否需要什么。 MediaCodec是最大的指南,它提到document对原始数据进行操作,这使我认为我需要MediaCodec,但这并不需要MediaExtractor作为正确顺序的输入管道中的项目更加令人困惑。

android android-camera android-camera2 video-encoding android-mediacodec
1个回答
0
投票

您不需要MediaExtractor-用于处理完整的容器文件并拆分其各种流和其他组件。

MediaCodec直接从摄像机接收原始图像缓冲区,并将输出编码的缓冲区。如果要保存标准视频文件,则需要将这些编码的ByteBuffer馈送到MediaMuxer实例中。如果您只是将编码后的缓冲区发送到其他地方以进行解码(例如视频聊天应用程序),则只需将ByteBuffers馈送到目的地的MediaCodec。

我无法说出您对MediaCodec的所有参数是否正确,但是我看不出任何明显错误的地方。

© www.soinside.com 2019 - 2024. All rights reserved.