如何获得MediaCodec编码器的步幅和Y平面对齐值

And*_*nih 4 encoding android mediacodec

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

我正在将相机预览帧(NV21转换为NV12)提供给MediaCodec编码器(NV12aka COLOR_FormatYUV420SemiPlanar).看起来在某些带有QualComm编码器的设备上运行Android版本比4.3我必须做一些输入帧处理以便接收具有正确颜色的背帧.

Sony Xperia ZR运行时,Android 4.2.2我必须添加Y平面对齐,以使其适用于几乎所有分辨率.上面的代码添加1024字节对准为宽度不能被分割32,并2048为其他分辨率字节对准.它可以MediaCodec对所有可以除以的分辨率正确编码帧16(除了176x144哪个UV平面看起来不对齐).

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;
}
Run Code Online (Sandbox Code Playgroud)

我试图测试这个LG G2运行相同Android 4.2.2且具有QualComm编码器的对齐,看起来它没有正确地工作.UV平面未对齐(框架底部的绿色条纹).我无法计算适用于这两款手机的填充.

我也可以使用芯片组Sony Xperia Z1运行Android 4.3,QualComm看起来它没有这样的问题.每个分辨率的视频都很好,Y无论如何都不需要对齐平面.

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

fad*_*den 7

问题简而言之:在Android 4.3(API 18)之前,没有针对视频编码的CTS测试.

结果,MediaCodec跨不同设备的行为不一致,并且一些错误被忽视.该EncodeDecodeTest测试锻炼你问的功能,因此你可以YUV数据可靠地喂到4.3以上版本的设备(虽然你还是要运行时检测是否愿意平面或半平面).

对于您的特定问题,较旧的Qualcomm设备上的Y平面需要在2K边界处对齐,这与您的代码不同.对于720p视频,这种情况自然发生(720*1280 == 450*2048),对于176x144,您需要调整1280以在26624而不是25344处启动UV平面.您需要在缓冲区内设置绝对对齐,而不是固定填充量 - 使用uvoffset = (width*height + 2047) & ~2047.

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