Pantalla borrosa de la cámara de Android_Análisis y solución de pantalla borrosa y pantalla verde en la grabación de video de Android

La vida es demasiado corta, no digas tonterías, no hagas trabajos inútiles.

Cuando usamos Android para desarrollar la grabación de video, nos encontraremos con el fenómeno de la pantalla borrosa del video grabado, la pantalla verde, etc. No hay duda de que el 90% se debe a que el formato de color de la codificación del video no coincide con el formato de codificación configurado. por el codificador.

Los datos de vista previa de la cámara son generalmente dos tipos de NV21 y YV12. El siguiente código puede encontrar el formato de vista previa compatible con el teléfono móvil:

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

El formato de color del códec Mobile MediaCodec es generalmente:

1、COLOR_FormatYUV420Planar

2, COLOR_FormatYUV420Semiplanar

En general, hay dos formatos de color compatibles con YUV420Planar: NV21, NV12

En general, hay dos formatos de color compatibles con YUV420SemiPlanne: I420, YV12

La relación correspondiente es la siguiente:

I420: YYYYYYYY UU VV =>YUV420P

YV12: YYYYYYYY VV UU =>YUV420P

NV12: YYYYYYYY UVUV =>YUV420SP

NV21: YYYYYYYY VUVU =>YUV420SP

Al obtener una vista previa con la cámara Cámara:

El formato de datos de los primeros datos de parámetros aquí, si no hay una configuración especial, Android devuelve el formato NV21 de forma predeterminada, puede ver el código fuente:

Entonces, si la cámara es compatible con el formato de codificación YUV420SemiPlanne, entonces no hay problema con los datos NV21; de lo contrario, debe convertir el formato de datos NV21 al compatible con YUV420Planar.

P.ej:

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;

}

Configure también el formato de codificación de colores de mediaCodec:

mediaFormat_camera.setInteger(MediaFormat.KEY_COLOR_FORMAT,mColorFormat);

//mColorFormat puede ser MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar o MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar

Si la cámara es compatible con el formato de codificación YUV420SemiPlanne, es necesario convertir NV21 a NV12; de lo contrario, se informará un error.

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

}

}


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

Enlace original: https://blog.csdn.net/weixin_42510446/article/details/111902999

Supongo que te gusta

Origin blog.csdn.net/weixin_42602900/article/details/123654973
Recomendado
Clasificación