Tela borrada da câmera Android_Análise e solução de tela borrada e tela verde na gravação de vídeo Android

A vida é muito curta, não fale bobagens, não faça trabalhos inúteis

Quando usamos o Android para desenvolver a gravação de vídeo, encontraremos o fenômeno de tela desfocada de vídeo gravado, tela verde, etc. Não há dúvida de que 90% disso é porque o formato de cor da codificação de vídeo não corresponde ao formato de codificação configurado pelo codificador.

Os dados visualizados pela câmera geralmente são dois tipos de NV21 e YV12. O código a seguir pode descobrir o formato de visualização suportado pelo telefone celular:

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

O formato de cor do codec Mobile MediaCodec geralmente é:

1、COLOR_FormatYUV420Planar

2、COLOR_FormatYUV420SemiPlanar

Existem geralmente dois formatos de cores suportados pelo YUV420Planar: NV21, NV12

Geralmente, existem dois formatos de cores suportados pelo YUV420SemiPlanne: I420, YV12

A relação correspondente é a seguinte:

I420: YYYYYYYY UU VV =>YUV420P

YV12: YYYYYYYY VV UU =>YUV420P

NV12: YYYYYYYY UVUV =>YUV420SP

NV21: YYYYYYYY VUVU =>YUV420SP

Ao visualizar com a câmera Câmera:

O formato de dados dos dados do primeiro parâmetro aqui, se não houver configuração especial, o android retorna o formato NV21 por padrão, você pode ver o código-fonte:

Portanto, se a câmera suportar o formato de codificação YUV420SemiPlanne, não haverá problema com os dados NV21; caso contrário, você precisará converter o formato de dados NV21 para o formato suportado pelo YUV420Planar

Por exemplo:

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;

}

Defina também o formato de codificação de cores do mediaCodec:

mediaFormat_camera.setInteger(MediaFormat.KEY_COLOR_FORMAT,mColorFormat);

//mColorFormat pode ser MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar ou MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar

Se a câmera suportar o formato de codificação YUV420SemiPlanne, o NV21 precisa ser convertido para NV12, caso contrário, um erro será relatado

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

}

}


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

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

Acho que você gosta

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