Camera: Allow direct selection of operating mode
Instead of a true/false switch for high-speed mode, use an integer
enum instead and define the two existing modes, plus the start
of a vendor mode space.
For all non-high-speed modes, use the normal configuration path,
but pass the operating mode to the HAL.
Test: New CTS test passes
Bug: 34853980
Change-Id: I9dc2b2a2164e9779f079a30e936c4117bcf96efe
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 3512730..0771fc8 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -54,6 +54,22 @@
void beginConfigure();
/**
+ * The standard operating mode for a camera device; all API guarantees are in force
+ */
+ const int NORMAL_MODE = 0;
+
+ /**
+ * High-speed recording mode; only two outputs targeting preview and video recording may be
+ * used, and requests must be batched.
+ */
+ const int CONSTRAINED_HIGH_SPEED_MODE = 1;
+
+ /**
+ * Start of custom vendor modes
+ */
+ const int VENDOR_MODE_START = 0x8000;
+
+ /**
* End the device configuration.
*
* <p>
@@ -61,8 +77,10 @@
* a call to beginConfigure and subsequent createStream/deleteStream calls). This
* must be called before any requests can be submitted.
* <p>
+ * @param operatingMode The kind of session to create; either NORMAL_MODE or
+ * CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value.
*/
- void endConfigure(boolean isConstrainedHighSpeed);
+ void endConfigure(int operatingMode);
void deleteStream(int streamId);
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 79e7ff0..4428f75 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -321,7 +321,7 @@
return binder::Status::ok();
}
-binder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
+binder::Status CameraDeviceClient::endConfigure(int operatingMode) {
ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
__FUNCTION__, mInputStream.configured ? 1 : 0,
mStreamMap.size());
@@ -335,7 +335,16 @@
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
+ if (operatingMode < 0) {
+ String8 msg = String8::format(
+ "Camera %s: Invalid operating mode %d requested", mCameraIdStr.string(), operatingMode);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ msg.string());
+ }
+
// Sanitize the high speed session against necessary capability bit.
+ bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
if (isConstrainedHighSpeed) {
CameraMetadata staticInfo = mDevice->info();
camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
@@ -357,7 +366,7 @@
}
}
- status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
+ status_t err = mDevice->configureStreams(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 012beb4..2a95c88 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -70,70 +70,70 @@
const hardware::camera2::CaptureRequest& request,
bool streaming = false,
/*out*/
- hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
+ hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
// List of requests are copied.
virtual binder::Status submitRequestList(
const std::vector<hardware::camera2::CaptureRequest>& requests,
bool streaming = false,
/*out*/
- hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
+ hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
virtual binder::Status cancelRequest(int requestId,
/*out*/
- int64_t* lastFrameNumber = NULL);
+ int64_t* lastFrameNumber = NULL) override;
- virtual binder::Status beginConfigure();
+ virtual binder::Status beginConfigure() override;
- virtual binder::Status endConfigure(bool isConstrainedHighSpeed = false);
+ virtual binder::Status endConfigure(int operatingMode) override;
// Returns -EBUSY if device is not idle
- virtual binder::Status deleteStream(int streamId);
+ virtual binder::Status deleteStream(int streamId) override;
virtual binder::Status createStream(
const hardware::camera2::params::OutputConfiguration &outputConfiguration,
/*out*/
- int32_t* newStreamId = NULL);
+ int32_t* newStreamId = NULL) override;
// Create an input stream of width, height, and format.
virtual binder::Status createInputStream(int width, int height, int format,
/*out*/
- int32_t* newStreamId = NULL);
+ int32_t* newStreamId = NULL) override;
// Get the buffer producer of the input stream
virtual binder::Status getInputSurface(
/*out*/
- view::Surface *inputSurface);
+ view::Surface *inputSurface) override;
// Create a request object from a template.
virtual binder::Status createDefaultRequest(int templateId,
/*out*/
- hardware::camera2::impl::CameraMetadataNative* request);
+ hardware::camera2::impl::CameraMetadataNative* request) override;
// Get the static metadata for the camera
// -- Caller owns the newly allocated metadata
virtual binder::Status getCameraInfo(
/*out*/
- hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics);
+ hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics) override;
// Wait until all the submitted requests have finished processing
- virtual binder::Status waitUntilIdle();
+ virtual binder::Status waitUntilIdle() override;
// Flush all active and pending requests as fast as possible
virtual binder::Status flush(
/*out*/
- int64_t* lastFrameNumber = NULL);
+ int64_t* lastFrameNumber = NULL) override;
// Prepare stream by preallocating its buffers
- virtual binder::Status prepare(int32_t streamId);
+ virtual binder::Status prepare(int32_t streamId) override;
// Tear down stream resources by freeing its unused buffers
- virtual binder::Status tearDown(int32_t streamId);
+ virtual binder::Status tearDown(int32_t streamId) override;
// Prepare stream by preallocating up to maxCount of its buffers
- virtual binder::Status prepare2(int32_t maxCount, int32_t streamId);
+ virtual binder::Status prepare2(int32_t maxCount, int32_t streamId) override;
// Finalize the output configurations with surfaces not added before.
virtual binder::Status finalizeOutputConfigurations(int32_t streamId,
- const hardware::camera2::params::OutputConfiguration &outputConfiguration);
+ const hardware::camera2::params::OutputConfiguration &outputConfiguration) override;
/**
* Interface used by CameraService
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 98a3fcc..f9b062a 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -184,7 +184,7 @@
* - 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(bool isConstrainedHighSpeed = false) = 0;
+ virtual status_t configureStreams(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 f20556d..3b9cb1a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -63,6 +63,7 @@
Camera3Device::Camera3Device(const String8 &id):
mId(id),
+ mOperatingMode(NO_MODE),
mIsConstrainedHighSpeedConfiguration(false),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
@@ -514,19 +515,25 @@
return StreamRotation::ROTATION_0;
}
-StreamConfigurationMode Camera3Device::mapToStreamConfigurationMode(
- camera3_stream_configuration_mode_t operationMode) {
- switch(operationMode) {
- case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
- return StreamConfigurationMode::NORMAL_MODE;
- case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
- return StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
- case CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START:
- // Needs to be mapped by vendor extensions
- break;
+status_t Camera3Device::mapToStreamConfigurationMode(
+ camera3_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
+ if (mode == nullptr) return BAD_VALUE;
+ if (operationMode < CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START) {
+ switch(operationMode) {
+ case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
+ *mode = StreamConfigurationMode::NORMAL_MODE;
+ break;
+ case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
+ *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
+ break;
+ default:
+ ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
+ return BAD_VALUE;
+ }
+ } else {
+ *mode = static_cast<StreamConfigurationMode>(operationMode);
}
- ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
- return StreamConfigurationMode::NORMAL_MODE;
+ return OK;
}
camera3_buffer_status_t Camera3Device::mapHidlBufferStatus(BufferStatus status) {
@@ -677,8 +684,12 @@
lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
}
lines.appendFormat(" Stream configuration:\n");
- lines.appendFormat(" Operation mode: %s \n", mIsConstrainedHighSpeedConfiguration ?
- "CONSTRAINED HIGH SPEED VIDEO" : "NORMAL");
+ const char *mode =
+ mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
+ mOperatingMode == static_cast<int>(
+ StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
+ "CUSTOM";
+ lines.appendFormat(" Operation mode: %s (%d) \n", mode, mOperatingMode);
if (mInputStream != NULL) {
write(fd, lines.string(), lines.size());
@@ -1501,16 +1512,21 @@
return INVALID_OPERATION;
}
-status_t Camera3Device::configureStreams(bool isConstrainedHighSpeed) {
+status_t Camera3Device::configureStreams(int operatingMode) {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
- if (mIsConstrainedHighSpeedConfiguration != isConstrainedHighSpeed) {
+ bool isConstrainedHighSpeed =
+ static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
+ operatingMode;
+
+ if (mOperatingMode != operatingMode) {
mNeedConfig = true;
mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
+ mOperatingMode = operatingMode;
}
return configureStreamsLocked();
@@ -2188,9 +2204,7 @@
ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
camera3_stream_configuration config;
- config.operation_mode = mIsConstrainedHighSpeedConfiguration ?
- CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE :
- CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
+ config.operation_mode = mOperatingMode;
config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
Vector<camera3_stream_t*> streams;
@@ -3149,8 +3163,12 @@
}
}
- requestedConfiguration.operationMode = mapToStreamConfigurationMode(
- (camera3_stream_configuration_mode_t) config->operation_mode);
+ res = mapToStreamConfigurationMode(
+ (camera3_stream_configuration_mode_t) config->operation_mode,
+ /*out*/ &requestedConfiguration.operationMode);
+ if (res != OK) {
+ return res;
+ }
// Invoke configureStreams
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index e19b62e..2e0c101 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -135,7 +135,9 @@
status_t deleteStream(int id) override;
status_t deleteReprocessStream(int id) override;
- status_t configureStreams(bool isConstraiedHighSpeed = false) override;
+ status_t configureStreams(int operatingMode =
+ static_cast<int>(hardware::camera::device::V3_2::StreamConfigurationMode::NORMAL_MODE))
+ override;
status_t getInputBufferProducer(
sp<IGraphicBufferProducer> *producer) override;
@@ -212,6 +214,11 @@
// Camera device ID
const String8 mId;
+ // Current stream configuration mode;
+ int mOperatingMode;
+ // Constant to use for no set operating mode
+ static const int NO_MODE = -1;
+
// Flag indicating is the current active stream configuration is constrained high speed.
bool mIsConstrainedHighSpeedConfiguration;
@@ -574,8 +581,9 @@
static hardware::camera::device::V3_2::ConsumerUsageFlags mapToConsumerUsage(uint32_t usage);
static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
camera3_stream_rotation_t rotation);
- static hardware::camera::device::V3_2::StreamConfigurationMode mapToStreamConfigurationMode(
- camera3_stream_configuration_mode_t operationMode);
+ // Returns a negative error code if the passed-in operation mode is not valid.
+ static status_t mapToStreamConfigurationMode(camera3_stream_configuration_mode_t operationMode,
+ /*out*/ hardware::camera::device::V3_2::StreamConfigurationMode *mode);
static camera3_buffer_status_t mapHidlBufferStatus(hardware::camera::device::V3_2::BufferStatus status);
static int mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat);
static uint32_t mapConsumerToFrameworkUsage(