zoukankan      html  css  js  c++  java
  • Android视频录制 花屏、绿屏的分析及解决方案

          人生苦短,不说废话,不做无用功      

          当我们在用android 开发视频录制时候,会遇到录制出来的视频 花屏、绿屏等现象,不用怀疑,90%是因为视频编码时候的颜色格式和编码器配置的编码格式不匹配。

    相机预览的数据一般是两种 NV21和YV12,以下代码可以查出手机支持的预览格式:

    List<Integer> previewFormats = mCamera.getParameters().getSupportedPreviewFormats();
    

    手机MediaCodec编解码颜色格式一般为:

    1、COLOR_FormatYUV420Planar
    2、COLOR_FormatYUV420SemiPlanar

    YUV420Planar支持的颜色格式一般也有两种:NV21、NV12

    YUV420SemiPlanne支持的颜色格式一般也有两种:I420、YV12

    对应关系如下:

    I420: YYYYYYYY UU VV =>YUV420P
    YV12: YYYYYYYY VV UU =>YUV420P
    NV12: YYYYYYYY UVUV =>YUV420SP
    NV21: YYYYYYYY VUVU =>YUV420SP

    用Camera摄像头预览的时候:

    这里第一个参数data的数据格式,如果没有特殊配置,android默认返回的是NV21格式,查看源码可以看到:

    所以如果相机支持YUV420SemiPlanne编码格式,那么NV21数据时没问题的,如果不支持那么需要将NV21的数据格式转为YUV420Planar所支持的

    例如:

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

      同时设置mediaCodec的颜色编码格式:

    mediaFormat_camera.setInteger(MediaFormat.KEY_COLOR_FORMAT,mColorFormat);
    //mColorFormat可以是 MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar 或者 MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar
    

      

        如果相机支持YUV420SemiPlanne编码格式,那么NV21需要转为NV12 否则会报错

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

      

     

     

     

  • 相关阅读:
    第一讲 递归与循环3
    第一讲 递归与循环2
    第一讲 递归与循环1
    [转]批处理
    VBA运算符(九)
    VBA常量(八)
    VBA变量(七)
    VBA输入框(InputBox)(六)
    VBA消息框(MsgBox)(五)
    VBA宏注释(四)
  • 原文地址:https://www.cnblogs.com/bimingcong/p/14082860.html
Copyright © 2011-2022 走看看