summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson_options.txt2
-rw-r--r--src/android/mm/cros_camera_buffer.cpp128
-rw-r--r--src/android/mm/meson.build3
3 files changed, 132 insertions, 1 deletions
diff --git a/meson_options.txt b/meson_options.txt
index d840543b..f6b6c65c 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -7,7 +7,7 @@ option('android',
option('android_platform',
type : 'combo',
- choices : ['generic'],
+ choices : ['cros', 'generic'],
value : 'generic',
description : 'Select the Android platform to compile for')
diff --git a/src/android/mm/cros_camera_buffer.cpp b/src/android/mm/cros_camera_buffer.cpp
new file mode 100644
index 00000000..7df4f47c
--- /dev/null
+++ b/src/android/mm/cros_camera_buffer.cpp
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * cros_camera_buffer.cpp - Chromium OS buffer backend using CameraBufferManager
+ */
+
+#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::Private : public Extensible::Private
+{
+ LIBCAMERA_DECLARE_PUBLIC(CameraBuffer)
+
+public:
+ Private(CameraBuffer *cameraBuffer,
+ buffer_handle_t camera3Buffer, int flags);
+ ~Private();
+
+ bool isValid() const { return valid_; }
+
+ unsigned int numPlanes() const;
+
+ Span<uint8_t> plane(unsigned int plane);
+
+ size_t jpegBufferSize(size_t maxJpegBufferSize) const;
+
+private:
+ cros::CameraBufferManager *bufferManager_;
+ buffer_handle_t handle_;
+ unsigned int numPlanes_;
+ bool valid_;
+ union {
+ void *addr;
+ android_ycbcr ycbcr;
+ } mem;
+
+ const uint8_t *planeAddr(unsigned int plane) const;
+ uint8_t *planeAddr(unsigned int plane);
+};
+
+CameraBuffer::Private::Private(CameraBuffer *cameraBuffer,
+ buffer_handle_t camera3Buffer, int flags)
+ : Extensible::Private(cameraBuffer), 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::Private::~Private()
+{
+ bufferManager_->Unlock(handle_);
+ bufferManager_->Deregister(handle_);
+}
+
+unsigned int CameraBuffer::Private::numPlanes() const
+{
+ return bufferManager_->GetNumPlanes(handle_);
+}
+
+Span<uint8_t> CameraBuffer::Private::plane(unsigned int plane)
+{
+ 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),
+ bufferManager_->GetPlaneSize(handle_, plane) };
+}
+
+size_t CameraBuffer::Private::jpegBufferSize(size_t maxJpegBufferSize) const
+{
+ return bufferManager_->GetPlaneSize(handle_, 0);
+}
+
+PUBLIC_CAMERA_BUFFER_IMPLEMENTATION
diff --git a/src/android/mm/meson.build b/src/android/mm/meson.build
index 97f83f2a..eeb5cc2e 100644
--- a/src/android/mm/meson.build
+++ b/src/android/mm/meson.build
@@ -3,4 +3,7 @@
platform = get_option('android_platform')
if platform == 'generic'
android_hal_sources += files(['generic_camera_buffer.cpp'])
+elif platform == 'cros'
+ android_hal_sources += files(['cros_camera_buffer.cpp'])
+ android_deps += [dependency('libcros_camera')]
endif