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

      

     

     

     

  • 相关阅读:
    sencha touch 扩展篇之将sencha touch打包成安装程序(上)- 使用sencha cmd打包安装程序
    sencha touch 扩展篇之使用sass自定义主题样式 (下)通过css修改官方组件样式以及自定义图标
    一个不错的android组件的网站
    sencha touch 扩展篇之使用sass自定义主题样式 (上)使用官方的api修改主题样式
    sencha touch 入门系列 (九) sencha touch 布局layout
    面试题总结
    国外接活网站Elance, Freelancer和ScriptLance的介绍和对比
    sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩
    Android Design Support Library——Navigation View
    设计模式——命令模式
  • 原文地址:https://www.cnblogs.com/bimingcong/p/14082860.html
Copyright © 2011-2022 走看看