Camera: Add stream use case API
Camera stream use case indicates the purpose of a camera stream
independent of its direct consumer target. The stream use case is
plumbed from the app to the camera HAL.
Test: Camera CTS
Bug: 200307880
Change-Id: I15f9e63c4dc41ce355a509c154686fc06c1ab72d
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
index bc83ec1..2a07ffc 100644
--- a/camera/CameraSessionStats.cpp
+++ b/camera/CameraSessionStats.cpp
@@ -118,6 +118,12 @@
return err;
}
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+ if ((err = parcel->readInt32(&streamUseCase)) != OK) {
+ ALOGE("%s: Failed to read stream use case from parcel", __FUNCTION__);
+ return err;
+ }
+
mWidth = width;
mHeight = height;
mFormat = format;
@@ -132,6 +138,7 @@
mHistogramBins = std::move(histogramBins);
mHistogramCounts = std::move(histogramCounts);
mDynamicRangeProfile = dynamicRangeProfile;
+ mStreamUseCase = streamUseCase;
return OK;
}
@@ -214,6 +221,11 @@
return err;
}
+ if ((err = parcel->writeInt32(mStreamUseCase)) != OK) {
+ ALOGE("%s: Failed to write stream use case!", __FUNCTION__);
+ return err;
+ }
+
return OK;
}
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 15c9dc9..0982bba 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -81,6 +81,10 @@
return mDynamicRangeProfile;
}
+int OutputConfiguration::getStreamUseCase() const {
+ return mStreamUseCase;
+}
+
OutputConfiguration::OutputConfiguration() :
mRotation(INVALID_ROTATION),
mSurfaceSetID(INVALID_SET_ID),
@@ -90,7 +94,8 @@
mIsDeferred(false),
mIsShared(false),
mIsMultiResolution(false),
- mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
+ mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
+ mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
}
OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
@@ -177,6 +182,12 @@
return err;
}
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+ if ((err = parcel->readInt32(&streamUseCase)) != OK) {
+ ALOGE("%s: Failed to read stream use case from parcel", __FUNCTION__);
+ return err;
+ }
+
mRotation = rotation;
mSurfaceSetID = setID;
mSurfaceType = surfaceType;
@@ -185,6 +196,7 @@
mIsDeferred = isDeferred != 0;
mIsShared = isShared != 0;
mIsMultiResolution = isMultiResolution != 0;
+ mStreamUseCase = streamUseCase;
for (auto& surface : surfaceShims) {
ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
surface.graphicBufferProducer.get(),
@@ -196,8 +208,9 @@
mDynamicRangeProfile = dynamicProfile;
ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d,"
- " physicalCameraId = %s, isMultiResolution = %d", __FUNCTION__, mRotation,
- mSurfaceSetID, mSurfaceType, String8(mPhysicalCameraId).string(), mIsMultiResolution);
+ " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %d", __FUNCTION__,
+ mRotation, mSurfaceSetID, mSurfaceType, String8(mPhysicalCameraId).string(),
+ mIsMultiResolution, mStreamUseCase);
return err;
}
@@ -213,6 +226,7 @@
mPhysicalCameraId = physicalId;
mIsMultiResolution = false;
mDynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+ mStreamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
}
OutputConfiguration::OutputConfiguration(
@@ -222,7 +236,8 @@
: mGbps(gbps), mRotation(rotation), mSurfaceSetID(surfaceSetID), mSurfaceType(surfaceType),
mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared),
mPhysicalCameraId(physicalCameraId), mIsMultiResolution(false),
- mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) { }
+ mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
+ mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) { }
status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
@@ -272,6 +287,9 @@
err = parcel->writeInt32(mDynamicRangeProfile ? 1 : 0);
if (err != OK) return err;
+ err = parcel->writeInt32(mStreamUseCase);
+ if (err != OK) return err;
+
return OK;
}
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
index 1209a20..ab2d903 100644
--- a/camera/include/camera/CameraSessionStats.h
+++ b/camera/include/camera/CameraSessionStats.h
@@ -64,19 +64,24 @@
// Dynamic range profile
int mDynamicRangeProfile;
+ // Stream use case
+ int mStreamUseCase;
CameraStreamStats() :
mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0),
mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
mMaxHalBuffers(0), mMaxAppBuffers(0), mHistogramType(HISTOGRAM_TYPE_UNKNOWN),
- mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {}
+ mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
+ mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {}
CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage,
- int maxHalBuffers, int maxAppBuffers, int dynamicRangeProfile)
+ int maxHalBuffers, int maxAppBuffers, int dynamicRangeProfile,
+ int streamUseCase)
: mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace),
mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers),
mHistogramType(HISTOGRAM_TYPE_UNKNOWN),
- mDynamicRangeProfile(dynamicRangeProfile) {}
+ mDynamicRangeProfile(dynamicRangeProfile),
+ mStreamUseCase(streamUseCase) {}
virtual status_t readFromParcel(const android::Parcel* parcel) override;
virtual status_t writeToParcel(android::Parcel* parcel) const override;
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index 1631903..f1cb6bd 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -49,6 +49,7 @@
bool isShared() const;
String16 getPhysicalCameraId() const;
bool isMultiResolution() const;
+ int getStreamUseCase() const;
// set of sensor pixel mode resolutions allowed {MAX_RESOLUTION, DEFAULT_MODE};
const std::vector<int32_t>& getSensorPixelModesUsed() const;
@@ -91,7 +92,8 @@
mPhysicalCameraId == other.mPhysicalCameraId &&
mIsMultiResolution == other.mIsMultiResolution &&
sensorPixelModesUsedEqual(other) &&
- mDynamicRangeProfile == other.mDynamicRangeProfile);
+ mDynamicRangeProfile == other.mDynamicRangeProfile &&
+ mStreamUseCase == other.mStreamUseCase );
}
bool operator != (const OutputConfiguration& other) const {
return !(*this == other);
@@ -131,6 +133,9 @@
if (mDynamicRangeProfile != other.mDynamicRangeProfile) {
return mDynamicRangeProfile < other.mDynamicRangeProfile;
}
+ if (mStreamUseCase != other.mStreamUseCase) {
+ return mStreamUseCase < other.mStreamUseCase;
+ }
return gbpsLessThan(other);
}
@@ -156,6 +161,7 @@
bool mIsMultiResolution;
std::vector<int32_t> mSensorPixelModesUsed;
int mDynamicRangeProfile;
+ int mStreamUseCase;
};
} // namespace params
} // namespace camera2
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index bd281c8..5cc6759 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -4206,6 +4206,55 @@
*/
ACAMERA_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED = // byte (acamera_metadata_enum_android_scaler_multi_resolution_stream_supported_t)
ACAMERA_SCALER_START + 24,
+ /**
+ * <p>The stream use cases supported by this camera device.</p>
+ *
+ * <p>Type: int32[n] (acamera_metadata_enum_android_scaler_available_stream_use_cases_t)</p>
+ *
+ * <p>This tag may appear in:
+ * <ul>
+ * <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+ * </ul></p>
+ *
+ * <p>The stream use case indicates the purpose of a particular camera stream from
+ * the end-user perspective. Some examples of camera use cases are: preview stream for
+ * live viewfinder shown to the user, still capture for generating high quality photo
+ * capture, video record for encoding the camera output for the purpose of future playback,
+ * and video call for live realtime video conferencing.</p>
+ * <p>With this flag, the camera device can optimize the image processing pipeline
+ * parameters, such as tuning, sensor mode, and ISP settings, indepedent of
+ * the properties of the immediate camera output surface. For example, if the output
+ * surface is a SurfaceTexture, the stream use case flag can be used to indicate whether
+ * the camera frames eventually go to display, video encoder,
+ * still image capture, or all of them combined.</p>
+ * <p>The application sets the use case of a camera stream by calling
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration.html#setStreamUseCase">OutputConfiguration#setStreamUseCase</a>.</p>
+ * <p>A camera device with
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE">CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE</a>
+ * capability must support the following stream use cases:</p>
+ * <ul>
+ * <li>DEFAULT</li>
+ * <li>PREVIEW</li>
+ * <li>STILL_CAPTURE</li>
+ * <li>VIDEO_RECORD</li>
+ * <li>PREVIEW_VIDEO_STILL</li>
+ * <li>VIDEO_CALL</li>
+ * </ul>
+ * <p>The guaranteed stream combinations related to stream use case for a camera device with
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE">CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE</a>
+ * capability is documented in the camera device
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#createCaptureSession">guideline</a>. The
+ * application is strongly recommended to use one of the guaranteed stream combintations.
+ * If the application creates a session with a stream combination not in the guaranteed
+ * list, or with mixed DEFAULT and non-DEFAULT use cases within the same session,
+ * the camera device may ignore some stream use cases due to hardware constraints
+ * and implementation details.</p>
+ * <p>For stream combinations not covered by the stream use case mandatory lists, such as
+ * reprocessable session, constrained high speed session, or RAW stream combinations, the
+ * application should leave stream use cases within the session as DEFAULT.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES = // int32[n] (acamera_metadata_enum_android_scaler_available_stream_use_cases_t)
+ ACAMERA_SCALER_START + 25,
ACAMERA_SCALER_END,
/**
@@ -9142,6 +9191,35 @@
ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR
= 16,
+ /**
+ * <p>The camera device supports selecting a per-stream use case via
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/params/OutputConfiguration.html#setStreamUseCase">OutputConfiguration#setStreamUseCase</a>
+ * so that the device can optimize camera pipeline parameters such as tuning, sensor
+ * mode, or ISP settings for a specific user scenario.
+ * Some sample usages of this capability are:
+ * * Distinguish high quality YUV captures from a regular YUV stream where
+ * the image quality may not be as good as the JPEG stream, or
+ * * Use one stream to serve multiple purposes: viewfinder, video recording and
+ * still capture. This is common with applications that wish to apply edits equally
+ * to preview, saved images, and saved videos.</p>
+ * <p>This capability requires the camera device to support the following
+ * stream use cases:
+ * * DEFAULT for backward compatibility where the application doesn't set
+ * a stream use case
+ * * PREVIEW for live viewfinder and in-app image analysis
+ * * STILL_CAPTURE for still photo capture
+ * * VIDEO_RECORD for recording video clips
+ * * PREVIEW_VIDEO_STILL for one single stream used for viewfinder, video
+ * recording, and still capture.
+ * * VIDEO_CALL for long running video calls</p>
+ * <p><a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SCALER_AVAILABLE_STREAM_USE_CASES">CameraCharacteristics#SCALER_AVAILABLE_STREAM_USE_CASES</a>
+ * lists all of the supported stream use cases.</p>
+ * <p>Refer to <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#createCaptureSession">CameraDevice#createCaptureSession</a> for the
+ * mandatory stream combinations involving stream use cases, which can also be queried
+ * via <a href="https://developer.android.com/reference/android/hardware/camera2/params/MandatoryStreamCombination.html">MandatoryStreamCombination</a>.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE = 19,
+
} acamera_metadata_enum_android_request_available_capabilities_t;
// ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP
@@ -9420,6 +9498,76 @@
} acamera_metadata_enum_android_scaler_multi_resolution_stream_supported_t;
+// ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES
+typedef enum acamera_metadata_enum_acamera_scaler_available_stream_use_cases {
+ /**
+ * <p>Default stream use case.</p>
+ * <p>This use case is the same as when the application doesn't set any use case for
+ * the stream. The camera device uses the properties of the output target, such as
+ * format, dataSpace, or surface class type, to optimize the image processing pipeline.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0x0,
+
+ /**
+ * <p>Live stream shown to the user.</p>
+ * <p>Optimized for performance and usability as a viewfinder, but not necessarily for
+ * image quality. The output is not meant to be persisted as saved images or video.</p>
+ * <p>No stall if android.control.<em> are set to FAST; may have stall if android.control.</em>
+ * are set to HIGH_QUALITY. This use case has the same behavior as the default
+ * SurfaceView and SurfaceTexture targets. Additionally, this use case can be used for
+ * in-app image analysis.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 0x1,
+
+ /**
+ * <p>Still photo capture.</p>
+ * <p>Optimized for high-quality high-resolution capture, and not expected to maintain
+ * preview-like frame rates.</p>
+ * <p>The stream may have stalls regardless of whether ACAMERA_CONTROL_* is HIGH_QUALITY.
+ * This use case has the same behavior as the default JPEG and RAW related formats.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 0x2,
+
+ /**
+ * <p>Recording video clips.</p>
+ * <p>Optimized for high-quality video capture, including high-quality image stabilization
+ * if supported by the device and enabled by the application. As a result, may produce
+ * output frames with a substantial lag from real time, to allow for highest-quality
+ * stabilization or other processing. As such, such an output is not suitable for drawing
+ * to screen directly, and is expected to be persisted to disk or similar for later
+ * playback or processing. Only streams that set the VIDEO_RECORD use case are guaranteed
+ * to have video stabilization applied when the video stabilization control is set
+ * to ON, as opposed to PREVIEW_STABILIZATION.</p>
+ * <p>This use case has the same behavior as the default MediaRecorder and MediaCodec
+ * targets.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3,
+
+ /**
+ * <p>One single stream used for combined purposes of preview, video, and still capture.</p>
+ * <p>For such multi-purpose streams, the camera device aims to make the best tradeoff
+ * between the individual use cases. For example, the STILL_CAPTURE use case by itself
+ * may have stalls for achieving best image quality. But if combined with PREVIEW and
+ * VIDEO_RECORD, the camera device needs to trade off the additional image processing
+ * for speed so that preview and video recording aren't slowed down.</p>
+ * <p>Similarly, VIDEO_RECORD may produce frames with a substantial lag, but
+ * PREVIEW_VIDEO_STILL must have minimal output delay. This means that to enable video
+ * stabilization with this use case, the device must support and the app must select the
+ * PREVIEW_STABILIZATION mode for video stabilization.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4,
+
+ /**
+ * <p>Long-running video call optimized for both power efficienty and video quality.</p>
+ * <p>The camera sensor may run in a lower-resolution mode to reduce power consumption
+ * at the cost of some image and digital zoom quality. Unlike VIDEO_RECORD, VIDEO_CALL
+ * outputs are expected to work in dark conditions, so are usually accompanied with
+ * variable frame rate settings to allow sufficient exposure time in low light.</p>
+ */
+ ACAMERA_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5,
+
+} acamera_metadata_enum_android_scaler_available_stream_use_cases_t;
+
// ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
typedef enum acamera_metadata_enum_acamera_sensor_reference_illuminant1 {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index f33ae97..64173e3 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -145,9 +145,9 @@
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
if (entry.count > 0) {
- const auto it = std::find(entry.data.i32, entry.data.i32 + entry.count,
+ const auto it = std::find(entry.data.u8, entry.data.u8 + entry.count,
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT);
- if (it != entry.data.i32 + entry.count) {
+ if (it != entry.data.u8 + entry.count) {
entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
if (entry.count > 0 || ((entry.count % 2) != 0)) {
int standardBitmap = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
@@ -856,6 +856,7 @@
bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
bool isMultiResolution = outputConfiguration.isMultiResolution();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
+ int streamUseCase = outputConfiguration.getStreamUseCase();
res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
outputConfiguration.getSurfaceType());
@@ -899,7 +900,8 @@
sp<Surface> surface;
res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
- mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile);
+ mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
+ streamUseCase);
if (!res.isOk())
return res;
@@ -944,7 +946,7 @@
static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
&streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
- streamInfo.dynamicRangeProfile);
+ /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase);
}
if (err != OK) {
@@ -1039,7 +1041,8 @@
&surfaceIds,
outputConfiguration.getSurfaceSetID(), isShared,
outputConfiguration.isMultiResolution(), consumerUsage,
- outputConfiguration.getDynamicRangeProfile());
+ outputConfiguration.getDynamicRangeProfile(),
+ outputConfiguration.getStreamUseCase());
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -1053,7 +1056,8 @@
mStreamInfoMap.emplace(std::piecewise_construct, std::forward_as_tuple(streamId),
std::forward_as_tuple(width, height, format, dataSpace, consumerUsage,
overriddenSensorPixelModesUsed,
- outputConfiguration.getDynamicRangeProfile()));
+ outputConfiguration.getDynamicRangeProfile(),
+ outputConfiguration.getStreamUseCase()));
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
" (%d x %d) stream with format 0x%x.",
@@ -1241,6 +1245,7 @@
}
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
+ int streamUseCase = outputConfiguration.getStreamUseCase();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
@@ -1249,7 +1254,8 @@
sp<Surface> surface;
res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
/*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
- mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile);
+ mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
+ streamUseCase);
if (!res.isOk())
return res;
@@ -1607,6 +1613,7 @@
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
+ int streamUseCase= outputConfiguration.getStreamUseCase();
for (auto& bufferProducer : bufferProducers) {
// Don't create multiple streams for the same target surface
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
@@ -1619,7 +1626,8 @@
sp<Surface> surface;
res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
- mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile);
+ mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile,
+ streamUseCase);
if (!res.isOk())
return res;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index e936cb6..6ddf500 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -183,7 +183,8 @@
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) = 0;
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) = 0;
/**
* Create an output stream of the requested size, format, rotation and
@@ -201,7 +202,8 @@
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) = 0;
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) = 0;
/**
* Create an input stream of width, height, and format.
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 992027a..c8f6310 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -978,7 +978,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage, int dynamicRangeProfile) {
+ uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase) {
ATRACE_CALL();
if (consumer == nullptr) {
@@ -991,7 +991,8 @@
return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
- streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile);
+ streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile,
+ streamUseCase);
}
static bool isRawFormat(int format) {
@@ -1011,7 +1012,7 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage, int dynamicRangeProfile) {
+ uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
@@ -1089,7 +1090,7 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, blobBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile);
+ isMultiResolution, dynamicRangeProfile, streamUseCase);
} else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
bool maxResolution =
sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
@@ -1103,22 +1104,22 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile);
+ isMultiResolution, dynamicRangeProfile, streamUseCase);
} else if (isShared) {
newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- mUseHalBufManager, dynamicRangeProfile);
+ mUseHalBufManager, dynamicRangeProfile, streamUseCase);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile);
+ isMultiResolution, dynamicRangeProfile, streamUseCase);
} else {
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile);
+ isMultiResolution, dynamicRangeProfile, streamUseCase);
}
size_t consumerCount = consumers.size();
@@ -1812,14 +1813,16 @@
streamIds.push_back(stream->getId());
Camera3Stream* camera3Stream = Camera3Stream::cast(stream->asHalStream());
int64_t usage = 0LL;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
if (camera3Stream != nullptr) {
usage = camera3Stream->getUsage();
+ streamUseCase = camera3Stream->getStreamUseCase();
}
streamStats.emplace_back(stream->getWidth(), stream->getHeight(),
stream->getFormat(), stream->getDataSpace(), usage,
stream->getMaxHalBuffers(),
stream->getMaxTotalBuffers() - stream->getMaxHalBuffers(),
- stream->getDynamicRangeProfile());
+ stream->getDynamicRangeProfile(), streamUseCase);
}
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 6c4ba49..d466ae4 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -134,7 +134,8 @@
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
int dynamicRangeProfile =
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) override;
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) override;
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
@@ -146,7 +147,8 @@
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
int dynamicRangeProfile =
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) override;
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) override;
status_t createInputStream(
uint32_t width, uint32_t height, int format, bool isMultiResolution,
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index ba97367..dc3a6f3 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -34,11 +34,11 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile, int streamUseCase) :
Camera3Stream(id, type,
width, height, maxSize, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile),
+ dynamicRangeProfile, streamUseCase),
mTotalBufferCount(0),
mHandoutTotalBufferCount(0),
mHandoutOutputBufferCount(0),
@@ -89,6 +89,7 @@
lines.appendFormat(" Physical camera id: %s\n", camera_stream::physical_camera_id);
}
lines.appendFormat(" Dynamic Range Profile: 0x%x", camera_stream::dynamic_range_profile);
+ lines.appendFormat(" Stream use case: %d\n", camera_stream::use_case);
lines.appendFormat(" Frames produced: %d, last timestamp: %" PRId64 " ns\n",
mFrameCount, mLastTimestamp);
lines.appendFormat(" Total buffers: %zu, currently dequeued: %zu\n",
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 518ee42..f2b1536 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -38,7 +38,8 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
public:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 69723b6..d52d1e3 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -46,11 +46,12 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile,
+ int streamUseCase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile),
+ dynamicRangeProfile, streamUseCase),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -75,10 +76,11 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile,
+ int streamUseCase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height, maxSize,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
- setId, isMultiResolution, dynamicRangeProfile),
+ setId, isMultiResolution, dynamicRangeProfile, streamUseCase),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -110,11 +112,12 @@
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile,
+ int streamUseCase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile),
+ dynamicRangeProfile, streamUseCase),
mConsumer(nullptr),
mTransform(0),
mTraceFirstBuffer(true),
@@ -152,12 +155,12 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
uint64_t consumerUsage, nsecs_t timestampOffset,
int setId, bool isMultiResolution,
- int dynamicRangeProfile) :
+ int dynamicRangeProfile, int streamUseCase) :
Camera3IOStreamBase(id, type, width, height,
/*maxSize*/0,
format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile),
+ dynamicRangeProfile, streamUseCase),
mTransform(0),
mTraceFirstBuffer(true),
mUseMonoTimestamp(false),
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index d9bf62a..7d2d32e 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -90,7 +90,8 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
/**
* Set up a stream for formats that have a variable buffer size for the same
* dimensions, such as compressed JPEG.
@@ -103,7 +104,8 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
/**
* Set up a stream with deferred consumer for formats that have 2 dimensions, such as
* RAW and YUV. The consumer must be set before using this stream for output. A valid
@@ -115,7 +117,8 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
virtual ~Camera3OutputStream();
@@ -243,7 +246,8 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
/**
* Note that we release the lock briefly in this function
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index 0e2671a..fbd1e56 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -33,10 +33,12 @@
camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool useHalBufManager, int dynamicProfile) :
+ int setId, bool useHalBufManager, int dynamicProfile,
+ int streamUseCase) :
Camera3OutputStream(id, CAMERA_STREAM_OUTPUT, width, height,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
- consumerUsage, timestampOffset, setId, dynamicProfile),
+ consumerUsage, timestampOffset, setId, /*isMultiResolution*/false,
+ dynamicProfile, streamUseCase),
mUseHalBufManager(useHalBufManager) {
size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
if (surfaces.size() > consumerCount) {
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index fafa26f..223d52b 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -41,7 +41,8 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID,
bool useHalBufManager = false,
- int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
virtual ~Camera3SharedOutputStream();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 83f9a98..6b093b3 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -54,7 +54,8 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile,
+ int streamUseCase) :
camera_stream(),
mId(id),
mSetId(setId),
@@ -91,6 +92,7 @@
camera_stream::physical_camera_id = mPhysicalCameraId.string();
camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
camera_stream::dynamic_range_profile = dynamicRangeProfile;
+ camera_stream::use_case = streamUseCase;
if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
maxSize == 0) {
@@ -175,6 +177,10 @@
return camera_stream::max_buffers;
}
+int Camera3Stream::getStreamUseCase() const {
+ return camera_stream::use_case;
+}
+
void Camera3Stream::setOfflineProcessingSupport(bool support) {
mSupportOfflineProcessing = support;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index bbbea8d..ada570b 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -178,6 +178,7 @@
android_dataspace getOriginalDataSpace() const;
int getMaxHalBuffers() const;
const String8& physicalCameraId() const;
+ int getStreamUseCase() const;
void setOfflineProcessingSupport(bool) override;
bool getOfflineProcessingSupport() const override;
@@ -505,7 +506,8 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile);
+ int setId, bool isMultiResolution, int dynamicRangeProfile,
+ int streamUseCase);
wp<Camera3StreamBufferFreedListener> mBufferFreedListener;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index ef10f0d..7b1597b 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -65,6 +65,7 @@
std::unordered_set<int32_t> sensor_pixel_modes_used;
int dynamic_range_profile;
+ int use_case;
} camera_stream_t;
typedef struct camera_stream_buffer {
@@ -109,16 +110,19 @@
bool supportsOffline = false;
std::unordered_set<int32_t> sensorPixelModesUsed;
int dynamicRangeProfile;
+ int streamUseCase;
OutputStreamInfo() :
width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
consumerUsage(0),
- dynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {}
+ dynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
+ streamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {}
OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
uint64_t _consumerUsage, const std::unordered_set<int32_t>& _sensorPixelModesUsed,
- int _dynamicRangeProfile) :
+ int _dynamicRangeProfile, int _streamUseCase) :
width(_width), height(_height), format(_format),
dataSpace(_dataSpace), consumerUsage(_consumerUsage),
- sensorPixelModesUsed(_sensorPixelModesUsed), dynamicRangeProfile(_dynamicRangeProfile){}
+ sensorPixelModesUsed(_sensorPixelModesUsed), dynamicRangeProfile(_dynamicRangeProfile),
+ streamUseCase(_streamUseCase) {}
};
/**
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 7b7a2a2..87cf99a 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -65,6 +65,7 @@
using namespace android::hardware::camera;
using namespace android::hardware::camera::device::V3_2;
using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
+using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases;
namespace android {
@@ -969,8 +970,16 @@
__FUNCTION__, src->dynamic_range_profile);
return BAD_VALUE;
}
+ if (src->use_case != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT &&
+ mHidlSession_3_8 == nullptr) {
+ ALOGE("%s: Camera device doesn't support non-default stream use case %d!",
+ __FUNCTION__, src->use_case);
+ return BAD_VALUE;
+ }
dst3_8.v3_7 = dst3_7;
dst3_8.dynamicRangeProfile = mapToHidlDynamicProfile(src->dynamic_range_profile);
+ dst3_8.useCase =
+ static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(src->use_case);
activeStreams.insert(streamId);
// Create Buffer ID map if necessary
mBufferRecords.tryCreateBufferCache(streamId);
@@ -992,7 +1001,6 @@
requestedConfiguration3_4.sessionParams.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
sessionParamSize);
- requestedConfiguration3_7.operationMode = operationMode;
requestedConfiguration3_7.sessionParams.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
sessionParamSize);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index f826d83..548fb0b 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -31,6 +31,7 @@
using android::hardware::camera2::ICameraDeviceUser;
using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
+using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases;
namespace android {
namespace camera3 {
@@ -310,11 +311,30 @@
}
}
+bool isStreamUseCaseSupported(int streamUseCase,
+ const CameraMetadata &deviceInfo) {
+ camera_metadata_ro_entry_t availableStreamUseCases =
+ deviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES);
+
+ if (availableStreamUseCases.count == 0 &&
+ streamUseCase == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ return true;
+ }
+
+ for (size_t i = 0; i < availableStreamUseCases.count; i++) {
+ if (availableStreamUseCases.data.i32[i] == streamUseCase) {
+ return true;
+ }
+ }
+ return false;
+}
+
binder::Status createSurfaceFromGbp(
OutputStreamInfo& streamInfo, bool isStreamInfoValid,
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
- const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile){
+ const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
+ int streamUseCase) {
// bufferProducer must be non-null
if (gbp == nullptr) {
String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
@@ -427,6 +447,13 @@
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
+ if (!SessionConfigurationUtils::isStreamUseCaseSupported(streamUseCase,
+ physicalCameraMetadata)) {
+ String8 msg = String8::format("Camera %s: stream use case %d not supported,"
+ " failed to create output stream", logicalCameraId.string(), streamUseCase);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
if (!isStreamInfoValid) {
streamInfo.width = width;
@@ -436,6 +463,7 @@
streamInfo.consumerUsage = consumerUsage;
streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
streamInfo.dynamicRangeProfile = dynamicRangeProfile;
+ streamInfo.streamUseCase = streamUseCase;
return binder::Status::ok();
}
if (width != streamInfo.width) {
@@ -506,6 +534,8 @@
stream->dynamicRangeProfile =
static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
streamInfo.dynamicRangeProfile);
+ stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
+ streamInfo.streamUseCase);
}
binder::Status checkPhysicalCameraId(
@@ -666,6 +696,7 @@
return res;
}
+ int streamUseCase = it.getStreamUseCase();
if (deferredConsumer) {
streamInfo.width = it.getWidth();
streamInfo.height = it.getHeight();
@@ -686,6 +717,7 @@
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Deferred surface sensor pixel modes not valid");
}
+ streamInfo.streamUseCase = streamUseCase;
mapStreamInfo(streamInfo, camera3::CAMERA_STREAM_ROTATION_0, physicalCameraId, groupId,
&streamConfiguration.streams[streamIdx++]);
isStreamInfoValid = true;
@@ -698,7 +730,8 @@
for (auto& bufferProducer : bufferProducers) {
sp<Surface> surface;
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
- logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile);
+ logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,
+ streamUseCase);
if (!res.isOk())
return res;
@@ -851,6 +884,11 @@
// image
return false;
}
+ if (static_cast<int32_t>(streamConfigV38.streams[i].useCase) !=
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ // ICameraDevice older than 3.8 doesn't support stream use case
+ return false;
+ }
streamConfigV37.streams[i] = streamConfigV38.streams[i].v3_7;
}
streamConfigV37.operationMode = streamConfigV38.operationMode;
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 9a5dc2c..8dfc11d 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -94,13 +94,15 @@
// Create a Surface from an IGraphicBufferProducer. Returns error if
// IGraphicBufferProducer's property doesn't match with streamInfo
binder::Status createSurfaceFromGbp(
-camera3::OutputStreamInfo& streamInfo, bool isStreamInfoValid,
-sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
-const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
-const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile);
+ camera3::OutputStreamInfo& streamInfo, bool isStreamInfoValid,
+ sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
+ const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
+ const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
+ int streamUseCase);
+
void mapStreamInfo(const camera3::OutputStreamInfo &streamInfo,
camera3::camera_stream_rotation_t rotation, String8 physicalId, int32_t groupId,
- hardware::camera::device::V3_7::Stream *stream /*out*/);
+ hardware::camera::device::V3_8::Stream *stream /*out*/);
//check if format is 10-bit output compatible
bool is10bitCompatibleFormat(int32_t format);
@@ -111,6 +113,8 @@
// Check if the device supports a given dynamicRangeProfile
bool isDynamicRangeProfileSupported(int dynamicRangeProfile, const CameraMetadata& staticMeta);
+bool isStreamUseCaseSupported(int streamUseCase, const CameraMetadata &deviceInfo);
+
// Check that the physicalCameraId passed in is spported by the camera
// device.
binder::Status checkPhysicalCameraId(