selectColorFormat方法返回的颜色格式不正确

时间:2014-12-19 15:28:36

标签: android yuv mediacodec

我使用bigflake的selectColorFormat方法获得MediaCodec编码器支持的输入颜色格式。除了华为Mate7之外,它在某些测试设备上运行良好。返回的颜色格式为COLOR_FormatYUV420Planar。因此我将其配置为输入格式。但是在编码时我发现输入缓冲区的容量不正确,应该是3 *宽*高度/ 2.但是它是不是小于那个。当queueInputBuffer调用错误时发生。然后我观察了capabilities.colorFormats列表,它有十几种颜色格式。但在普通设备上,列表有大约2或3种颜色格式。然后我选择颜色格式为COLOR_FormatYUV420SemiPlanar,它也适用于Mate7。

所以我怀疑这是否是Mate7版本的bug或者selectColorFormat方法的错误?

我发现FAQ Q5的问题有:

#20 COLOR_FormatYUV420PackedPlanar (also I420)
#39 COLOR_FormatYUV420PackedSemiPlanar (also NV12)
#0x7f000100 COLOR_TI_FormatYUV420PackedSemiPlanar (also also NV12) 

I420和NV12的含义是什么?是否意味着I420或NV12的布局完全相同?因为我测试了I420和NV12,但是没有遇到这三种颜色设备

selectColorFormat方法如下:

private MediaCodecInfo selectCodec(String mimeType) {
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
        MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
        if (!codecInfo.isEncoder()) {
            continue;
        }
        String[] types = codecInfo.getSupportedTypes();
        for (int j = 0; j < types.length; j++) {
            if (types[j].equalsIgnoreCase(mimeType)) {
                return codecInfo;
            }
        }
    }
    return null;
}

private int selectColorFormat(String mimeType) {
    MediaCodecInfo codecInfo = selectCodec(mimeType);
    int colorFormat = 0;
    MediaCodecInfo.CodecCapabilities capabilities =  codecInfo.getCapabilitiesForType(mimeType);
    for (int i = 0; i < capabilities.colorFormats.length; i++) {

        if (isRecognizedFormat(capabilities.colorFormats[i])) {
            colorFormat = capabilities.colorFormats[i];
            break;
        }
    }

    return colorFormat; 
}

private boolean isRecognizedFormat(int colorFormat) {
    switch (colorFormat) {
    // these are the formats we know how to handle for this test
    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
    case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
    return true;
    default:
    return false;
    }
}

1 个答案:

答案 0 :(得分:1)

所有运行Android 4.3(API 18)或更高版本的设备都支持I420 or NV12 formats中的YUV输入。我可以自信地说出来,因为它们是所有“官方”Android设备必须通过的CTS测试的一部分。

编解码器返回的颜色常数具有多个映射到I420或NV12的值。您可以在bigflake示例代码中看到如何处理此问题(例如EncodeDecodeTest中的generateFrame())。

输入缓冲区容量应等于或略大于width * height * 3 / 2。如果遇到缓冲区溢出异常,请确保在将数据复制到其中之前clearing the buffer