Camera3: Fix the deadlock during recording pinch zooming
When zooming during recording, hal callback thread and request update thread run
into deadlock due to lock circular dependency. This change release lock during
queuebuffer in callback thread to break the dependency.
Bug: 9091576
Change-Id: Ia7b3f0ec17573cb32a5696dcde419ca28f42cfb8
diff --git a/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp b/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
index a2c97d4..2efeede 100644
--- a/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
@@ -166,11 +166,20 @@
int anwReleaseFence = releaseFence->dup();
/**
+ * Release the lock briefly to avoid deadlock with
+ * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this
+ * thread will go into StreamingProcessor::onFrameAvailable) during
+ * queueBuffer
+ */
+ sp<ANativeWindow> currentConsumer = mConsumer;
+ mLock.unlock();
+
+ /**
* Return buffer back to ANativeWindow
*/
if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
// Cancel buffer
- res = mConsumer->cancelBuffer(mConsumer.get(),
+ res = currentConsumer->cancelBuffer(currentConsumer.get(),
container_of(buffer.buffer, ANativeWindowBuffer, handle),
anwReleaseFence);
if (res != OK) {
@@ -178,7 +187,7 @@
" %s (%d)", __FUNCTION__, mId, strerror(-res), res);
}
} else {
- res = mConsumer->queueBuffer(mConsumer.get(),
+ res = currentConsumer->queueBuffer(currentConsumer.get(),
container_of(buffer.buffer, ANativeWindowBuffer, handle),
anwReleaseFence);
if (res != OK) {
@@ -186,7 +195,7 @@
"%s (%d)", __FUNCTION__, mId, strerror(-res), res);
}
}
-
+ mLock.lock();
if (res != OK) {
close(anwReleaseFence);
return res;
diff --git a/services/camera/libcameraservice/camera3/Camera3OutputStream.h b/services/camera/libcameraservice/camera3/Camera3OutputStream.h
index ce317f9..774fbdd 100644
--- a/services/camera/libcameraservice/camera3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/camera3/Camera3OutputStream.h
@@ -66,6 +66,9 @@
Camera3OutputStream(int id, camera3_stream_type_t type,
uint32_t width, uint32_t height, int format);
+ /**
+ * Note that we release the lock briefly in this function
+ */
virtual status_t returnBufferCheckedLocked(
const camera3_stream_buffer &buffer,
nsecs_t timestamp,