[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