【问题标题】:If is it possible to get BGR from MediaCodec?是否可以从 MediaCodec 获得 BGR?
【发布时间】:2019-07-28 06:03:17
【问题描述】:

据我所知,MediaCodecYUV420 中返回图像的输出缓冲区,然后您可以随意处理它...但在我的情况下,我需要将YUV420 转换为BGR ,这是相当昂贵的转换。

所以,问题是是否可以立即(无需转换)从MediaCodec 获得BGR

我现在的代码

uint8_t *buf = AMediaCodec_getOutputBuffer(m_data.codec, static_cast<size_t>(status), /*bufsize*/nullptr);
cv::Mat YUVframe(cv::Size(m_frameSize.width, static_cast<int>(m_frameSize.height * 1.5)), CV_8UC1, buf);

cv::Mat colImg(m_frameSize, CV_8UC3);
cv::cvtColor(YUVframe, colImg, CV_YUV420sp2BGR, 3);
auto dataSize = colImg.rows * colImg.cols * colImg.channels();
imageData.assign(colImg.data, colImg.data + dataSize);

所以,你可以在这里看到

cv::Mat YUVframe(cv::Size(m_frameSize.width, static_cast<int>(m_frameSize.height * 1.5)), CV_8UC1, buf);

我从编解码器缓冲区获取YUVframe,然后在这里

cv::cvtColor(YUVframe, colImg, CV_YUV420sp2BGR, 3);

我进行转换

转换需要很长时间。对我来说,性能至关重要。

【问题讨论】:

    标签: android android-mediacodec


    【解决方案1】:

    MediaCodec 以编解码器喜欢的任何格式输出帧。大多数数码相机和视频编解码器都使用 YUV 格式的帧。捕获静止图像时,相机需要使用两种特定格式中的一种,但 MediaCodec 更像是免费的。如果您希望数据采用特定格式,则必须进行转换。

    在 Android 上,您可以通过 GPU 让硬件为您完成这项工作,这是接受 MediaCodec 决定在该设备上生成的任何格式所必需的。您通过将每一帧输入到 SurfaceTexture 中将其锁定为“外部”纹理,然后告诉 GLES 在 pbuffer 上以 RGB 呈现它,然后您可以以不同的方式访问它。有关使用glReadPixels() 的示例,请参阅ExtractMpegFramesTest

    glReadPixels() 的替代方案依赖私有本机方法来访问 pbuffer(例如 thisthis),但除非您完全控制设备,否则使用非公共 API 是不明智的。

    可能有一些更新的方法可以访问我没有使用过的 pbuffer,例如使用 native hardware buffers 似乎很有用 (or maybe not?)。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多