Постоянная поверхность ввода MediaCodec не поддерживается сеансом Camera2?

Я пишу приложение для Android, которое поддерживает сохранение RAW/JPEG и одновременную запись видео. Я пытался передать 4 поверхности при создании CameraCaptureSession: предварительный просмотр, 2x ImageSaver и 1x PersistentInputSurface, созданный MediaCodec#createPersistentInputSurface. Используя постоянную поверхность ввода, я намереваюсь избежать остановки между двумя захватами.

При создании сеанса происходит сбой:

W/CameraDevice-JV-0: Stream configuration failed due to: endConfigure:380: Camera 0: Unsupported set of inputs/outputs provided
Session 0: Failed to create capture session; configuration failed

Я пробовал убрать все остальные поверхности, оставив только PersistentInputSurface, все равно не получается.

 @Override
    public void onResume() {
        super.onResume();

        //Some other setups...

        if (persistentRecorderSurface == null) {
            persistentRecorderSurface = MediaCodec.createPersistentInputSurface();
        }

        startBackgroundThread();
        startCamera();

        if (mPreviewView.isAvailable()) {
            configureTransform(mPreviewView.getWidth(), mPreviewView.getHeight());
        } else {
            mPreviewView.setSurfaceTextureListener(mSurfaceTextureListener);
        }
        if (mOrientationListener != null && mOrientationListener.canDetectOrientation()) {
            mOrientationListener.enable();
        }
    }

    private void createCameraPreviewSessionLocked() {
        try {

            SurfaceTexture texture = mPreviewView.getSurfaceTexture();
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
            Surface surface = new Surface(texture);

            mPreviewRequestBuilder = mBackCameraDevice.createCaptureRequest(
                    CameraDevice.TEMPLATE_PREVIEW);
            mPreviewRequestBuilder.addTarget(surface);

            mBackCameraDevice.createCaptureSession(Arrays.asList(
                                surface,
                                mJpegImageReader.get().getSurface(),
                                mRAWImageReader.get().getSurface(),
                                persistentRecorderSurface
                        ), new CameraCaptureSession.StateCallback() {

                    @Override
                    public void onConfigured(CameraCaptureSession session) {
                        synchronized (mCameraStateLock) {
                            if (mBackCameraDevice == null) {
                                return;
                            }

                            try {
                                setup3AControlsLocked(mPreviewRequestBuilder);

                                session.setRepeatingRequest(mPreviewRequestBuilder.build(),
                                        mPreCaptureCallback, mBackgroundHandler);
                                mState = CameraStates.PREVIEW;
                            } catch (CameraAccessException | IllegalStateException e) {
                                e.printStackTrace();
                                return;
                            }

                            mSession = session;
                        }
                    }

                    @Override
                    public void onConfigureFailed(CameraCaptureSession session) {
                        showToast("Failed to configure camera.");
                    }
                }, mBackgroundHandler);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

1
0
992
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Было бы полезно увидеть строки системного журнала прямо перед этой строкой ошибки для подтверждения, но, скорее всего:

Вам нужно фактически связать persistRecorderSurface с МедиаРекордер или Медиакодек и вызвать для них prepare(), прежде чем создавать сеанс захвата камеры.

В противном случае на другом конце постоянной поверхности на самом деле ничего нет, и камера не может сказать, какое разрешение или другие параметры требуются.

Также имейте в виду, что существуют ограничения на количество одновременных выходов с камеры, в зависимости от поддерживаемого аппаратного уровня и возможностей. В настоящее время нет требования, чтобы устройство поддерживало вашу комбинацию выходов (предварительный просмотр, запись, JPEG, RAW), к сожалению, поэтому очень вероятно, что многие или все устройства по-прежнему будут выдавать вам ошибку.

Спасибо, @Эдди Талвала. Это решает мою проблему. Хотя у prepare() слишком много предпосылок. Например, OrientationHint нельзя определить, пока пользователь не нажмет кнопку «Пуск». Тем не менее, при запуске приложения я был вынужден prepare()MediaRecorder, иначе persistentInputSurface недостаточно квалифицирован для создания сеанса камеры. Кроме того, я отделил ImageSaver от MediaRecorder, так как это создает неожиданное поведение на разных устройствах.

Wangsta 26.04.2019 10:14

Другие вопросы по теме