Camera2 MediaRecorder changes Frame Rate on Galaxy S9

拜拜、爱过 提交于 2019-12-13 17:31:00

问题


I am not able to get a constant framerate with the camera2 API using MediaRecorder on the Galaxy S9 front camera.

Essentially I am using the example Project from https://github.com/googlesamples/android-Camera2Video but stripped it down to find the error. I removed the mTextureView and use only the mediaRecorder surface.

Here are the relevant code snippets:

@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() returns a Range of [30,30]. So it should record at 30fps. If I move the camera to some darker areas the frame rate suddenly drops. If locking the AE while moving to a light area the framerate is stable, even in dark areas.

So it seems to have something to do with AE but can not figure out what. Any help?

来源:https://stackoverflow.com/questions/54823902/camera2-mediarecorder-changes-frame-rate-on-galaxy-s9

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!