@@ -1282,6 +1282,17 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
return -EINVAL;
}
+ /*
+ * 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
@@ -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;
}
@@ -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);
+}
@@ -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,11 @@ 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_;
+ std::unique_ptr<std::mutex> mutex_;
};
#endif /* __ANDROID_CAMERA_STREAM__ */