NV21 旋转+转为NV12

yuv420sp的分两种,nv21和nv12。Android 取摄像头中的数据 ,当使用camera1.0 时,onPreviewFrame返回的数据yuv420sp的nv21,并且camera中取出的数据显示时是偏转的,需要将其旋转顺时针旋转270或逆时针旋转90,注:旋转后宽高对调

/**
 * 此处为顺时针旋转270
 * @param data 旋转前的数据
 * @param imageWidth 旋转前数据的宽
 * @param imageHeight 旋转前数据的高
 * @return 旋转后的数据
 */
private byte[] rotateYUV420Degree270(byte[] data, int imageWidth, int imageHeight){

    byte[] yuv =new byte[imageWidth*imageHeight*3/2];

    // Rotate the Y luma

    int i =0;

    for(int x = imageWidth-1;x >=0;x--){

        for(int y =0;y < imageHeight;y++){

            yuv[i]= data[y*imageWidth+x];
            i++;

        }
    }// Rotate the U and V color components
    i = imageWidth*imageHeight;

    for(int x = imageWidth-1;x >0;x=x-2){

        for(int y =0;y < imageHeight/2;y++){
            yuv[i]= data[(imageWidth*imageHeight)+(y*imageWidth)+(x-1)];
            i++;
            yuv[i]= data[(imageWidth*imageHeight)+(y*imageWidth)+x];
            i++;

        }

    }

    return yuv;

}
/**
 * 此处为顺时针旋转旋转90度
 * @param data 旋转前的数据
 * @param imageWidth 旋转前数据的宽
 * @param imageHeight 旋转前数据的高
 * @return 旋转后的数据
 */
private byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight)
{
    byte [] yuv = new byte[imageWidth*imageHeight*3/2];
    // Rotate the Y luma
    int i = 0;
    for(int x = 0;x < imageWidth;x++)
    {
        for(int y = imageHeight-1;y >= 0;y--)
        {
            yuv[i] = data[y*imageWidth+x];
            i++;
        }
    }
    // Rotate the U and V color components
    i = imageWidth*imageHeight*3/2-1;
    for(int x = imageWidth-1;x > 0;x=x-2)
    {
        for(int y = 0;y < imageHeight/2;y++)
        {
            yuv[i] = data[(imageWidth*imageHeight)+(y*imageWidth)+x];
            i--;
            yuv[i] = data[(imageWidth*imageHeight)+(y*imageWidth)+(x-1)];
            i--;
        }
    }
    return yuv;
}

顺时针旋转180度

private byte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight){

    byte[] yuv =new byte[imageWidth*imageHeight*3/2];

    int i =0;int count =0;

    for(i = imageWidth * imageHeight -1; i >=0; i--){
        yuv[count]= data[i];
        count++;}

    i = imageWidth * imageHeight *3/2-1;for(i = imageWidth * imageHeight *3/2-1; i >= imageWidth
            * imageHeight; i -=2){
        yuv[count++]= data[i -1];
        yuv[count++]= data[i]; 
    }return yuv;
}

用mediacode编码h264时,因为mediacode编码视频只支持yuv420sp的nv12,需要将nv21转为nv12

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

 

 

你可能感兴趣的:(NV21 旋转+转为NV12)