Camera2 MediaRecorder更改Galaxy S9的帧频

时间:2019-02-22 09:28:25

标签: android android-camera2 mediarecorder android-mediarecorder

在Galaxy S9 前置相机上,使用MediaRecorder的camera2 API无法获得恒定的帧速率。

本质上,我正在使用https://github.com/googlesamples/android-Camera2Video中的示例项目,但将其剥离下来以查找错误。我删除了mTextureView,仅使用mediaRecorder表面。

以下是相关的代码段:

@Override
protected void setUpMediaRecorder() throws IOException {
    final Activity activity = getActivity();
    if (null == activity) {
        return;
    }
    // Camcorder Profile QUALITY_HIGH doenst work
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

    mMediaRecorder.setVideoEncodingBitRate(30000000);
    mMediaRecorder.setVideoFrameRate(30);
    mMediaRecorder.setVideoSize(2560, 1440);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
    mMediaRecorder.prepare();
}


@Override
protected void setUpCaptureRequestBuilder(CaptureRequest.Builder builder) {
    Range<Integer> range = getRange();
    builder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, range);
}

// get highest range
private Range<Integer> getRange() {
    CameraManager mCameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
    CameraCharacteristics chars = null;
    try {
        chars = mCameraManager.getCameraCharacteristics(mCameraManager.getCameraIdList()[1]);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
    Range<Integer>[] ranges = chars.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);

    Range<Integer> result = null;

    for (Range<Integer> range : ranges) {
        if (result == null) {
            result = range;
        } else {
            int upper = range.getUpper();
            int lower = range.getLower();
            if (upper >= result.getUpper() && lower >= result.getLower()) {
                result = range;
            }
        }
    }
    return result;
}

protected void startRecordingVideo() {
    if (null == mCameraDevice) {
        return;
    }
    try {
        closeCaptureSession();
        setUpMediaRecorder();
        mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
        List<Surface> surfaces = new ArrayList<>();

        // Set up Surface for the MediaRecorder
        Surface recorderSurface = mMediaRecorder.getSurface();
        surfaces.add(recorderSurface);
        mPreviewBuilder.addTarget(recorderSurface);

        // Start a capture session
        // Once the session starts, we can update the UI and start recording
        mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {

            @Override
            public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                mCaptureSession = cameraCaptureSession;
                setUpCaptureRequestBuilder(mPreviewBuilder);

                if (null == mCameraDevice) {
                    return;
                }
                try {
                    mCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }

                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // UI
                        mButtonVideo.setText(R.string.stop);
                        mIsRecordingVideo = true;

                        // Start recording
                        mMediaRecorder.start();
                    }
                });
            }

            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
                Activity activity = getActivity();
                if (null != activity) {
                    Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show();
                }
            }
        }, mBackgroundHandler);
    } catch (CameraAccessException | IOException e) {
        e.printStackTrace();
    }

}

getRange()返回范围[30,30]。因此它应该以30fps的速度录制。如果将相机移至较暗的区域,则帧速率会突然下降。如果在移动到明亮区域时锁定AE,则即使在黑暗区域中,帧率也保持稳定。

因此,它似乎与AE有关,但无法弄清楚是什么。有帮助吗?

0 个答案:

没有答案