summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2020-10-03 13:21:50 +0200
committerJacopo Mondi <jacopo@jmondi.org>2020-10-07 16:09:20 +0200
commitb84e35dc97059716c7e90f73ce1df2709c5a7f6e (patch)
treef72e2644b64318dea44440f388320cce33a1c35d
parent6c8837da5e8f9ba31aed338f8f6bbe578ddd638a (diff)
android: camera_stream: Create buffer pool
Add a FrameBufferAllocator class member to the CameraStream class. The allocator is constructed for CameraStream instances that needs internal allocation and automatically deleted. Allocate FrameBuffers using the allocator_ class member in the CameraStream class at CameraStream::configure() time and add two methods to the CameraStream class to get and put FrameBuffer pointers from the pool of allocated buffers. As buffer allocation can take place only after the Camera has been configured, move the CameraStream configuration loop in the CameraDevice class after camera_->configure() call. The newly created pool will be used to provide buffers to CameraStream that need to provide memory to libcamera where to deliver frames. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r--src/android/camera_device.cpp22
-rw-r--r--src/android/camera_stream.cpp43
-rw-r--r--src/android/camera_stream.h13
3 files changed, 67 insertions, 11 deletions
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 1e2cbeeb..ecdc0922 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -1283,6 +1283,17 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
}
/*
+ * Once the CameraConfiguration has been adjusted/validated
+ * it can be applied to the camera.
+ */
+ int ret = camera_->configure(config_.get());
+ if (ret) {
+ LOG(HAL, Error) << "Failed to configure camera '"
+ << camera_->id() << "'";
+ return ret;
+ }
+
+ /*
* Configure the HAL CameraStream instances using the associated
* StreamConfiguration and set the number of required buffers in
* the Android camera3_stream_t.
@@ -1295,17 +1306,6 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
}
}
- /*
- * Once the CameraConfiguration has been adjusted/validated
- * it can be applied to the camera.
- */
- int ret = camera_->configure(config_.get());
- if (ret) {
- LOG(HAL, Error) << "Failed to configure camera '"
- << camera_->id() << "'";
- return ret;
- }
-
return 0;
}
diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp
index f899be4f..eac14805 100644
--- a/src/android/camera_stream.cpp
+++ b/src/android/camera_stream.cpp
@@ -26,6 +26,11 @@ CameraStream::CameraStream(CameraDevice *cameraDevice, Type type,
if (type_ == Type::Internal || type_ == Type::Mapped)
encoder_ = std::make_unique<EncoderLibJpeg>();
+
+ if (type == Type::Internal) {
+ allocator_ = std::make_unique<FrameBufferAllocator>(cameraDevice_->camera());
+ mutex_ = std::make_unique<std::mutex>();
+ }
}
const StreamConfiguration &CameraStream::configuration() const
@@ -46,6 +51,16 @@ int CameraStream::configure()
return ret;
}
+ if (allocator_) {
+ int ret = allocator_->allocate(stream());
+ if (ret < 0)
+ return ret;
+
+ /* Save a pointer to the reserved frame buffers */
+ for (const auto &frameBuffer : allocator_->buffers(stream()))
+ buffers_.push_back(frameBuffer.get());
+ }
+
camera3Stream_->max_buffers = configuration().bufferCount;
return 0;
@@ -109,3 +124,31 @@ int CameraStream::process(const libcamera::FrameBuffer &source,
return 0;
}
+
+FrameBuffer *CameraStream::getBuffer()
+{
+ if (!allocator_)
+ return nullptr;
+
+ std::lock_guard<std::mutex> locker(*mutex_);
+
+ if (buffers_.empty()) {
+ LOG(HAL, Error) << "Buffer underrun";
+ return nullptr;
+ }
+
+ FrameBuffer *buffer = buffers_.back();
+ buffers_.pop_back();
+
+ return buffer;
+}
+
+void CameraStream::putBuffer(libcamera::FrameBuffer *buffer)
+{
+ if (!allocator_)
+ return;
+
+ std::lock_guard<std::mutex> locker(*mutex_);
+
+ buffers_.push_back(buffer);
+}
diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h
index 4c51f0fb..8df0101c 100644
--- a/src/android/camera_stream.h
+++ b/src/android/camera_stream.h
@@ -8,11 +8,14 @@
#define __ANDROID_CAMERA_STREAM_H__
#include <memory>
+#include <mutex>
+#include <vector>
#include <hardware/camera3.h>
#include <libcamera/buffer.h>
#include <libcamera/camera.h>
+#include <libcamera/framebuffer_allocator.h>
#include <libcamera/geometry.h>
#include <libcamera/pixel_format.h>
@@ -117,6 +120,8 @@ public:
int configure();
int process(const libcamera::FrameBuffer &source,
MappedCamera3Buffer *dest, CameraMetadata *metadata);
+ libcamera::FrameBuffer *getBuffer();
+ void putBuffer(libcamera::FrameBuffer *buffer);
private:
CameraDevice *cameraDevice_;
@@ -129,7 +134,15 @@ private:
* one or more streams to the Android framework.
*/
unsigned int index_;
+
std::unique_ptr<Encoder> encoder_;
+ std::unique_ptr<libcamera::FrameBufferAllocator> allocator_;
+ std::vector<libcamera::FrameBuffer *> buffers_;
+ /*
+ * The class has to be MoveConstructible as instances are stored in
+ * an std::vector in CameraDevice.
+ */
+ std::unique_ptr<std::mutex> mutex_;
};
#endif /* __ANDROID_CAMERA_STREAM__ */