summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2022-05-27 18:34:38 +0900
committerJacopo Mondi <jacopo@jmondi.org>2022-06-10 11:48:09 +0200
commit7ea83eba0df612f5771ebd9ae06bf22ca6f4b915 (patch)
tree2f5a54b0ab04103e62ac79ccd1d14dc16c495cd5
parent1261ff9e935d543764db4eb620d7747caea81a87 (diff)
android: camera_device: Postpone mapped streams handling
Mapped streams are generated by post-processing and always require a source buffer to process image data from. In case a Mapped stream is requested but its source stream is not, it is required to allocate a buffer on the fly and add it to the libcamera::Request. Make sure a source stream is available for all mapped streams, and if that's not the case, add a dedicated buffer to the request for that purpose. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--src/android/camera_device.cpp64
1 files changed, 56 insertions, 8 deletions
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 773cb3b6..25fae9c8 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include <fstream>
+#include <set>
#include <sys/mman.h>
#include <unistd.h>
#include <vector>
@@ -930,6 +931,14 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie()
<< " with " << descriptor->buffers_.size() << " streams";
+ /*
+ * Process all the Direct and Internal streams first, they map directly
+ * to a libcamera stream. Streams of type Mapped will be handled later.
+ *
+ * Collect the CameraStream associated to each requested capture stream.
+ * Since requestedStreams is an std:set<>, no duplications can happen.
+ */
+ std::set<CameraStream *> requestedStreams;
for (const auto &[i, buffer] : utils::enumerate(descriptor->buffers_)) {
CameraStream *cameraStream = buffer.stream;
camera3_stream_t *camera3Stream = cameraStream->camera3Stream();
@@ -952,14 +961,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
switch (cameraStream->type()) {
case CameraStream::Type::Mapped:
- /*
- * Mapped streams don't need buffers added to the
- * Request.
- */
- LOG(HAL, Debug) << ss.str() << " (mapped)";
-
- descriptor->pendingStreamsToProcess_.insert(
- { cameraStream, &buffer });
+ /* Mapped streams will be handled in the next loop. */
continue;
case CameraStream::Type::Direct:
@@ -1003,6 +1005,52 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
auto fence = std::make_unique<Fence>(std::move(acquireFence));
descriptor->request_->addBuffer(cameraStream->stream(),
frameBuffer, std::move(fence));
+
+ requestedStreams.insert(cameraStream);
+ }
+
+ /*
+ * Now handle the Mapped streams. If no buffer has been added for them
+ * because their corresponding direct source stream is not part of this
+ * particular request, add one here.
+ */
+ for (const auto &[i, buffer] : utils::enumerate(descriptor->buffers_)) {
+ CameraStream *cameraStream = buffer.stream;
+ camera3_stream_t *camera3Stream = cameraStream->camera3Stream();
+
+ if (cameraStream->type() != CameraStream::Type::Mapped)
+ continue;
+
+ LOG(HAL, Debug) << i << " - (" << camera3Stream->width << "x"
+ << camera3Stream->height << ")"
+ << "[" << utils::hex(camera3Stream->format) << "] -> "
+ << "(" << cameraStream->configuration().size << ")["
+ << cameraStream->configuration().pixelFormat << "]"
+ << " (mapped)";
+
+ MutexLocker lock(descriptor->streamsProcessMutex_);
+ descriptor->pendingStreamsToProcess_.insert({ cameraStream, &buffer });
+
+ /*
+ * Make sure the CameraStream this stream is mapped on has been
+ * added to the request.
+ */
+ CameraStream *sourceStream = cameraStream->sourceStream();
+ ASSERT(sourceStream);
+ if (requestedStreams.find(sourceStream) != requestedStreams.end())
+ continue;
+
+ /*
+ * If that's not the case, we need to add a buffer to the request
+ * for this stream.
+ */
+ FrameBuffer *frameBuffer = cameraStream->getBuffer();
+ buffer.internalBuffer = frameBuffer;
+
+ descriptor->request_->addBuffer(sourceStream->stream(),
+ frameBuffer, nullptr);
+
+ requestedStreams.erase(sourceStream);
}
/*