summaryrefslogtreecommitdiff
path: root/src/android/camera_stream.cpp
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2021-09-24 17:59:20 +0200
committerJacopo Mondi <jacopo@jmondi.org>2021-09-29 20:29:07 +0200
commit2eca16b674ff9e849d7681fbc670325de87ad0a2 (patch)
treee007d0860173186c024fec060a8f31c4f80ec321 /src/android/camera_stream.cpp
parentc8c1d07cea2d8ef63905bf4f0b5266a5e6fd749f (diff)
android: Wait on fences in CameraStream::process()
Acquire fences for streams of type Mapped generated by post-processing are not correctly handled and are currently ignored by the camera HAL. Fix this by adding CameraStream::waitFence(), executed before starting the post-processing in CameraStream::process(). The change applies to all streams generated by post-processing (Mapped and Internal) but currently acquire fences of Internal streams are handled by the camera worker. Postpone that to post-processing time by passing -1 to the Worker for Internal streams. Also correct the release_fence handling for failed captures, as the framework requires the release fences to be set to the acquire fence value if the acquire fence has not been waited on. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Tested-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/android/camera_stream.cpp')
-rw-r--r--src/android/camera_stream.cpp50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp
index e30c7ee4..e80f842d 100644
--- a/src/android/camera_stream.cpp
+++ b/src/android/camera_stream.cpp
@@ -7,7 +7,11 @@
#include "camera_stream.h"
+#include <errno.h>
+#include <string.h>
#include <sys/mman.h>
+#include <sys/poll.h>
+#include <unistd.h>
#include <libcamera/formats.h>
@@ -109,11 +113,53 @@ int CameraStream::configure()
return 0;
}
+int CameraStream::waitFence(int fence)
+{
+ /*
+ * \todo The implementation here is copied from camera_worker.cpp
+ * and both should be removed once libcamera is instrumented to handle
+ * fences waiting in the core.
+ *
+ * \todo Better characterize the timeout. Currently equal to the one
+ * used by the Rockchip Camera HAL on ChromeOS.
+ */
+ constexpr unsigned int timeoutMs = 300;
+ struct pollfd fds = { fence, POLLIN, 0 };
+
+ do {
+ int ret = poll(&fds, 1, timeoutMs);
+ if (ret == 0)
+ return -ETIME;
+
+ if (ret > 0) {
+ if (fds.revents & (POLLERR | POLLNVAL))
+ return -EINVAL;
+
+ return 0;
+ }
+ } while (errno == EINTR || errno == EAGAIN);
+
+ return -errno;
+}
+
int CameraStream::process(const FrameBuffer &source,
- buffer_handle_t camera3Dest,
+ camera3_stream_buffer_t &camera3Dest,
const CameraMetadata &requestMetadata,
CameraMetadata *resultMetadata)
{
+ /* Handle waiting on fences on the destination buffer. */
+ int fence = camera3Dest.acquire_fence;
+ if (fence != -1) {
+ int ret = waitFence(fence);
+ ::close(fence);
+ camera3Dest.acquire_fence = -1;
+ if (ret < 0) {
+ LOG(HAL, Error) << "Failed waiting for fence: "
+ << fence << ": " << strerror(-ret);
+ return ret;
+ }
+ }
+
if (!postProcessor_)
return 0;
@@ -122,7 +168,7 @@ int CameraStream::process(const FrameBuffer &source,
* separate thread.
*/
const StreamConfiguration &output = configuration();
- CameraBuffer dest(camera3Dest, formats::MJPEG, output.size,
+ CameraBuffer dest(*camera3Dest.buffer, formats::MJPEG, output.size,
PROT_READ | PROT_WRITE);
if (!dest.isValid()) {
LOG(HAL, Error) << "Failed to map android blob buffer";