Android camera blurry screen_Analysis and solution of blurry screen and green screen in Android video recording

Life is too short, don't talk nonsense, don't do useless work

When we use android to develop video recording, we will encounter the phenomenon of recorded video blurry screen, green screen, etc. There is no doubt that 90% of it is because the color format of the video encoding does not match the encoding format configured by the encoder.

The data previewed by the camera is generally two kinds of NV21 and YV12. The following code can find out the preview format supported by the mobile phone:

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

Mobile MediaCodec codec color format is generally:

1、COLOR_FormatYUV420Planar

2、COLOR_FormatYUV420SemiPlanar

There are generally two color formats supported by YUV420Planar: NV21, NV12

There are generally two color formats supported by YUV420SemiPlanne: I420, YV12

The corresponding relationship is as follows:

I420: YYYYYYYY UU VV =>YUV420P

YV12: YYYYYYYY VV UU =>YUV420P

NV12: YYYYYYYY UVUV =>YUV420SP

NV21: YYYYYYYY VUVU =>YUV420SP

When previewing with the Camera camera:

The data format of the first parameter data here, if there is no special configuration, android returns the NV21 format by default, you can see the source code:

So if the camera supports YUV420SemiPlanne encoding format, then there is no problem with NV21 data, if not, then you need to convert the NV21 data format to the one supported by YUV420Planar

E.g:

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;

}

Also set the color coding format of mediaCodec:

mediaFormat_camera.setInteger(MediaFormat.KEY_COLOR_FORMAT,mColorFormat);

//mColorFormat can be MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar or MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar

If the camera supports YUV420SemiPlanne encoding format, then NV21 needs to be converted to NV12, otherwise an error will be reported

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];

}

}


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

Original link: https://blog.csdn.net/weixin_42510446/article/details/111902999

Guess you like

Origin blog.csdn.net/weixin_42602900/article/details/123654973