Camera: Detect session parameter updates and re-configure camera
Camera clients are allowed to change session parameters during
active session, however some camera devices might not be able
to apply them without additional stream configuration. To resolve
this, detect whether any of the available session parameter changes
in the queued requests and re-configure the camera before trying
to apply it.
Bug: 64450664
Test: Manual, Camera CTS
Change-Id: I005d6b7d6c6b27d4b5bac4b0d0809c7c019af9a4
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index fbe8f4f..83ce18a 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -140,6 +140,75 @@
return mOriginalDataSpace;
}
+status_t Camera3Stream::forceToIdle() {
+ ATRACE_CALL();
+ Mutex::Autolock l(mLock);
+ status_t res;
+
+ switch (mState) {
+ case STATE_ERROR:
+ case STATE_CONSTRUCTED:
+ case STATE_IN_CONFIG:
+ case STATE_PREPARING:
+ case STATE_IN_RECONFIG:
+ ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
+ res = NO_INIT;
+ break;
+ case STATE_CONFIGURED:
+ if (hasOutstandingBuffersLocked()) {
+ sp<StatusTracker> statusTracker = mStatusTracker.promote();
+ if (statusTracker != 0) {
+ statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
+ }
+ }
+
+ mState = STATE_IN_IDLE;
+ res = OK;
+
+ break;
+ default:
+ ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
+ res = NO_INIT;
+ }
+
+ return res;
+}
+
+status_t Camera3Stream::restoreConfiguredState() {
+ ATRACE_CALL();
+ Mutex::Autolock l(mLock);
+ status_t res;
+
+ switch (mState) {
+ case STATE_ERROR:
+ case STATE_CONSTRUCTED:
+ case STATE_IN_CONFIG:
+ case STATE_PREPARING:
+ case STATE_IN_RECONFIG:
+ case STATE_CONFIGURED:
+ ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
+ res = NO_INIT;
+ break;
+ case STATE_IN_IDLE:
+ if (hasOutstandingBuffersLocked()) {
+ sp<StatusTracker> statusTracker = mStatusTracker.promote();
+ if (statusTracker != 0) {
+ statusTracker->markComponentActive(mStatusId);
+ }
+ }
+
+ mState = STATE_CONFIGURED;
+ res = OK;
+
+ break;
+ default:
+ ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
+ res = NO_INIT;
+ }
+
+ return res;
+}
+
camera3_stream* Camera3Stream::startConfiguration() {
ATRACE_CALL();
Mutex::Autolock l(mLock);
@@ -150,6 +219,7 @@
ALOGE("%s: In error state", __FUNCTION__);
return NULL;
case STATE_CONSTRUCTED:
+ case STATE_IN_IDLE:
// OK
break;
case STATE_IN_CONFIG:
@@ -179,6 +249,11 @@
return NULL;
}
+ if (mState == STATE_IN_IDLE) {
+ // Skip configuration.
+ return this;
+ }
+
// Stop tracking if currently doing so
if (mStatusId != StatusTracker::NO_STATUS_ID) {
sp<StatusTracker> statusTracker = mStatusTracker.promote();
@@ -219,6 +294,9 @@
ALOGE("%s: Cannot finish configuration that hasn't been started",
__FUNCTION__);
return INVALID_OPERATION;
+ case STATE_IN_IDLE:
+ //Skip configuration in this state
+ return OK;
default:
ALOGE("%s: Unknown state", __FUNCTION__);
return INVALID_OPERATION;
@@ -267,6 +345,7 @@
return INVALID_OPERATION;
case STATE_IN_CONFIG:
case STATE_IN_RECONFIG:
+ case STATE_IN_IDLE:
// OK
break;
case STATE_CONSTRUCTED:
@@ -282,7 +361,9 @@
mUsage = mOldUsage;
camera3_stream::max_buffers = mOldMaxBuffers;
- mState = (mState == STATE_IN_RECONFIG) ? STATE_CONFIGURED : STATE_CONSTRUCTED;
+ mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
+ STATE_CONSTRUCTED;
+
return OK;
}