Camera: plumbing for RAW OPAQUE
Bug: 25596619
Change-Id: I0867a36962084bc508aebc89cb910473402a5e09
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
index 4f00e84..d1c79d0 100644
--- a/services/camera/libcameraservice/common/CameraModule.cpp
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -28,9 +28,9 @@
uint32_t deviceVersion, CameraMetadata &chars) {
ATRACE_CALL();
+ Vector<int32_t> derivedCharKeys;
// Keys added in HAL3.3
if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
- const size_t NUM_DERIVED_KEYS_HAL3_3 = 5;
Vector<uint8_t> controlModes;
uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1);
@@ -102,18 +102,11 @@
chars.update(ANDROID_SHADING_AVAILABLE_MODES, lscModes);
chars.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, lscMapModes);
- entry = chars.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
- Vector<int32_t> availableCharsKeys;
- availableCharsKeys.setCapacity(entry.count + NUM_DERIVED_KEYS_HAL3_3);
- for (size_t i = 0; i < entry.count; i++) {
- availableCharsKeys.push(entry.data.i32[i]);
- }
- availableCharsKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
- availableCharsKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
- availableCharsKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
- availableCharsKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
- availableCharsKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
- chars.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, availableCharsKeys);
+ derivedCharKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
+ derivedCharKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
+ derivedCharKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
+ derivedCharKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
+ derivedCharKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
// Need update android.control.availableHighSpeedVideoConfigurations since HAL3.3
// adds batch size to this array.
@@ -132,6 +125,44 @@
}
}
+ // Keys added in HAL3.4
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
+ // Check if HAL supports RAW_OPAQUE output
+ camera_metadata_entry entry = chars.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
+ bool supportRawOpaque = false;
+ const int STREAM_CONFIGURATION_SIZE = 4;
+ const int STREAM_FORMAT_OFFSET = 0;
+ const int STREAM_WIDTH_OFFSET = 1;
+ const int STREAM_HEIGHT_OFFSET = 2;
+ const int STREAM_IS_INPUT_OFFSET = 3;
+ Vector<int32_t> rawOpaqueSizes;
+
+ for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+ int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
+ int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
+ int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
+ int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
+ if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
+ format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
+ supportRawOpaque = true;
+ rawOpaqueSizes.push(width);
+ rawOpaqueSizes.push(height);
+ // 2 bytes per pixel. This rough estimation is only used when
+ // HAL does not fill in the opaque raw size
+ rawOpaqueSizes.push(width * height *2);
+ }
+ }
+
+ if (supportRawOpaque) {
+ entry = chars.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
+ if (entry.count == 0) {
+ // Fill in estimated value if HAL does not list it
+ chars.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, rawOpaqueSizes);
+ derivedCharKeys.push(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
+ }
+ }
+ }
+
// Always add a default for the pre-correction active array if the vendor chooses to omit this
camera_metadata_entry entry = chars.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
if (entry.count == 0) {
@@ -139,8 +170,21 @@
entry = chars.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
preCorrectionArray.appendArray(entry.data.i32, entry.count);
chars.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, preCorrectionArray);
+ derivedCharKeys.push(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
}
+ // Add those newly added keys to AVAILABLE_CHARACTERISTICS_KEYS
+ // This has to be done at this end of this function.
+ entry = chars.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+ Vector<int32_t> availableCharsKeys;
+ availableCharsKeys.setCapacity(entry.count + derivedCharKeys.size());
+ for (size_t i = 0; i < entry.count; i++) {
+ availableCharsKeys.push(entry.data.i32[i]);
+ }
+ for (size_t i = 0; i < derivedCharKeys.size(); i++) {
+ availableCharsKeys.push(derivedCharKeys[i]);
+ }
+ chars.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, availableCharsKeys);
return;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 7acd150..6c07aef 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -422,7 +422,31 @@
return maxBytesForPointCloud;
}
+ssize_t Camera3Device::getRawOpaqueBufferSize(uint32_t width, uint32_t height) const {
+ const int PER_CONFIGURATION_SIZE = 3;
+ const int WIDTH_OFFSET = 0;
+ const int HEIGHT_OFFSET = 1;
+ const int SIZE_OFFSET = 2;
+ camera_metadata_ro_entry rawOpaqueSizes =
+ mDeviceInfo.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
+ int count = rawOpaqueSizes.count;
+ if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
+ ALOGE("%s: Camera %d: bad opaque RAW size static metadata length(%d)!",
+ __FUNCTION__, mId, count);
+ return BAD_VALUE;
+ }
+ for (size_t i = 0; i < count; i += PER_CONFIGURATION_SIZE) {
+ if (width == rawOpaqueSizes.data.i32[i + WIDTH_OFFSET] &&
+ height == rawOpaqueSizes.data.i32[i + HEIGHT_OFFSET]) {
+ return rawOpaqueSizes.data.i32[i + SIZE_OFFSET];
+ }
+ }
+
+ ALOGE("%s: Camera %d: cannot find size for %dx%d opaque RAW image!",
+ __FUNCTION__, mId, width, height);
+ return BAD_VALUE;
+}
status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
ATRACE_CALL();
@@ -956,6 +980,14 @@
}
newStream = new Camera3OutputStream(mNextStreamId, consumer,
width, height, blobBufferSize, format, dataSpace, rotation);
+ } else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
+ ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(width, height);
+ if (rawOpaqueBufferSize <= 0) {
+ SET_ERR_L("Invalid RAW opaque buffer size %zd", rawOpaqueBufferSize);
+ return BAD_VALUE;
+ }
+ newStream = new Camera3OutputStream(mNextStreamId, consumer,
+ width, height, rawOpaqueBufferSize, format, dataSpace, rotation);
} else {
newStream = new Camera3OutputStream(mNextStreamId, consumer,
width, height, format, dataSpace, rotation);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 2cd5af3..7e20b0d 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -150,6 +150,7 @@
virtual ssize_t getJpegBufferSize(uint32_t width, uint32_t height) const;
ssize_t getPointCloudBufferSize() const;
+ ssize_t getRawOpaqueBufferSize(uint32_t width, uint32_t height) const;
// Methods called by subclasses
void notifyStatus(bool idle); // updates from StatusTracker
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 23b1c45..7b298e6 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -42,7 +42,8 @@
mCombinedFence = new Fence();
- if (maxSize > 0 && format != HAL_PIXEL_FORMAT_BLOB) {
+ if (maxSize > 0 &&
+ (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
format);
mState = STATE_ERROR;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 3f0a736..a5aa1fa 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -57,7 +57,7 @@
mTransform(0),
mTraceFirstBuffer(true) {
- if (format != HAL_PIXEL_FORMAT_BLOB) {
+ if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
format);
mState = STATE_ERROR;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 96299b3..141f6c3 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -66,8 +66,9 @@
camera3_stream::max_buffers = 0;
camera3_stream::priv = NULL;
- if (format == HAL_PIXEL_FORMAT_BLOB && maxSize == 0) {
- ALOGE("%s: BLOB format with size == 0", __FUNCTION__);
+ if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
+ maxSize == 0) {
+ ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__);
mState = STATE_ERROR;
}
}