自定义Camera提升帧率的方法

最近在做项目的时候,需要将Android camera的帧率尽可能提升到30帧/s,测试的过程发现一些特别的情况,camera api 1和camera api2,在不同手机平台上的表现还不相同。

Camera api 1

camera api1主要有以下两种提升帧率的方法:

  • 通过Camera.Parameters进行设置,主要有以下方法
    • setPreviewFpsRange(或setPreviewFrameRate)
    Camera.Parameters parameters = camera.getParameters();
    ···
    List fpsList = parameters.getSupportedPreviewFpsRange();
    if(fpsList != null && fpsList.size() > 0) {
        int[] maxFps = fpsList.get(0);
        for (int[] fps: fpsList) {
            if(maxFps[0] * maxFps[1] < fps[0] * fps[1]) {
                maxFps = fps;
            }
        }
        //注意setPreviewFpsRange的输入参数是帧率*1000,如30帧/s则参数为30*1000
        parameters.setPreviewFpsRange(maxFps[0] , maxFps[1]);
        //setPreviewFrameRate的参数是实际的帧率
        //parameters.setPreviewFrameRate(MAX_FPS);
    }
    
    • 测试发现,不进行任何帧率相关设置的时候,960P以上的分辨率已经会导致输出帧率降低,最低的时候仅有10帧/s,480P的输出帧率还是接近30帧/s。这种情况下, 如果想要达到更大的帧率,例如960P的时候需要将帧率提高至30帧/s,采用setPreviewFpsRange(或setPreviewFrameRate)的方法已经不起作用了,这种方法只能起到限制帧率的效果,如果需要将帧率提到最大,需要采用以下方法
      • setRecordingHint
      Camera.Parameters parameters = camera.getParameters();
      ···
      parameters.setRecordingHint(true);
      
      • 官方文档对该api的注释如下:
        Sets recording mode hint. This tells the camera that the intent of the application is to record videos MediaRecorder.start(), not to take still pictures Camera.takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback). Using this hint can allow MediaRecorder.start() to start faster or with fewer glitches on output. This should be called before starting preview for the best result, but can be changed while the preview is active. The default value is false. The app can still call takePicture() when the hint is true or call MediaRecorder.start() when the hint is false. But the performance may be worse.
        大致的意思就是让相机一直运行在视频采集的状态下,由于视频采集的时候一般需要高帧率才能保证数据的完整,所以该状态下的输出帧率会保持在能达到的最大帧率

Camera api 2

  • 使用Camera api 2之前要注意,查看下设备对于Camera api的支持级别
    characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
    //CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2
    //CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3
    //CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0
    //CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1
    //LEGACY < LIMITED < FULL < LEVEL_3
    
    具体关于支持级别的内容可以查看官方文档。但是根据网上查找的资料以及现有设备的测试,发现市面上很多品牌的手机对于camera api 2的支持都是低级别的,也就是上述的LEGACY,这种情况下使用camera api 2的相机效果有可能还不如camera api 1的,所以使用的时候得考虑到这些情况。
    • 设置帧率
    Range[] fpsRange = characteristics.get(
        CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
        if(fpsRange != null && fpsRange.length > 0) {
        Range maxFps = fpsRange[0];
        for (Range aFpsRange : fpsRange) {
            if (maxFps.getLower() * maxFps.getUpper() < aFpsRange.getLower() * aFpsRange.getUpper()) {
                maxFps = aFpsRange;
            }
        }
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, maxFps);
    }
    
    • 在使用上述帧率设置之后,发现在不同的手机平台上的表现效果还不一致。手头上一台高通自研的测试手机能达到近乎30帧/s,自己的红米Note 5只有十几帧,另一台测试用的华为手机则有二十几帧,后两台手机的支持级别都为LEGACY。并不清楚具体的原因。。

你可能感兴趣的:(Android)