android 摄像头花屏_Android视频录制 花屏、绿屏的分析及解决方案

人生苦短,不说废话,不做无用功

当我们在用android 开发视频录制时候,会遇到录制出来的视频 花屏、绿屏等现象,不用怀疑,90%是因为视频编码时候的颜色格式和编码器配置的编码格式不匹配。

相机预览的数据一般是两种 NV21和YV12,以下代码可以查出手机支持的预览格式:

List previewFormats = mCamera.getParameters().getSupportedPreviewFormats();

手机MediaCodec编解码颜色格式一般为:

1、COLOR_FormatYUV420Planar

2、COLOR_FormatYUV420SemiPlanar

YUV420Planar支持的颜色格式一般也有两种:NV21、NV12

YUV420SemiPlanne支持的颜色格式一般也有两种:I420、YV12

对应关系如下:

I420: YYYYYYYY UU VV =>YUV420P

扫描二维码关注公众号,回复: 13725389 查看本文章

YV12: YYYYYYYY VV UU =>YUV420P

NV12: YYYYYYYY UVUV =>YUV420SP

NV21: YYYYYYYY VUVU =>YUV420SP

用Camera摄像头预览的时候:

这里第一个参数data的数据格式,如果没有特殊配置,android默认返回的是NV21格式,查看源码可以看到:

所以如果相机支持YUV420SemiPlanne编码格式,那么NV21数据时没问题的,如果不支持那么需要将NV21的数据格式转为YUV420Planar所支持的

例如:

public final static int NV21_TO_yuv420P(byte[] dst, byte[] src, int w, int h){
int ysize = w * h;

int usize = w * h * 1 / 4;

byte[] dsttmp = dst;

// y

System.arraycopy(src, 0, dst, 0, ysize);

// u, 1/4

int srcPointer = ysize;

int dstPointer = ysize;

int count = usize;

while (count > 0)

{
srcPointer++;

dst[dstPointer] = src[srcPointer];

dstPointer++;

srcPointer++;

count--;

}

// v, 1/4

srcPointer = ysize;

count = usize;

while (count > 0)

{
dst[dstPointer] = src[srcPointer];

dstPointer++;

srcPointer += 2;

count--;

}

dst = dsttmp;

// _EF_TIME_DEBUG_END(0x000414141);

return 0;

}

同时设置mediaCodec的颜色编码格式:

mediaFormat_camera.setInteger(MediaFormat.KEY_COLOR_FORMAT,mColorFormat);

//mColorFormat可以是 MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar 或者 MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar

如果相机支持YUV420SemiPlanne编码格式,那么NV21需要转为NV12 否则会报错

public static void NV21ToNV12(byte[] nv21,byte[] nv12,int width,int height) {
if (nv21 ==null || nv12 ==null)return;

int framesize = width * height;

int i =0, j =0;

System.arraycopy(nv21,0, nv12,0, framesize);

for (i =0; i < framesize; i++) {
nv12[i] = nv21[i];

}

for (j =0; j < framesize /2; j +=2) {
nv12[framesize + j -1] = nv21[j + framesize];

}

for (j =0; j < framesize /2; j +=2) {
nv12[framesize + j] = nv21[j + framesize -1];

}

}


————————————————

原文链接:https://blog.csdn.net/weixin_42510446/article/details/111902999

猜你喜欢

转载自blog.csdn.net/weixin_42602900/article/details/123654973