summaryrefslogtreecommitdiffstats
path: root/services/camera
diff options
context:
space:
mode:
authorZhijun He <zhijunhe@google.com>2013-05-22 14:01:30 -0700
committerZhijun He <zhijunhe@google.com>2013-05-23 13:12:12 -0700
commit124ccf4b5023a40c57b49981123e6c9b61408a5d (patch)
treee26d6244a932977b13db3815403aec7e540af34d /services/camera
parented49d7b57e66cc2520817b345ef9de289d688bd4 (diff)
downloadframeworks_av-124ccf4b5023a40c57b49981123e6c9b61408a5d.zip
frameworks_av-124ccf4b5023a40c57b49981123e6c9b61408a5d.tar.gz
frameworks_av-124ccf4b5023a40c57b49981123e6c9b61408a5d.tar.bz2
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
Diffstat (limited to 'services/camera')
-rw-r--r--services/camera/libcameraservice/camera3/Camera3OutputStream.cpp15
-rw-r--r--services/camera/libcameraservice/camera3/Camera3OutputStream.h3
2 files changed, 15 insertions, 3 deletions
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 @@ status_t Camera3OutputStream::returnBufferCheckedLocked(
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 @@ status_t Camera3OutputStream::returnBufferCheckedLocked(
" %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 @@ status_t Camera3OutputStream::returnBufferCheckedLocked(
"%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 @@ class Camera3OutputStream :
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,