gpt4 book ai didi

android - 使用 cv::Mat 和 MediaCodec 在 Android 中编码视频

转载 作者:太空宇宙 更新时间:2023-11-03 12:34:33 24 4
gpt4 key购买 nike

我正在使用 Android 4.3 设备使用 cv::Mat 对视频进行编码。

我查看了 grafika hacksBigFrake samples ,我已经对它们进行了测试,它们正在运行。

我在 C++ 中有我的 cv::Mat,并且使用 JNI 我可以将一个缓冲区或缓冲区指针发送到我已经准备好的 Java 和编码器:

///////////////////////// Configure encoder
// QVGA at 2Mbps
mWidth = 320;
mHeight = 240;
mBitRate = 2000000;
//////////////////////////////////////

MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
if (codecInfo == null)
{
// Don't fail CTS if they don't have an AVC codec (not here, anyway).
Log.e(LOG_TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
}
if (VERBOSE) Log.d(LOG_TAG, "found codec: " + codecInfo.getName());

mBufferInfo = new MediaCodec.BufferInfo();

MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);

// Set some properties. Failing to specify some of these can cause the MediaCodec
// configure() call to throw an unhelpful exception.

format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
// format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
// format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 200);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); // PROBLEM: Color_formatSurface is the only want who works!!!!!
if (VERBOSE) Log.d(LOG_TAG, "format: " + format);

// Create a MediaCodec encoder, and configure it with our format.
//
mEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
//mInputSurface = new CodecInputSurface(mEncoder.createInputSurface()); // I don't want to use a surface
mEncoder.start();
inputBuffers = mEncoder.getInputBuffers();
outputBuffers = mEncoder.getOutputBuffers();

问题是,MediaFormat.KEY_COLOR_FORMAT 只接受 COLOR_FormatSurface 或 COLOR_FormatYUV420SemiPlanar,但我的数据是 RGB,没有表面元数据或 YUV。我已经尝试使用我可以使用的 3 编解码器:

//private static final String MIME_TYPE = "video/avc";    // H.264 Advanced Video Coding
//private static final String MIME_TYPE = "video/mp4v-es"; // Mp4
private static final String MIME_TYPE = "video/3gpp"; // 3gpp

1) 在这种情况下颜色格式有问题吗?我的意思是,是否可以直接使用,我必须使用 PixelBuffer 来伪造 COLOR_FormatSurface,或者将我的数据转换为 YUV?

2) 将数据从 cv::Mat.data 指针复制到 MediaCodec 缓冲区的最有效方法是什么?

更新 1:

  • 在提取 CV:Mat 之前,我有一个 FBO OpenGL。我认为另一种解决方案是在 InputSurface 中渲染 FBO 以直接使用 MediaCodec 对视频进行编码,而无需共享上下文。但是我没有找到将 FBO 从 OpenGL 上下文复制到 CodecInputSurface 的引用资料。

最佳答案

将 FBO 渲染到编解码器输入表面非常简单。您将需要 GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebuffer);
然后将 frameBuffer 的输出纹理 id 绑定(bind)到 mediacodec 上下文,即首先 makeCurrent,

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);

并使用类似于 mediacodec stufs 中存在的常规复制着色器,但没有 OES 纹理但具有 2D 纹理:例如

private static final String VERTEXT_SHADER =
"uniform mat4 uOrientationM;\n" +
"uniform mat4 uTransformM;\n" +
"attribute vec2 aPosition;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
"gl_Position = vec4(aPosition, 0.0, 1.0);\n" +
"vTextureCoord = (uTransformM * ((uOrientationM * gl_Position + 1.0) * 0.5)).xy;" +
"}";

private static final String FRAGMENT_SHADER =
"precision mediump float;\n" +
"uniform sampler2D sTexture;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
"gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}";

该副本的可行示例解决方案以及 FBO 初始化您可以在适用于 Android 的英特尔 INDE 示例中找到 https://software.intel.com/en-us/articles/intel-inde-media-pack-for-android-tutorials

关于android - 使用 cv::Mat 和 MediaCodec 在 Android 中编码视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23753932/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com