[libcamera-devel] [PATCH 11/12] android: Introduce cros_cbm_buffer
Jacopo Mondi
jacopo at jmondi.org
Fri Feb 26 14:29:31 CET 2021
Introduce the CameraBuffer backend for the ChromeOS operating system.
The cros_cbm CameraBuffer implementation uses the ChromeOS
CameraBufferManager class to perform mapping of 1 plane and multiplane
buffers.
Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
src/android/mm/cros_cbm.cpp | 167 ++++++++++++++++++++++++++++++++++++
src/android/mm/meson.build | 3 +
2 files changed, 170 insertions(+)
create mode 100644 src/android/mm/cros_cbm.cpp
diff --git a/src/android/mm/cros_cbm.cpp b/src/android/mm/cros_cbm.cpp
new file mode 100644
index 000000000000..6c931c99d2d0
--- /dev/null
+++ b/src/android/mm/cros_cbm.cpp
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * cros_cbm.cpp - ChromiumOS libcbm frame buffer backend
+ */
+
+#include "../camera_buffer.h"
+
+#include "libcamera/internal/log.h"
+
+#include "cros-camera/camera_buffer_manager.h"
+
+using namespace libcamera;
+
+LOG_DECLARE_CATEGORY(HAL)
+
+class CameraBuffer::CameraBufferImpl : public libcamera::MappedBuffer
+{
+public:
+ CameraBufferImpl(buffer_handle_t camera3Buffer, int flags);
+ ~CameraBufferImpl();
+
+ bool isValid() const { return valid_; }
+
+ unsigned int numPlanes() const;
+ ssize_t planeSize(unsigned int plane) const;
+
+ const uint8_t *plane(unsigned int plane) const;
+ uint8_t *plane(unsigned int plane);
+
+private:
+ cros::CameraBufferManager *bufferManager_;
+ buffer_handle_t handle_;
+ unsigned int numPlanes_;
+ bool valid_;
+ union {
+ void *addr;
+ android_ycbcr ycbcr;
+ } mem;
+};
+
+CameraBuffer::CameraBufferImpl::CameraBufferImpl(buffer_handle_t camera3Buffer,
+ int flags)
+ : handle_(camera3Buffer), numPlanes_(0), valid_(false)
+{
+ bufferManager_ = cros::CameraBufferManager::GetInstance();
+
+ bufferManager_->Register(camera3Buffer);
+
+ numPlanes_ = bufferManager_->GetNumPlanes(camera3Buffer);
+ switch (numPlanes_) {
+ case 1: {
+ int ret = bufferManager_->Lock(handle_, 0, 0, 0, 0, 0, &mem.addr);
+ if (ret) {
+ LOG(HAL, Error) << "Single plane buffer mapping failed";
+ return;
+ }
+ break;
+ }
+ case 2: {
+ case 3:
+ int ret = bufferManager_->LockYCbCr(handle_, 0, 0, 0, 0, 0,
+ &mem.ycbcr);
+ if (ret) {
+ LOG(HAL, Error) << "YCbCr buffer mapping failed";
+ return;
+ }
+ break;
+ }
+ default:
+ LOG(HAL, Error) << "Invalid number of planes: " << numPlanes_;
+ return;
+ }
+
+ valid_ = true;
+}
+
+CameraBuffer::CameraBufferImpl::~CameraBufferImpl()
+{
+ bufferManager_->Unlock(handle_);
+ bufferManager_->Deregister(handle_);
+}
+
+unsigned int CameraBuffer::CameraBufferImpl::numPlanes() const
+{
+ return bufferManager_->GetNumPlanes(handle_);
+}
+
+ssize_t CameraBuffer::CameraBufferImpl::planeSize(unsigned int plane) const
+{
+ if (plane >= numPlanes())
+ return -EINVAL;
+
+ return bufferManager_->GetPlaneSize(handle_, plane);
+}
+
+const uint8_t *CameraBuffer::CameraBufferImpl::plane(unsigned int plane) const
+{
+ if (plane >= numPlanes())
+ return nullptr;
+
+ return const_cast<const uint8_t *>(this->plane(plane));
+}
+
+uint8_t *CameraBuffer::CameraBufferImpl::plane(unsigned int plane)
+{
+ if (plane >= numPlanes())
+ return nullptr;
+
+ void *addr;
+ switch (numPlanes()) {
+ case 1:
+ addr = mem.addr;
+ break;
+ default:
+ switch (plane) {
+ case 1:
+ addr = mem.ycbcr.y;
+ break;
+ case 2:
+ addr = mem.ycbcr.cb;
+ break;
+ case 3:
+ addr = mem.ycbcr.cr;
+ break;
+ }
+ }
+
+ return static_cast<uint8_t *>(addr);
+}
+
+CameraBuffer::CameraBuffer(buffer_handle_t camera3Buffer, int flags)
+ : impl_(new CameraBuffer::CameraBufferImpl(camera3Buffer, flags))
+{
+}
+
+CameraBuffer::~CameraBuffer()
+{
+ delete impl_;
+}
+
+bool CameraBuffer::isValid() const
+{
+ return impl_->isValid();
+}
+
+unsigned int CameraBuffer::numPlanes() const
+{
+ return impl_->numPlanes();
+}
+
+ssize_t CameraBuffer::planeSize(unsigned int plane) const
+{
+ return impl_->planeSize(plane);
+}
+
+const uint8_t *CameraBuffer::plane(unsigned int plane) const
+{
+ return impl_->plane(plane);
+}
+
+uint8_t *CameraBuffer::plane(unsigned int plane)
+{
+ return impl_->plane(plane);
+}
+
diff --git a/src/android/mm/meson.build b/src/android/mm/meson.build
index 39be8fec8567..a801c54ff4f4 100644
--- a/src/android/mm/meson.build
+++ b/src/android/mm/meson.build
@@ -3,4 +3,7 @@
memory_backend = get_option('android_memory_backend')
if memory_backend == 'android_generic'
android_hal_sources += files(['android_generic_buffer.cpp'])
+elif memory_backend == 'cros_cbm'
+ android_hal_sources += files(['cros_cbm.cpp'])
+ android_deps += [ dependency('libcros_camera') ]
endif
--
2.30.0
More information about the libcamera-devel
mailing list