Fix lock mechanism in v4l2 camera HAL
Both in_flight_lock_ lock in v4l2_camera.cpp and buffer_queue_lock_ in
v4l2_wrapper.cpp have problems that guards the buffer indices and in
flight buffer vector incorrectly. Those problem leads to mismatching in
terms of buffer size between the HAL and Camera3Device and eventually
the Camera3Device will stop to wait for buffers that HAL will not post
in the future.
Bug: 69076261
Test: Camera samples app doesn't stuck with FB impl.
Exempt-From-Owner-Approval: got +2 from the HAL maintainer.
Change-Id: I3d0a4361d46571fd144a5eb8bc160296a31d6358
diff --git a/modules/camera/3_4/v4l2_wrapper.cpp b/modules/camera/3_4/v4l2_wrapper.cpp
index 3fafffd..b5a1c71 100644
--- a/modules/camera/3_4/v4l2_wrapper.cpp
+++ b/modules/camera/3_4/v4l2_wrapper.cpp
@@ -535,6 +535,7 @@
std::lock_guard<std::mutex> guard(buffer_queue_lock_);
for (int i = 0; i < buffers_.size(); ++i) {
if (!buffers_[i]) {
+ buffers_[i] = true;
index = i;
break;
}
@@ -557,6 +558,9 @@
// and fill out remaining fields.
if (IoctlLocked(VIDIOC_QUERYBUF, &device_buffer) < 0) {
HAL_LOGE("QUERYBUF fails: %s", strerror(errno));
+ // Return buffer index.
+ std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+ buffers_[index] = false;
return -ENODEV;
}
@@ -565,18 +569,20 @@
gralloc_->lock(camera_buffer, format_->bytes_per_line(), &device_buffer);
if (res) {
HAL_LOGE("Gralloc failed to lock buffer.");
+ // Return buffer index.
+ std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+ buffers_[index] = false;
return res;
}
if (IoctlLocked(VIDIOC_QBUF, &device_buffer) < 0) {
HAL_LOGE("QBUF fails: %s", strerror(errno));
gralloc_->unlock(&device_buffer);
+ // Return buffer index.
+ std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+ buffers_[index] = false;
return -ENODEV;
}
- // Mark the buffer as in flight.
- std::lock_guard<std::mutex> guard(buffer_queue_lock_);
- buffers_[index] = true;
-
if (enqueued_index) {
*enqueued_index = index;
}