Camera: Account for any pending freed buffers during the offline switch
During offline session switches, pending buffer cache updates may not
have the ability to propagate to CameraHal due to absence of any
additional capture requests. This scenario will result in a delta between
the circulating buffers declared by Hal and the current buffer records in
camera service.
Try to detect and avoid possible switch failures in such cases.
Bug: 232892208
Test: Camera CTS
Change-Id: I835ec422131135eb884130a79642d5cb9952498b
Merged-In: I894fdac0d9a18be53560363123c3d504e2c4c701
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 3c5cb78..db2ad17 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -458,6 +458,28 @@
// Verify buffer caches
std::vector<uint64_t> bufIds(offlineStream.circulatingBufferIds.begin(),
offlineStream.circulatingBufferIds.end());
+ {
+ // Due to timing it is possible that we may not have any remaining pending
+ // capture requests that can update the caches on Hal side. This can result in
+ // buffer cache mismatch between the service and the Hal and must be accounted
+ // for.
+ std::lock_guard<std::mutex> l(mFreedBuffersLock);
+ for (const auto& it : mFreedBuffers) {
+ if (it.first == id) {
+ ALOGV("%s: stream ID %d buffer id %" PRIu64 " cache removal still "
+ "pending", __FUNCTION__, id, it.second);
+ const auto& cachedEntry = std::find(bufIds.begin(), bufIds.end(),
+ it.second);
+ if (cachedEntry != bufIds.end()) {
+ bufIds.erase(cachedEntry);
+ } else {
+ ALOGE("%s: stream ID %d buffer id %" PRIu64 " cache removal still "
+ "pending however buffer is no longer in the offline stream "
+ "info!", __FUNCTION__, id, it.second);
+ }
+ }
+ }
+ }
if (!verifyBufferIds(id, bufIds)) {
ALOGE("%s: stream ID %d buffer cache records mismatch!", __FUNCTION__, id);
return UNKNOWN_ERROR;