Camera: clear buffer cache when stream is reconfigured
Also fix a issue for finishConfiguration is unintentionally
delayed till first capture request.
Test: Camera CTS + partner device testing
Bug: 126390310
Change-Id: Ibca740a7160cbf41e01884dbcef8ba51eb4c75f7
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 415b2d8..f4abba4 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2522,6 +2522,9 @@
CLOGE("Stream %d is unknown", streamId);
return BAD_VALUE;
}
+
+ // isConsumerConfigurationDeferred will be off after setConsumers
+ bool isDeferred = stream->isConsumerConfigurationDeferred();
status_t res = stream->setConsumers(consumers);
if (res != OK) {
CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
@@ -2537,7 +2540,7 @@
surfaceIds->push_back(id);
}
- if (stream->isConsumerConfigurationDeferred()) {
+ if (isDeferred) {
if (!stream->isConfiguring()) {
CLOGE("Stream %d was already fully configured.", streamId);
return INVALID_OPERATION;
@@ -2612,7 +2615,6 @@
sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
ATRACE_CALL();
- status_t res;
sp<CaptureRequest> newRequest = new CaptureRequest;
newRequest->mSettingsList = request;
@@ -2626,16 +2628,11 @@
inputStreams.data.u8[0]);
return NULL;
}
- // Lazy completion of stream configuration (allocation/registration)
- // on first use
+
if (mInputStream->isConfiguring()) {
- res = mInputStream->finishConfiguration();
- if (res != OK) {
- SET_ERR_L("Unable to finish configuring input stream %d:"
- " %s (%d)",
- mInputStream->getId(), strerror(-res), res);
- return NULL;
- }
+ SET_ERR_L("%s: input stream %d is not configured!",
+ __FUNCTION__, mInputStream->getId());
+ return NULL;
}
// Check if stream prepare is blocking requests.
if (mInputStream->isBlockedByPrepare()) {
@@ -2675,15 +2672,9 @@
newRequest->mOutputSurfaces[streams.data.i32[i]] = surfaces;
}
- // Lazy completion of stream configuration (allocation/registration)
- // on first use
if (stream->isConfiguring()) {
- res = stream->finishConfiguration();
- if (res != OK) {
- SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
- stream->getId(), strerror(-res), res);
- return NULL;
- }
+ SET_ERR_L("%s: stream %d is not configured!", __FUNCTION__, stream->getId());
+ return NULL;
}
// Check if stream prepare is blocking requests.
if (stream->isBlockedByPrepare()) {
@@ -2908,7 +2899,8 @@
// faster
if (mInputStream != NULL && mInputStream->isConfiguring()) {
- res = mInputStream->finishConfiguration();
+ bool streamReConfigured = false;
+ res = mInputStream->finishConfiguration(&streamReConfigured);
if (res != OK) {
CLOGE("Can't finish configuring input stream %d: %s (%d)",
mInputStream->getId(), strerror(-res), res);
@@ -2918,12 +2910,16 @@
}
return BAD_VALUE;
}
+ if (streamReConfigured) {
+ mInterface->onStreamReConfigured(mInputStream->getId());
+ }
}
for (size_t i = 0; i < mOutputStreams.size(); i++) {
sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
- res = outputStream->finishConfiguration();
+ bool streamReConfigured = false;
+ res = outputStream->finishConfiguration(&streamReConfigured);
if (res != OK) {
CLOGE("Can't finish configuring output stream %d: %s (%d)",
outputStream->getId(), strerror(-res), res);
@@ -2933,6 +2929,9 @@
}
return BAD_VALUE;
}
+ if (streamReConfigured) {
+ mInterface->onStreamReConfigured(outputStream->getId());
+ }
}
}
@@ -4780,7 +4779,7 @@
__FUNCTION__, handle, streamId);
return;
} else {
- bufferId = it->second;
+ bufferId = it->second;
bIdMap.erase(it);
ALOGV("%s: stream %d now have %zu buffer caches after removing buf %p",
__FUNCTION__, streamId, bIdMap.size(), handle);
@@ -4788,6 +4787,22 @@
mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
}
+void Camera3Device::HalInterface::onStreamReConfigured(int streamId) {
+ std::lock_guard<std::mutex> lock(mBufferIdMapLock);
+ auto mapIt = mBufferIdMaps.find(streamId);
+ if (mapIt == mBufferIdMaps.end()) {
+ ALOGE("%s: streamId %d not found!", __FUNCTION__, streamId);
+ return;
+ }
+
+ BufferIdMap& bIdMap = mapIt->second;
+ for (const auto& it : bIdMap) {
+ uint64_t bufferId = it.second;
+ mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
+ }
+ bIdMap.clear();
+}
+
/**
* RequestThread inner class methods
*/