From 5fbe0ba24d88910e68610add74fd1e1b94d282b5 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Fri, 20 Oct 2017 15:45:45 +0100 Subject: [PATCH] Camera: Add support for session parameters The initial values of the session-wide capture parameters should be passed along the stream list during stream configuration. This could yield performance gains depending on the Hal implementation and support. Bug: 64450664 Test: Camera CTS Change-Id: I2b0ec8916f027e7f34f81dc414c3ca649807e925 --- .../hardware/camera2/ICameraDeviceUser.aidl | 3 +- camera/ndk/NdkCameraDevice.cpp | 18 +++- camera/ndk/impl/ACameraDevice.cpp | 14 ++- camera/ndk/impl/ACameraDevice.h | 7 +- camera/ndk/impl/ACameraMetadata.cpp | 2 +- camera/ndk/impl/ACameraMetadata.h | 2 +- camera/ndk/include/camera/NdkCameraDevice.h | 33 +++++++ .../include/camera/NdkCameraMetadataTags.h | 53 ++++++++++ camera/ndk/libcamera2ndk.map.txt | 1 + camera/tests/CameraBinderTests.cpp | 5 +- services/camera/libcameraservice/Android.mk | 3 +- .../api2/CameraDeviceClient.cpp | 5 +- .../api2/CameraDeviceClient.h | 3 +- .../common/CameraDeviceBase.h | 3 +- .../device3/Camera3Device.cpp | 98 ++++++++++++++----- .../libcameraservice/device3/Camera3Device.h | 12 ++- 16 files changed, 218 insertions(+), 44 deletions(-) diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl index 07d4e7ee35..4ced08c229 100644 --- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl +++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl @@ -79,8 +79,9 @@ interface ICameraDeviceUser *

* @param operatingMode The kind of session to create; either NORMAL_MODE or * CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value. + * @param sessionParams Session wide camera parameters */ - void endConfigure(int operatingMode); + void endConfigure(int operatingMode, in CameraMetadataNative sessionParams); void deleteStream(int streamId); diff --git a/camera/ndk/NdkCameraDevice.cpp b/camera/ndk/NdkCameraDevice.cpp index ac4beeae32..812a312c54 100644 --- a/camera/ndk/NdkCameraDevice.cpp +++ b/camera/ndk/NdkCameraDevice.cpp @@ -220,5 +220,21 @@ camera_status_t ACameraDevice_createCaptureSession( __FUNCTION__, device, outputs, callbacks, session); return ACAMERA_ERROR_INVALID_PARAMETER; } - return device->createCaptureSession(outputs, callbacks, session); + return device->createCaptureSession(outputs, nullptr, callbacks, session); +} + +EXPORT +camera_status_t ACameraDevice_createCaptureSessionWithSessionParameters( + ACameraDevice* device, + const ACaptureSessionOutputContainer* outputs, + const ACaptureRequest* sessionParameters, + const ACameraCaptureSession_stateCallbacks* callbacks, + /*out*/ACameraCaptureSession** session) { + ATRACE_CALL(); + if (device == nullptr || outputs == nullptr || callbacks == nullptr || session == nullptr) { + ALOGE("%s: Error: invalid input: device %p, outputs %p, callbacks %p, session %p", + __FUNCTION__, device, outputs, callbacks, session); + return ACAMERA_ERROR_INVALID_PARAMETER; + } + return device->createCaptureSession(outputs, sessionParameters, callbacks, session); } diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp index 45fa28ef9b..4bb82cb3a3 100644 --- a/camera/ndk/impl/ACameraDevice.cpp +++ b/camera/ndk/impl/ACameraDevice.cpp @@ -157,6 +157,7 @@ CameraDevice::createCaptureRequest( camera_status_t CameraDevice::createCaptureSession( const ACaptureSessionOutputContainer* outputs, + const ACaptureRequest* sessionParameters, const ACameraCaptureSession_stateCallbacks* callbacks, /*out*/ACameraCaptureSession** session) { sp currentSession = mCurrentSession.promote(); @@ -172,7 +173,7 @@ CameraDevice::createCaptureSession( } // Create new session - ret = configureStreamsLocked(outputs); + ret = configureStreamsLocked(outputs, sessionParameters); if (ret != ACAMERA_OK) { ALOGE("Fail to create new session. cannot configure streams"); return ret; @@ -434,7 +435,7 @@ CameraDevice::notifySessionEndOfLifeLocked(ACameraCaptureSession* session) { } // No new session, unconfigure now - camera_status_t ret = configureStreamsLocked(nullptr); + camera_status_t ret = configureStreamsLocked(nullptr, nullptr); if (ret != ACAMERA_OK) { ALOGE("Unconfigure stream failed. Device might still be configured! ret %d", ret); } @@ -598,7 +599,8 @@ CameraDevice::getSurfaceFromANativeWindow( } camera_status_t -CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs) { +CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outputs, + const ACaptureRequest* sessionParameters) { ACaptureSessionOutputContainer emptyOutput; if (outputs == nullptr) { outputs = &emptyOutput; @@ -694,7 +696,11 @@ CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outpu mConfiguredOutputs.insert(std::make_pair(streamId, outputPair)); } - remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false); + CameraMetadata params; + if ((sessionParameters != nullptr) && (sessionParameters->settings != nullptr)) { + params.append(sessionParameters->settings->getInternalData()); + } + remoteRet = mRemote->endConfigure(/*isConstrainedHighSpeed*/ false, params); if (remoteRet.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) { ALOGE("Camera device %s cannnot support app output configuration: %s", getId(), remoteRet.toString8().string()); diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h index 23cc1a1283..560860663b 100644 --- a/camera/ndk/impl/ACameraDevice.h +++ b/camera/ndk/impl/ACameraDevice.h @@ -60,6 +60,7 @@ class CameraDevice final : public RefBase { camera_status_t createCaptureSession( const ACaptureSessionOutputContainer* outputs, + const ACaptureRequest* sessionParameters, const ACameraCaptureSession_stateCallbacks* callbacks, /*out*/ACameraCaptureSession** session); @@ -139,7 +140,8 @@ class CameraDevice final : public RefBase { // For capture session to notify its end of life void notifySessionEndOfLifeLocked(ACameraCaptureSession* session); - camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs); + camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs, + const ACaptureRequest* sessionParameters); // Input message will be posted and cleared after this returns void postSessionMsgAndCleanup(sp& msg); @@ -309,9 +311,10 @@ struct ACameraDevice { camera_status_t createCaptureSession( const ACaptureSessionOutputContainer* outputs, + const ACaptureRequest* sessionParameters, const ACameraCaptureSession_stateCallbacks* callbacks, /*out*/ACameraCaptureSession** session) { - return mDevice->createCaptureSession(outputs, callbacks, session); + return mDevice->createCaptureSession(outputs, sessionParameters, callbacks, session); } /*********************** diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp index 7b33c32ce6..29ad09bc60 100644 --- a/camera/ndk/impl/ACameraMetadata.cpp +++ b/camera/ndk/impl/ACameraMetadata.cpp @@ -235,7 +235,7 @@ ACameraMetadata::getTags(/*out*/int32_t* numTags, } const CameraMetadata& -ACameraMetadata::getInternalData() { +ACameraMetadata::getInternalData() const { return mData; } diff --git a/camera/ndk/impl/ACameraMetadata.h b/camera/ndk/impl/ACameraMetadata.h index 143efc7e12..0fd7efa163 100644 --- a/camera/ndk/impl/ACameraMetadata.h +++ b/camera/ndk/impl/ACameraMetadata.h @@ -64,7 +64,7 @@ struct ACameraMetadata : public RefBase { void filterUnsupportedFeatures(); // Hide features not yet supported by NDK void filterStreamConfigurations(); // Hide input streams, translate hal format to NDK formats - const CameraMetadata& getInternalData(); + const CameraMetadata& getInternalData() const; template camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) { diff --git a/camera/ndk/include/camera/NdkCameraDevice.h b/camera/ndk/include/camera/NdkCameraDevice.h index 3a6f3ef855..61deb4647a 100644 --- a/camera/ndk/include/camera/NdkCameraDevice.h +++ b/camera/ndk/include/camera/NdkCameraDevice.h @@ -720,6 +720,39 @@ camera_status_t ACaptureSessionSharedOutput_add(ACaptureSessionOutput *output, A camera_status_t ACaptureSessionSharedOutput_remove(ACaptureSessionOutput *output, ANativeWindow* anw); +/** + * Create a new camera capture session similar to {@link ACameraDevice_createCaptureSession}. This + * function allows clients to pass additional session parameters during session initialization. For + * further information about session parameters see {@link ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS}. + * + * @param device the camera device of interest. + * @param outputs the {@link ACaptureSessionOutputContainer} describes all output streams. + * @param sessionParameters An optional capture request that contains the initial values of session + * parameters advertised in + * {@link ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS}. + * @param callbacks the {@link ACameraCaptureSession_stateCallbacks} + * capture session state callbacks. + * @param session the created {@link ACameraCaptureSession} will be filled here if the method call + * succeeds. + * + * @return

+ */ +camera_status_t ACameraDevice_createCaptureSessionWithSessionParameters( + ACameraDevice* device, + const ACaptureSessionOutputContainer* outputs, + const ACaptureRequest* sessionParameters, + const ACameraCaptureSession_stateCallbacks* callbacks, + /*out*/ACameraCaptureSession** session); + #endif /* __ANDROID_API__ >= 28 */ __END_DECLS diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h index 4f893f1d6a..80d460fc05 100644 --- a/camera/ndk/include/camera/NdkCameraMetadataTags.h +++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h @@ -2877,6 +2877,59 @@ typedef enum acamera_metadata_tag { */ ACAMERA_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS = // int32[n] ACAMERA_REQUEST_START + 15, + /** + *

A subset of the available request keys that the camera device + * can pass as part of the capture session initialization.

+ * + *

Type: int32[n]

+ * + *

This tag may appear in: + *

+ * + *

This is a subset of ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS which + * contains a list of keys that are difficult to apply per-frame and + * can result in unexpected delays when modified during the capture session + * lifetime. Typical examples include parameters that require a + * time-consuming hardware re-configuration or internal camera pipeline + * change. For performance reasons we advise clients to pass their initial + * values as part of + * {@link ACameraDevice_createCaptureSessionWithSessionParameters }.i + * Once the camera capture session is enabled it is also recommended to avoid + * changing them from their initial values set in + * {@link ACameraDevice_createCaptureSessionWithSessionParameters }. + * Control over session parameters can still be exerted in capture requests + * but clients should be aware and expect delays during their application. + * An example usage scenario could look like this:

+ * + * + * @see ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS + */ + ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS = // int32[n] + ACAMERA_REQUEST_START + 16, ACAMERA_REQUEST_END, /** diff --git a/camera/ndk/libcamera2ndk.map.txt b/camera/ndk/libcamera2ndk.map.txt index 58d239ba28..d179aa01f0 100644 --- a/camera/ndk/libcamera2ndk.map.txt +++ b/camera/ndk/libcamera2ndk.map.txt @@ -10,6 +10,7 @@ LIBCAMERA2NDK { ACameraDevice_close; ACameraDevice_createCaptureRequest; ACameraDevice_createCaptureSession; + ACameraDevice_createCaptureSessionWithSessionParameters; ACameraDevice_getId; ACameraManager_create; ACameraManager_delete; diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp index 51d92140f3..8fe9a8699a 100644 --- a/camera/tests/CameraBinderTests.cpp +++ b/camera/tests/CameraBinderTests.cpp @@ -476,7 +476,8 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { res = device->createStream(output, &streamId); EXPECT_TRUE(res.isOk()) << res; EXPECT_LE(0, streamId); - res = device->endConfigure(/*isConstrainedHighSpeed*/ false); + CameraMetadata sessionParams; + res = device->endConfigure(/*isConstrainedHighSpeed*/ false, sessionParams); EXPECT_TRUE(res.isOk()) << res; EXPECT_FALSE(callbacks->hadError()); @@ -574,7 +575,7 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { EXPECT_TRUE(res.isOk()) << res; res = device->deleteStream(streamId); EXPECT_TRUE(res.isOk()) << res; - res = device->endConfigure(/*isConstrainedHighSpeed*/ false); + res = device->endConfigure(/*isConstrainedHighSpeed*/ false, sessionParams); EXPECT_TRUE(res.isOk()) << res; sleep(/*second*/1); // allow some time for errors to show up, if any diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index 1fbba58ba6..aeaca48793 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -78,7 +78,8 @@ LOCAL_SHARED_LIBRARIES:= \ android.hardware.camera.provider@2.4 \ android.hardware.camera.device@1.0 \ android.hardware.camera.device@3.2 \ - android.hardware.camera.device@3.3 + android.hardware.camera.device@3.3 \ + android.hardware.camera.device@3.4 LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libcamera_client libfmq diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index a376ab45d2..ea7dc27e09 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -318,7 +318,8 @@ binder::Status CameraDeviceClient::beginConfigure() { return binder::Status::ok(); } -binder::Status CameraDeviceClient::endConfigure(int operatingMode) { +binder::Status CameraDeviceClient::endConfigure(int operatingMode, + const hardware::camera2::impl::CameraMetadataNative& sessionParams) { ATRACE_CALL(); ALOGV("%s: ending configure (%d input stream, %zu output surfaces)", __FUNCTION__, mInputStream.configured ? 1 : 0, @@ -364,7 +365,7 @@ binder::Status CameraDeviceClient::endConfigure(int operatingMode) { } } - status_t err = mDevice->configureStreams(operatingMode); + status_t err = mDevice->configureStreams(sessionParams, operatingMode); if (err == BAD_VALUE) { String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided", mCameraIdStr.string()); diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index e1a11db463..fbbafc92c9 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -85,7 +85,8 @@ public: virtual binder::Status beginConfigure() override; - virtual binder::Status endConfigure(int operatingMode) override; + virtual binder::Status endConfigure(int operatingMode, + const hardware::camera2::impl::CameraMetadataNative& sessionParams) override; // Returns -EBUSY if device is not idle or in error state virtual binder::Status deleteStream(int streamId) override; diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h index f1f96c3995..3fd6921965 100644 --- a/services/camera/libcameraservice/common/CameraDeviceBase.h +++ b/services/camera/libcameraservice/common/CameraDeviceBase.h @@ -212,7 +212,8 @@ class CameraDeviceBase : public virtual RefBase { * - BAD_VALUE if the set of streams was invalid (e.g. fmts or sizes) * - INVALID_OPERATION if the device was in the wrong state */ - virtual status_t configureStreams(int operatingMode = 0) = 0; + virtual status_t configureStreams(const CameraMetadata& sessionParams, + int operatingMode = 0) = 0; // get the buffer producer of the input stream virtual status_t getInputBufferProducer( diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index c0db8e7634..d99fc1de1c 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -55,6 +55,8 @@ #include "device3/Camera3SharedOutputStream.h" #include "CameraService.h" +#include + using namespace android::camera3; using namespace android::hardware::camera; using namespace android::hardware::camera::device::V3_2; @@ -1102,7 +1104,7 @@ sp Camera3Device::setUpRequestLocked( if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) { // This point should only be reached via API1 (API2 must explicitly call configureStreams) // so unilaterally select normal operating mode. - res = configureStreamsLocked(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE); + res = configureStreamsLocked(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, mSessionParams); // Stream configuration failed. Client might try other configuraitons. if (res != OK) { CLOGE("Can't set up streams: %s (%d)", strerror(-res), res); @@ -1205,8 +1207,8 @@ status_t Camera3Device::createInputStream( // Continue captures if active at start if (wasActive) { ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__); - // Reuse current operating mode for new stream config - res = configureStreamsLocked(mOperatingMode); + // Reuse current operating mode and session parameters for new stream config + res = configureStreamsLocked(mOperatingMode, mSessionParams); if (res != OK) { ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)", __FUNCTION__, mNextStreamId, strerror(-res), res); @@ -1360,8 +1362,8 @@ status_t Camera3Device::createStream(const std::vector>& consumers, // Continue captures if active at start if (wasActive) { ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__); - // Reuse current operating mode for new stream config - res = configureStreamsLocked(mOperatingMode); + // Reuse current operating mode and session parameters for new stream config + res = configureStreamsLocked(mOperatingMode, mSessionParams); if (res != OK) { CLOGE("Can't reconfigure device for new stream %d: %s (%d)", mNextStreamId, strerror(-res), res); @@ -1499,14 +1501,29 @@ status_t Camera3Device::deleteStream(int id) { return res; } -status_t Camera3Device::configureStreams(int operatingMode) { +status_t Camera3Device::configureStreams(const CameraMetadata& sessionParams, int operatingMode) { ATRACE_CALL(); ALOGV("%s: E", __FUNCTION__); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); - return configureStreamsLocked(operatingMode); + //Filter out any incoming session parameters + const CameraMetadata params(sessionParams); + CameraMetadata filteredParams; + camera_metadata_entry_t availableSessionKeys = mDeviceInfo.find( + ANDROID_REQUEST_AVAILABLE_SESSION_KEYS); + if (availableSessionKeys.count > 0) { + for (size_t i = 0; i < availableSessionKeys.count; i++) { + camera_metadata_ro_entry entry = params.find( + availableSessionKeys.data.i32[i]); + if (entry.count > 0) { + filteredParams.update(entry); + } + } + } + + return configureStreamsLocked(operatingMode, filteredParams); } status_t Camera3Device::getInputBufferProducer( @@ -2188,7 +2205,8 @@ void Camera3Device::cancelStreamsConfigurationLocked() { mNeedConfig = true; } -status_t Camera3Device::configureStreamsLocked(int operatingMode) { +status_t Camera3Device::configureStreamsLocked(int operatingMode, + const CameraMetadata& sessionParams) { ATRACE_CALL(); status_t res; @@ -2272,7 +2290,9 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode) { // Do the HAL configuration; will potentially touch stream // max_buffers, usage, priv fields. - res = mInterface->configureStreams(&config); + const camera_metadata_t *sessionBuffer = sessionParams.getAndLock(); + res = mInterface->configureStreams(sessionBuffer, &config); + sessionParams.unlock(sessionBuffer); if (res == BAD_VALUE) { // HAL rejected this set of streams as unsupported, clean up config @@ -2337,6 +2357,14 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode) { } // Update device state + const camera_metadata_t *newSessionParams = sessionParams.getAndLock(); + const camera_metadata_t *currentSessionParams = mSessionParams.getAndLock(); + bool updateSessionParams = (newSessionParams != currentSessionParams) ? true : false; + sessionParams.unlock(newSessionParams); + mSessionParams.unlock(currentSessionParams); + if (updateSessionParams) { + mSessionParams = sessionParams; + } mNeedConfig = false; @@ -3224,17 +3252,18 @@ status_t Camera3Device::HalInterface::constructDefaultRequestSettings( return res; } -status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configuration *config) { +status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *sessionParams, + camera3_stream_configuration *config) { ATRACE_NAME("CameraHal::configureStreams"); if (!valid()) return INVALID_OPERATION; status_t res = OK; // Convert stream config to HIDL std::set activeStreams; - StreamConfiguration requestedConfiguration; - requestedConfiguration.streams.resize(config->num_streams); + device::V3_4::StreamConfiguration requestedConfiguration; + requestedConfiguration.v3_2.streams.resize(config->num_streams); for (size_t i = 0; i < config->num_streams; i++) { - Stream &dst = requestedConfiguration.streams[i]; + Stream &dst = requestedConfiguration.v3_2.streams[i]; camera3_stream_t *src = config->streams[i]; Camera3Stream* cam3stream = Camera3Stream::cast(src); @@ -3281,29 +3310,50 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat res = mapToStreamConfigurationMode( (camera3_stream_configuration_mode_t) config->operation_mode, - /*out*/ &requestedConfiguration.operationMode); + /*out*/ &requestedConfiguration.v3_2.operationMode); if (res != OK) { return res; } + requestedConfiguration.sessionParams.setToExternal( + reinterpret_cast(const_cast(sessionParams)), + get_camera_metadata_size(sessionParams)); + // Invoke configureStreams device::V3_3::HalStreamConfiguration finalConfiguration; common::V1_0::Status status; - // See if we have v3.3 HAL + // See if we have v3.4 or v3.3 HAL + sp hidlSession_3_4; sp hidlSession_3_3; - auto castResult = device::V3_3::ICameraDeviceSession::castFrom(mHidlSession); - if (castResult.isOk()) { - hidlSession_3_3 = castResult; + auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession); + if (castResult_3_4.isOk()) { + hidlSession_3_4 = castResult_3_4; } else { - ALOGE("%s: Transaction error when casting ICameraDeviceSession: %s", __FUNCTION__, - castResult.description().c_str()); + auto castResult_3_3 = device::V3_3::ICameraDeviceSession::castFrom(mHidlSession); + if (castResult_3_3.isOk()) { + hidlSession_3_3 = castResult_3_3; + } } - if (hidlSession_3_3 != nullptr) { + + if (hidlSession_3_4 != nullptr) { + // We do; use v3.4 for the call + ALOGV("%s: v3.4 device found", __FUNCTION__); + auto err = hidlSession_3_4->configureStreams_3_4(requestedConfiguration, + [&status, &finalConfiguration] + (common::V1_0::Status s, const device::V3_3::HalStreamConfiguration& halConfiguration) { + finalConfiguration = halConfiguration; + status = s; + }); + if (!err.isOk()) { + ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); + return DEAD_OBJECT; + } + } else if (hidlSession_3_3 != nullptr) { // We do; use v3.3 for the call ALOGV("%s: v3.3 device found", __FUNCTION__); - auto err = hidlSession_3_3->configureStreams_3_3(requestedConfiguration, + auto err = hidlSession_3_3->configureStreams_3_3(requestedConfiguration.v3_2, [&status, &finalConfiguration] (common::V1_0::Status s, const device::V3_3::HalStreamConfiguration& halConfiguration) { finalConfiguration = halConfiguration; @@ -3317,7 +3367,7 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat // We don't; use v3.2 call and construct a v3.3 HalStreamConfiguration ALOGV("%s: v3.2 device found", __FUNCTION__); HalStreamConfiguration finalConfiguration_3_2; - auto err = mHidlSession->configureStreams(requestedConfiguration, + auto err = mHidlSession->configureStreams(requestedConfiguration.v3_2, [&status, &finalConfiguration_3_2] (common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) { finalConfiguration_3_2 = halConfiguration; @@ -3331,7 +3381,7 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat for (size_t i = 0; i < finalConfiguration_3_2.streams.size(); i++) { finalConfiguration.streams[i].v3_2 = finalConfiguration_3_2.streams[i]; finalConfiguration.streams[i].overrideDataSpace = - requestedConfiguration.streams[i].dataSpace; + requestedConfiguration.v3_2.streams[i].dataSpace; } } diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index e9466abd75..cc7eb35913 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -138,7 +138,8 @@ class Camera3Device : status_t deleteStream(int id) override; - status_t configureStreams(int operatingMode = + status_t configureStreams(const CameraMetadata& sessionParams, + int operatingMode = static_cast(hardware::camera::device::V3_2::StreamConfigurationMode::NORMAL_MODE)) override; status_t getInputBufferProducer( @@ -236,6 +237,9 @@ class Camera3Device : // Current stream configuration mode; int mOperatingMode; + // Current session wide parameters + hardware::camera2::impl::CameraMetadataNative mSessionParams; + // Constant to use for no set operating mode static const int NO_MODE = -1; @@ -272,7 +276,8 @@ class Camera3Device : // Caller takes ownership of requestTemplate status_t constructDefaultRequestSettings(camera3_request_template_t templateId, /*out*/ camera_metadata_t **requestTemplate); - status_t configureStreams(/*inout*/ camera3_stream_configuration *config); + status_t configureStreams(const camera_metadata_t *sessionParams, + /*inout*/ camera3_stream_configuration *config); status_t processCaptureRequest(camera3_capture_request_t *request); status_t processBatchCaptureRequests( std::vector& requests, @@ -550,7 +555,8 @@ class Camera3Device : * Take the currently-defined set of streams and configure the HAL to use * them. This is a long-running operation (may be several hundered ms). */ - status_t configureStreamsLocked(int operatingMode); + status_t configureStreamsLocked(int operatingMode, + const CameraMetadata& sessionParams); /** * Cancel stream configuration that did not finish successfully.