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
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 1fbba58..aeaca48 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -78,7 +78,8 @@
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 a376ab4..ea7dc27 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -318,7 +318,8 @@
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 @@
}
}
- 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 e1a11db..fbbafc9 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -85,7 +85,8 @@
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 f1f96c3..3fd6921 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -212,7 +212,8 @@
* - 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 c0db8e7..d99fc1d 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 <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
+
using namespace android::camera3;
using namespace android::hardware::camera;
using namespace android::hardware::camera::device::V3_2;
@@ -1102,7 +1104,7 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
// 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 @@
}
// 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 @@
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<int> 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 @@
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<uint8_t*>(const_cast<camera_metadata_t*>(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<device::V3_4::ICameraDeviceSession> hidlSession_3_4;
sp<device::V3_3::ICameraDeviceSession> 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 @@
// 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 @@
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 e9466ab..cc7eb35 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -138,7 +138,8 @@
status_t deleteStream(int id) override;
- status_t configureStreams(int operatingMode =
+ status_t configureStreams(const CameraMetadata& sessionParams,
+ int operatingMode =
static_cast<int>(hardware::camera::device::V3_2::StreamConfigurationMode::NORMAL_MODE))
override;
status_t getInputBufferProducer(
@@ -236,6 +237,9 @@
// 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 @@
// 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<camera3_capture_request_t*>& requests,
@@ -550,7 +555,8 @@
* 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.