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