QCamera2: HAL3: Adjust buffer timeout depending on expected duration
The timeout used for detecting buffers that are overdue
should be further adjusted based on the expected frame duration.
Bug: 63448299
Test: Camera CTS
Change-Id: I4a1e950437cd1fa10b1bc4b04925c8f5ded92991
diff --git a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
index ed9bf0f..15757a6 100644
--- a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
@@ -97,7 +97,7 @@
#define REGIONS_TUPLE_COUNT 5
#define HDR_PLUS_PERF_TIME_OUT (7000) // milliseconds
// Set a threshold for detection of missing buffers //seconds
-#define MISSING_REQUEST_BUF_TIMEOUT 10
+#define MISSING_REQUEST_BUF_TIMEOUT 5
#define MISSING_HDRPLUS_REQUEST_BUF_TIMEOUT 30
#define FLUSH_TIMEOUT 3
#define METADATA_MAP_SIZE(MAP) (sizeof(MAP)/sizeof(MAP[0]))
@@ -479,6 +479,8 @@
mMinProcessedFrameDuration(0),
mMinJpegFrameDuration(0),
mMinRawFrameDuration(0),
+ mExpectedFrameDuration(0),
+ mExpectedInflightDuration(0),
mMetaFrameCount(0U),
mUpdateDebugLevel(false),
mCallbacks(callbacks),
@@ -797,6 +799,13 @@
}
if (i->settings != NULL)
free_camera_metadata((camera_metadata_t*)i->settings);
+
+ mExpectedInflightDuration -= i->expectedFrameDuration;
+ if (mExpectedInflightDuration < 0) {
+ LOGE("Negative expected in-flight duration!");
+ mExpectedInflightDuration = 0;
+ }
+
return mPendingRequestsList.erase(i);
}
@@ -3021,6 +3030,8 @@
req.mPendingBufferList.clear();
}
mPendingBuffersMap.mPendingBuffersInRequest.clear();
+ mExpectedInflightDuration = 0;
+ mExpectedFrameDuration = 0;
mCurJpegMeta.clear();
//Get min frame duration for this streams configuration
@@ -3649,6 +3660,9 @@
// HDR+ request is done. So allow a longer timeout.
timeout = (mHdrPlusPendingRequests.size() > 0) ?
MISSING_HDRPLUS_REQUEST_BUF_TIMEOUT : MISSING_REQUEST_BUF_TIMEOUT;
+ if (timeout < mExpectedInflightDuration) {
+ timeout = mExpectedInflightDuration;
+ }
}
if ( (currentSysTime - req.timestamp) > s2ns(timeout) ) {
@@ -5479,6 +5493,8 @@
}
pendingRequest.fwkCacMode = mCacMode;
pendingRequest.hdrplus = hdrPlusRequest;
+ pendingRequest.expectedFrameDuration = mExpectedFrameDuration;
+ mExpectedInflightDuration += mExpectedFrameDuration;
// extract enableZsl info
if (gExposeEnableZslKey) {
@@ -11434,6 +11450,89 @@
}
/*===========================================================================
+ * FUNCTION : getExpectedFrameDuration
+ *
+ * DESCRIPTION: Extract the maximum frame duration from either exposure or frame
+ * duration
+ *
+ * PARAMETERS :
+ * @request : request settings
+ * @frameDuration : The maximum frame duration in nanoseconds
+ *
+ * RETURN : None
+ *==========================================================================*/
+void QCamera3HardwareInterface::getExpectedFrameDuration(
+ const camera_metadata_t *request, nsecs_t *frameDuration /*out*/) {
+ if (nullptr == frameDuration) {
+ return;
+ }
+
+ camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
+ find_camera_metadata_ro_entry(request,
+ ANDROID_SENSOR_EXPOSURE_TIME,
+ &e);
+ if (e.count > 0) {
+ *frameDuration = e.data.i64[0];
+ }
+ find_camera_metadata_ro_entry(request,
+ ANDROID_SENSOR_FRAME_DURATION,
+ &e);
+ if (e.count > 0) {
+ *frameDuration = std::max(e.data.i64[0], *frameDuration);
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : calculateMaxExpectedDuration
+ *
+ * DESCRIPTION: Calculate the expected frame duration in nanoseconds given the
+ * current camera settings.
+ *
+ * PARAMETERS :
+ * @request : request settings
+ *
+ * RETURN : Expected frame duration in nanoseconds.
+ *==========================================================================*/
+nsecs_t QCamera3HardwareInterface::calculateMaxExpectedDuration(
+ const camera_metadata_t *request) {
+ nsecs_t maxExpectedDuration = kDefaultExpectedDuration;
+ camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
+ find_camera_metadata_ro_entry(request, ANDROID_CONTROL_MODE, &e);
+ if (e.count == 0) {
+ return maxExpectedDuration;
+ }
+
+ if (e.data.u8[0] == ANDROID_CONTROL_MODE_OFF) {
+ getExpectedFrameDuration(request, &maxExpectedDuration /*out*/);
+ }
+
+ if (e.data.u8[0] != ANDROID_CONTROL_MODE_AUTO) {
+ return maxExpectedDuration;
+ }
+
+ find_camera_metadata_ro_entry(request, ANDROID_CONTROL_AE_MODE, &e);
+ if (e.count == 0) {
+ return maxExpectedDuration;
+ }
+
+ switch (e.data.u8[0]) {
+ case ANDROID_CONTROL_AE_MODE_OFF:
+ getExpectedFrameDuration(request, &maxExpectedDuration /*out*/);
+ break;
+ default:
+ find_camera_metadata_ro_entry(request,
+ ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+ &e);
+ if (e.count > 1) {
+ maxExpectedDuration = 1e9 / e.data.u8[0];
+ }
+ break;
+ }
+
+ return maxExpectedDuration;
+}
+
+/*===========================================================================
* FUNCTION : setFrameParameters
*
* DESCRIPTION: set parameters per frame as requested in the metadata from
@@ -11489,6 +11588,7 @@
}
if(request->settings != NULL){
+ mExpectedFrameDuration = calculateMaxExpectedDuration(request->settings);
rc = translateToHalMetadata(request, mParameters, snapshotStreamId);
if (blob_request)
memcpy(mPrevParameters, mParameters, sizeof(metadata_buffer_t));
@@ -14132,6 +14232,8 @@
mShutterDispatcher.clear();
mOutputBufferDispatcher.clear(/*clearConfiguredStreams*/false);
mPendingBuffersMap.mPendingBuffersInRequest.clear();
+ mExpectedFrameDuration = 0;
+ mExpectedInflightDuration = 0;
LOGH("Cleared all the pending buffers ");
return NO_ERROR;