如何获得MediaCodec编码器的步幅和Y平面对齐值 [英] How to get stride and Y plane alignment values for MediaCodec encoder

查看:366
本文介绍了如何获得MediaCodec编码器的步幅和Y平面对齐值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关这个问题的一些相关问题和讨论:

There's a few related questions and discussions on this subject:

  • Mediacodec and camera, color space incorrect
  • Getting QualComm encoders to work via MediaCodec API
  • https://groups.google.com/d/msg/android-platform/awaNwgb6EbY/a-YiIOwaL0QJ
  • https://code.google.com/p/android/issues/detail?id=37769

我正在将相机预览框( NV21 转换为 NV12 )加载到 MediaCodec encoder( NV12 aka COLOR_FormatYUV420SemiPl ANAR )。看起来像在某些具有 QualComm 编码器的设备上,运行Android版本小于 4.3 我必须做一些输入框架处理以便以正确的颜色接收回帧。

I am feeding camera preview frames (NV21 converted to NV12) to MediaCodec encoder (NV12 aka COLOR_FormatYUV420SemiPlanar). It looks like that on some devices with QualComm encoder which are running Android versions less than 4.3 I have to do some input frames processing in order to receive back frame with correct color.

On Sony Xperia ZR running Android 4.2.2 我必须添加 Y 平面对齐,以使其处理几乎所有的分辨率。上面的代码为不能被 32 2048 的宽度添加 1024 / code>其他分辨率的字节对齐。它使 MediaCodec 正确编码所有可以除以 16 176x144 其中 UV 飞机看起来不一致)。

On Sony Xperia ZR running Android 4.2.2 I have to add Y plane alignment in order to make it working on almost all resolutions. Code above adds 1024 bytes alignment for widths which can not be divided by 32 and 2048 bytes alignment for other resolutions. It makes MediaCodec to encode frames properly for all resolutions which can be divided by 16 (except 176x144 for which UV plane looks misaligned).

int getYPadding() {
    if (mediaCodecInfo.getName().contains("OMX.qcom") && android.os.Build.VERSION.SDK_INT < 18) {
        if ((getWidth() % 32) != 0) {
            return (getWidth()*getHeight()) % 1024;
        } else {
            return (getWidth()*getHeight()) % 2048;
        }
    }
    return 0;
}

我试图在 LG上测试这个对齐方式G2 运行相同的 Android 4.2.2 ,并具有 QualComm 编码器,它看起来喜欢它不正确的工作。 UV 平面未对齐(框架底部的绿色条纹)。我无法计算两个手机的填充。

I've tried to test this alignment on LG G2 which is running same Android 4.2.2 and has QualComm encoder, and it looks like it does not working on it correctly. UV plane is misaligned (a green stripe at the bottom of the frame). I was not able to calculate the padding which will work for both phones.

我还可以访问 Sony Xperia Z1 运行 Android 4.3 QualComm 芯片组,它看起来没有这样的问题。每个分辨率的视频看起来都很好, Y 飞机不需要对齐。

I also have access to Sony Xperia Z1 running Android 4.3 with QualComm chipset and it looks like it does not have such problems. Video on every resolution looks fine and Y plane does not needs to be aligned anyhow.

我知道它是硬件相关并且可能很复杂,但是由于我必须支持在 4.3 之前运行Android的用户,我有一个问题。编码器对于给定的颜色格式可以编程确定 Y 平面对齐和垂直/水平步幅值?

I understand that it's hardware-related and might be complicated, but since I have to support users running Android prior to 4.3 I have a question. Is it possible to programmatically determine Y plane alignment and vertical / horizontal stride values which encoder is expecting for the given color format?

推荐答案

简而言之,问题是:没有 CTS测试用于视频编码,直到Android 4.3(API 18)。

The problem in a nutshell: there were no CTS tests for video encoding until Android 4.3 (API 18).

因此, MediaCodec 的行为不同的设备不一致,并且几个错误被忽视。 EncodeDecodeTest 测试执行您要查询的功能,因此您可以将YUV数据可靠地馈送到4.3以上的设备(虽然您仍然需要运行时检测是否需要平面或半平面)。

As a result, the behavior of MediaCodec across different devices was inconsistent, and a few bugs went unnoticed. The EncodeDecodeTest tests exercise the functions you're asking about, and as a result you can reliably feed YUV data to a 4.3+ device (though you still have to runtime-detect whether it wants planar or semi-planar).

对于您的具体问题,较旧的Qualcomm设备上的Y平面需要对齐在2K边界,这不是你的代码正在做什么。对于720p视频,这会自然发生(720 * 1280 == 450 * 2048),对于176x144,您可以调整1280以在26624而不是25344启动UV平面。您需要在缓冲区内设置绝对对齐方式,而不是固定的填充量 - 使用 uvoffset =(width * height + 2047)& 〜2047

For your specific question, the Y plane on older Qualcomm devices needs to be aligned at a 2K boundary, which isn't quite what your code is doing. For 720p video this happens naturally (720*1280 == 450 * 2048), for 176x144 you'd adjust by 1280 to start the UV plane at 26624 instead of 25344. You need to set the absolute alignment within the buffer, not a fixed amount of padding -- use uvoffset = (width*height + 2047) & ~2047.

您需要检测编解码器供应商和Android软件版本,如果是4.3之前的高通,则需要进行这个调整。如果您的需求发生变化,并且您可以针对API 18+,这些问题就会消失。 (您可以使用 Surface 输入到 MediaCodec ,这样可以避免U / V交换问题,尽管取决于您的需要这可能不是有用的。)

You will need to detect the codec vendor and Android software version, and if it's Qualcomm on pre-4.3 you need to make this adjustment. If your requirements change, and you can target API 18+, these issues go away. (And you can use Surface input to MediaCodec, which avoids the U/V swap issue, though depending on your needs that may not be useful.)

这篇关于如何获得MediaCodec编码器的步幅和Y平面对齐值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆