QCamera2: HAL3: Validate usage flags for configure_streams
If usage flag has combined bits from different consumers, fail
configure_streams if camera device doesn't support it.
Camera device take into consideration of below 3 factors:
- stream format
- stream dataspace, and
- HAL interface restriction
Test: Camera CTS
Bug: 33777818
Change-Id: Ie2b2ad44de74ad908269bc23c8ce8ce065153a8f
diff --git a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
index 1a0ec8a..26de733 100644
--- a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
@@ -1240,6 +1240,98 @@
return rc;
}
+/*===========================================================================
+ * FUNCTION : validateUsageFlags
+ *
+ * DESCRIPTION: Check if the configuration usage flags map to same internal format.
+ *
+ * PARAMETERS :
+ * @stream_list : streams to be configured
+ *
+ * RETURN :
+ * NO_ERROR if the usage flags are supported
+ * error code if usage flags are not supported
+ *
+ *==========================================================================*/
+int QCamera3HardwareInterface::validateUsageFlags(
+ const camera3_stream_configuration_t* streamList)
+{
+ for (size_t j = 0; j < streamList->num_streams; j++) {
+ const camera3_stream_t *newStream = streamList->streams[j];
+
+ if (newStream->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+ (newStream->stream_type != CAMERA3_STREAM_OUTPUT &&
+ newStream->stream_type != CAMERA3_STREAM_BIDIRECTIONAL)) {
+ continue;
+ }
+
+ bool isVideo = IS_USAGE_VIDEO(newStream->usage);
+ bool isPreview = IS_USAGE_PREVIEW(newStream->usage);
+ bool isZSL = IS_USAGE_ZSL(newStream->usage);
+ bool forcePreviewUBWC = true;
+ if (isVideo && !QCameraCommon::isVideoUBWCEnabled()) {
+ forcePreviewUBWC = false;
+ }
+ cam_format_t videoFormat = QCamera3Channel::getStreamDefaultFormat(
+ CAM_STREAM_TYPE_VIDEO, newStream->width, newStream->height, forcePreviewUBWC);
+ cam_format_t previewFormat = QCamera3Channel::getStreamDefaultFormat(
+ CAM_STREAM_TYPE_PREVIEW, newStream->width, newStream->height, forcePreviewUBWC);
+ cam_format_t zslFormat = QCamera3Channel::getStreamDefaultFormat(
+ CAM_STREAM_TYPE_SNAPSHOT, newStream->width, newStream->height, forcePreviewUBWC);
+
+ // Color space for this camera device is guaranteed to be ITU_R_601_FR.
+ // So color spaces will always match.
+
+ // Check whether underlying formats of shared streams match.
+ if (isVideo && isPreview && videoFormat != previewFormat) {
+ LOGE("Combined video and preview usage flag is not supported");
+ return -EINVAL;
+ }
+ if (isPreview && isZSL && previewFormat != zslFormat) {
+ LOGE("Combined preview and zsl usage flag is not supported");
+ return -EINVAL;
+ }
+ if (isVideo && isZSL && videoFormat != zslFormat) {
+ LOGE("Combined video and zsl usage flag is not supported");
+ return -EINVAL;
+ }
+ }
+ return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION : validateUsageFlagsForEis
+ *
+ * DESCRIPTION: Check if the configuration usage flags conflict with Eis
+ *
+ * PARAMETERS :
+ * @stream_list : streams to be configured
+ *
+ * RETURN :
+ * NO_ERROR if the usage flags are supported
+ * error code if usage flags are not supported
+ *
+ *==========================================================================*/
+int QCamera3HardwareInterface::validateUsageFlagsForEis(
+ const camera3_stream_configuration_t* streamList)
+{
+ for (size_t j = 0; j < streamList->num_streams; j++) {
+ const camera3_stream_t *newStream = streamList->streams[j];
+
+ bool isVideo = IS_USAGE_VIDEO(newStream->usage);
+ bool isPreview = IS_USAGE_PREVIEW(newStream->usage);
+
+ // Because EIS is "hard-coded" for certain use case, and current
+ // implementation doesn't support shared preview and video on the same
+ // stream, return failure if EIS is forced on.
+ if (isPreview && isVideo && m_bEisEnable && m_bEisSupportedSize) {
+ LOGE("Combined video and preview usage flag is not supported due to EIS");
+ return -EINVAL;
+ }
+ }
+ return NO_ERROR;
+}
+
/*==============================================================================
* FUNCTION : isSupportChannelNeeded
*
@@ -1554,6 +1646,11 @@
return BAD_VALUE;
}
+ rc = validateUsageFlags(streamList);
+ if (rc != NO_ERROR) {
+ return rc;
+ }
+
mOpMode = streamList->operation_mode;
LOGD("mOpMode: %d", mOpMode);
@@ -1619,6 +1716,7 @@
m_bVideoHdrEnabled = false;
bool isZsl = false;
bool depthPresent = false;
+ bool isPreview = false;
uint32_t videoWidth = 0U;
uint32_t videoHeight = 0U;
size_t rawStreamCnt = 0;
@@ -1700,6 +1798,11 @@
newStream->stream_type == CAMERA3_STREAM_INPUT){
isZsl = true;
}
+ if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
+ IS_USAGE_PREVIEW(newStream->usage)) {
+ isPreview = true;
+ }
+
if (newStream->stream_type == CAMERA3_STREAM_INPUT){
inputStream = newStream;
}
@@ -1731,6 +1834,7 @@
}
m_bEisSupportedSize = (newStream->width <= maxEisWidth) &&
(newStream->height <= maxEisHeight);
+
}
if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
newStream->stream_type == CAMERA3_STREAM_OUTPUT) {
@@ -1810,6 +1914,11 @@
m_bEisEnable = false;
}
+ if (validateUsageFlagsForEis(streamList) != NO_ERROR) {
+ pthread_mutex_unlock(&mMutex);
+ return -EINVAL;
+ }
+
uint8_t forceEnableTnr = 0;
char tnr_prop[PROPERTY_VALUE_MAX];
memset(tnr_prop, 0, sizeof(tnr_prop));
@@ -2253,6 +2362,7 @@
break;
}
+ bool forcePreviewUBWC = true;
if (newStream->stream_type == CAMERA3_STREAM_OUTPUT ||
newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
QCamera3ProcessingChannel *channel = NULL;
@@ -2315,13 +2425,12 @@
}
/* disable UBWC for preview, though supported,
* to take advantage of CPP duplication */
- if (m_bIsVideo && (!mCommon.isVideoUBWCEnabled()) &&
+ if (m_bIsVideo && (!QCameraCommon::isVideoUBWCEnabled()) &&
(previewSize.width == (int32_t)videoWidth)&&
(previewSize.height == (int32_t)videoHeight)){
- channel->setUBWCEnabled(false);
- }else {
- channel->setUBWCEnabled(true);
+ forcePreviewUBWC = false;
}
+ channel->setUBWCEnabled(forcePreviewUBWC);
newStream->max_buffers = channel->getNumBuffers();
newStream->priv = channel;
}
@@ -2416,10 +2525,10 @@
}
QCamera3Channel *channel = (QCamera3Channel*) newStream->priv;
- if (channel != NULL && channel->isUBWCEnabled()) {
- cam_format_t fmt = channel->getStreamDefaultFormat(
+ if (channel != NULL && QCamera3Channel::isUBWCEnabled()) {
+ cam_format_t fmt = QCamera3Channel::getStreamDefaultFormat(
mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
- newStream->width, newStream->height);
+ newStream->width, newStream->height, forcePreviewUBWC);
if(fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
newStream->usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
}