Camera2 MediaRecorder меняет частоту кадров на Galaxy S9 - PullRequest
0 голосов
/ 22 февраля 2019

Я не могу получить постоянную частоту кадров с API-интерфейсом camera2, используя MediaRecorder на передней панели Galaxy S9 .

По сути, я использую пример Project от 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].Так что он должен записывать со скоростью 30 кадров в секунду.Если я перемещу камеру в более темные области, частота кадров внезапно падает.Если блокировка AE при перемещении в светлую область, частота кадров остается стабильной даже в темных областях.

Так что, похоже, что-то связано с AE, но не может понять, что именно.Любая помощь?

...