我使用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;
}
}
答案 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。