From patchwork Mon Nov 1 07:16:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 14433 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 94C34C324E for ; Mon, 1 Nov 2021 07:17:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CE520600C9; Mon, 1 Nov 2021 08:17:02 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="EAMKVYT3"; dkim-atps=neutral Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 862BC600BD for ; Mon, 1 Nov 2021 08:17:01 +0100 (CET) Received: by mail-pg1-x533.google.com with SMTP id 75so16468568pga.3 for ; Mon, 01 Nov 2021 00:17:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2glnQsNPM3DcbbpvdGpPNleGnA7CSlP3RH/MuoYhCnQ=; b=EAMKVYT3pA/fLIBP2+/Vix92t5SxLFT6yDIh6ysqupjpqZ4+Ur3+dRINqWz2tT0oB4 wcAyf5qo1yAwYjpzbmW8uJsMx/GvEtI+NolwHXcFww7WA0wDHkr7/uZBOZV/2FuJJMGJ vORwiOW+sEaJOf5kGPnPhK72BJlV6SLCaLl0g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2glnQsNPM3DcbbpvdGpPNleGnA7CSlP3RH/MuoYhCnQ=; b=0QOi1xFXUoG7yTs6RZtP/iJ9/EQEINrOGT+lSKfP63pqlEOVdYF//H7hzKtIqkgLEN zSqtf0KsktkckXQUmXtyeQTd/zQa/ccRe1Okrj8Je75J+spAeHp6WoW7uOKmtnUL80kl V05Ilw+HB7h20HB5zXThoKGBkv7kLHQgOQffRlCjIsn0uCGuhUUmcikIFNHVTIyGypoV uNwS66/zfcv9N0qg5v5LSpof5VMHBblCWzupI6ulhwcpF5Lu4SIPVSTJ0OfW0ZSMER6l FwHV5UHOUPOVGga7OOonD3LLuHzlIjx40XLbnv6Nn6KKUD4RfWhHRg/Zb5MuHuIviwEA zj1A== X-Gm-Message-State: AOAM530pG5/gxGBAgcvfnRu2MGsNiMTnRMBTHbpU1muIHie9tjjHmhaw u+fcxtaaLP+jDyWDcZxAnnpyxhXxn3cUPw== X-Google-Smtp-Source: ABdhPJyGVrv5O0MtQRz6GON34tpRV4n8jEB0XHkxzTFVpriUXFghpdaSH9iiL6jzpNPHbG5N7GnLyQ== X-Received: by 2002:a63:710:: with SMTP id 16mr13096419pgh.324.1635751019898; Mon, 01 Nov 2021 00:16:59 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:3b39:f865:c90:680a]) by smtp.gmail.com with ESMTPSA id g14sm11910879pgo.88.2021.11.01.00.16.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 00:16:59 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Mon, 1 Nov 2021 16:16:51 +0900 Message-Id: <20211101071652.107912-2-hiroh@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211101071652.107912-1-hiroh@chromium.org> References: <20211101071652.107912-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/2] libcamera: framebuffer: Enable attaching additional data to FrameBuffer X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" We cannot have a subclass of FrameBuffer because it is marked as final. This adds a FrameBuffer constructor with FrameBuffer::Private. So we can attach some additional resources with FrameBuffer through a customized FrameBuffer::Private class. Signed-off-by: Hirokazu Honda Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- include/libcamera/framebuffer.h | 3 +++ include/libcamera/internal/framebuffer.h | 1 + src/libcamera/framebuffer.cpp | 26 ++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h index 7f2f176a..98ef9d5d 100644 --- a/include/libcamera/framebuffer.h +++ b/include/libcamera/framebuffer.h @@ -58,6 +58,9 @@ public: }; FrameBuffer(const std::vector &planes, unsigned int cookie = 0); + FrameBuffer(std::unique_ptr d, + const std::vector &planes, unsigned int cookie = 0); + const std::vector &planes() const { return planes_; } Request *request() const; diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h index cd33c295..3cced5b1 100644 --- a/include/libcamera/internal/framebuffer.h +++ b/include/libcamera/internal/framebuffer.h @@ -19,6 +19,7 @@ class FrameBuffer::Private : public Extensible::Private public: Private(); + virtual ~Private(); void setRequest(Request *request) { request_ = request; } bool isContiguous() const { return isContiguous_; } diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index d44a98ba..34e6cd4d 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -116,6 +116,15 @@ FrameBuffer::Private::Private() { } +/** + * \fn FrameBuffer::Private::~Private() + * \brief FrameBuffer::Private destructor + * + */ +FrameBuffer::Private::~Private() +{ +} + /** * \fn FrameBuffer::Private::setRequest() * \brief Set the request this buffer belongs to @@ -213,8 +222,21 @@ FrameBuffer::Private::Private() * \param[in] cookie Cookie */ FrameBuffer::FrameBuffer(const std::vector &planes, unsigned int cookie) - : Extensible(std::make_unique()), planes_(planes), - cookie_(cookie) + : FrameBuffer(std::make_unique(), planes, cookie) +{ +} + +/** + * \brief Construct a FrameBuffer with an extensible private class and an array + * of planes + * \param[in] d The extensible private class + * \param[in] planes The frame memory planes + * \param[in] cookie Cookie + */ +FrameBuffer::FrameBuffer(std::unique_ptr d, + const std::vector &planes, + unsigned int cookie) + : Extensible(std::move(d)), planes_(planes), cookie_(cookie) { metadata_.planes_.resize(planes_.size()); From patchwork Mon Nov 1 07:16:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 14434 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 75411C324F for ; Mon, 1 Nov 2021 07:17:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2B793600C6; Mon, 1 Nov 2021 08:17:05 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="ZDGho26j"; dkim-atps=neutral Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9B0E1600B6 for ; Mon, 1 Nov 2021 08:17:03 +0100 (CET) Received: by mail-pf1-x429.google.com with SMTP id 127so15571309pfu.1 for ; Mon, 01 Nov 2021 00:17:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Yvdv62NB27u93vblDL2sZj3M1v5wcfeoqzAF6yqzeps=; b=ZDGho26jISbucNX7GzPj7GioeE8gdrp8edpz3Dv7VX67LujhAk0nclVyG1DRiufBk4 fD+omyBc2EKWQqu4Qinr/SOJEF6XTSYhwAJaoMOPRyU+qf1yFsHjku2Tw9SMpq8D808I nsDHiJhGbGx0yNi46s5t3qEzdJsF+OeetyrAI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Yvdv62NB27u93vblDL2sZj3M1v5wcfeoqzAF6yqzeps=; b=GUDY+0aMpD3V3ZpIBzVufPwqcacO2xaF91WrOGm3Y9jaJAWdYpIIDs1QBOncYnwbjl lwcddlYzI6jC+MtkXONZSdJUi+aQDgZ5DpTKi1OvwbyeskiybqnQJ5Hm2RDYxey1MB8z SOOYSrOJ6EnHDz004mbLa6zW8J1+dSVH4p1nN5BH12Zrcw6Kqa2CJ6Qx3RO0uJa1aWR1 KyMvqr85KQIW0tIPTrSnMHjaGycKfZYiYvJp/MkVRagn3bdrEoGRYGh9iQLPrdP62jj4 UfiVFe8SuRwI4bacD29C0OAgHqup9fkaz2AsxUaSIxl0seblU1oMJKwuF1xlvcEXtajo wY3w== X-Gm-Message-State: AOAM533YEPx7wZft7HOyRPLuuqgy92lqK4/yJf3WcQeN2OBtJLf7xNta tu1OQ5luQMtldm+UOCwLDR9MYWaulzlhjg== X-Google-Smtp-Source: ABdhPJyNZMpLuAiWEyci6zD0L/Y8Ll3Ra3snK078RdvQTBg4Khjwf2q79QA76fEhbWHJwX2yCeMRRg== X-Received: by 2002:a63:ae08:: with SMTP id q8mr20435398pgf.76.1635751021458; Mon, 01 Nov 2021 00:17:01 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:3b39:f865:c90:680a]) by smtp.gmail.com with ESMTPSA id g14sm11910879pgo.88.2021.11.01.00.17.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 00:17:01 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Mon, 1 Nov 2021 16:16:52 +0900 Message-Id: <20211101071652.107912-3-hiroh@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211101071652.107912-1-hiroh@chromium.org> References: <20211101071652.107912-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/2] android: Introduce PlatformFrameBufferAllocator X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" After we unify identical streams to one stream configuration, the capture requested by a HAL client can have been resolved as CameraStream::Mapped. That is, a buffer to be written by a camera is not provided by a client. We would handle this case by dynamically allocating FrameBuffer. The existing FrameBufferAllocator cannot used because it is not allowed to allocate a new buffer while Camera is running. This introduces PlatformFrameBufferAllocator. It allocates FrameBuffer using cros::CameraBufferManager on ChromeOS and gralloc on non ChromeOS platform. The allocated FrameBuffer owns the underlying buffer but must be destroyed before PlatformFrameBufferAllocator is destroyed. Signed-off-by: Hirokazu Honda Reviewed-by: Laurent Pinchart --- src/android/frame_buffer_allocator.h | 54 +++++++ .../mm/cros_frame_buffer_allocator.cpp | 90 +++++++++++ .../mm/generic_frame_buffer_allocator.cpp | 144 ++++++++++++++++++ src/android/mm/meson.build | 6 +- 4 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 src/android/frame_buffer_allocator.h create mode 100644 src/android/mm/cros_frame_buffer_allocator.cpp create mode 100644 src/android/mm/generic_frame_buffer_allocator.cpp diff --git a/src/android/frame_buffer_allocator.h b/src/android/frame_buffer_allocator.h new file mode 100644 index 00000000..41ed4ae1 --- /dev/null +++ b/src/android/frame_buffer_allocator.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * frame_buffer_allocator.h - Interface definition to allocate Frame buffer in + * platform dependent way. + */ +#ifndef __ANDROID_FRAME_BUFFER_ALLOCATOR_H__ +#define __ANDROID_FRAME_BUFFER_ALLOCATOR_H__ + +#include + +#include +#include +#include +#include + +class CameraDevice; + +class PlatformFrameBufferAllocator : libcamera::Extensible +{ + LIBCAMERA_DECLARE_PRIVATE() + +public: + explicit PlatformFrameBufferAllocator(CameraDevice *const cameraDevice); + ~PlatformFrameBufferAllocator(); + + /* + * FrameBuffer owns the underlying buffer. Returns nullptr on failure. + * Note: The returned FrameBuffer needs to be destroyed before + * PlatformFrameBufferAllocator is destroyed. + */ + std::unique_ptr allocate( + int halPixelFormat, const libcamera::Size &size, uint32_t usage); +}; + +#define PUBLIC_FRAME_BUFFER_ALLOCATOR_IMPLEMENTATION \ +PlatformFrameBufferAllocator::PlatformFrameBufferAllocator( \ + CameraDevice *const cameraDevice) \ + : Extensible(std::make_unique(this, cameraDevice)) \ +{ \ +} \ +PlatformFrameBufferAllocator::~PlatformFrameBufferAllocator() \ +{ \ +} \ +std::unique_ptr \ +PlatformFrameBufferAllocator::allocate(int halPixelFormat, \ + const libcamera::Size& size, \ + uint32_t usage) \ +{ \ + return _d()->allocate(halPixelFormat, size, usage); \ +} + +#endif /* __ANDROID_FRAME_BUFFER_ALLOCATOR_H__ */ diff --git a/src/android/mm/cros_frame_buffer_allocator.cpp b/src/android/mm/cros_frame_buffer_allocator.cpp new file mode 100644 index 00000000..9c7e4ea4 --- /dev/null +++ b/src/android/mm/cros_frame_buffer_allocator.cpp @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * cros_frame_buffer.cpp - Allocate FrameBuffer for Chromium OS using + * CameraBufferManager + */ + +#include +#include + +#include + +#include "libcamera/internal/framebuffer.h" + +#include "../camera_device.h" +#include "../frame_buffer_allocator.h" +#include "cros-camera/camera_buffer_manager.h" + +using namespace libcamera; + +LOG_DECLARE_CATEGORY(HAL) + +namespace { +class CrosFrameBufferData : public FrameBuffer::Private +{ + LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) +public: + CrosFrameBufferData(cros::ScopedBufferHandle scopedHandle) + : FrameBuffer::Private(), scopedHandle_(std::move(scopedHandle)) + { + } + + ~CrosFrameBufferData() override = default; + +private: + cros::ScopedBufferHandle scopedHandle_; +}; +} /* namespace */ + +class PlatformFrameBufferAllocator::Private : public Extensible::Private +{ + LIBCAMERA_DECLARE_PUBLIC(PlatformFrameBufferAllocator) + +public: + Private([[maybe_unused]] PlatformFrameBufferAllocator *allocator, + [[maybe_unused]] CameraDevice *const cameraDevice) + { + } + + ~Private() override = default; + + std::unique_ptr allocate( + int halPixelFormat, const libcamera::Size &size, uint32_t usage); +}; + +std::unique_ptr +PlatformFrameBufferAllocator::Private::allocate( + int halPixelFormat, const libcamera::Size &size, uint32_t usage) +{ + cros::ScopedBufferHandle scopedHandle = + cros::CameraBufferManager::AllocateScopedBuffer( + size.width, size.height, halPixelFormat, usage); + if (!scopedHandle) { + LOG(HAL, Error) << "Failed to allocate buffer handle"; + return nullptr; + } + + buffer_handle_t handle = *scopedHandle; + const size_t numPlanes = cros::CameraBufferManager::GetNumPlanes(handle); + std::vector planes(numPlanes); + FileDescriptor fd{ handle->data[0] }; + if (!fd.isValid()) { + LOG(HAL, Fatal) << "Invalid fd"; + return nullptr; + } + + /* This code assumes all the planes are located in the same buffer. */ + for (auto [i, plane] : utils::enumerate(planes)) { + plane.fd = fd; + plane.offset = cros::CameraBufferManager::GetPlaneOffset(handle, i); + plane.length = cros::CameraBufferManager::GetPlaneSize(handle, i); + } + + return std::make_unique( + std::make_unique(std::move(scopedHandle)), + planes); +} + +PUBLIC_FRAME_BUFFER_ALLOCATOR_IMPLEMENTATION diff --git a/src/android/mm/generic_frame_buffer_allocator.cpp b/src/android/mm/generic_frame_buffer_allocator.cpp new file mode 100644 index 00000000..167cc1a5 --- /dev/null +++ b/src/android/mm/generic_frame_buffer_allocator.cpp @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * generic_camera_buffer.cpp - Allocate FrameBuffer using gralloc API + */ + +#include +#include + +#include + +#include "libcamera/internal/formats.h" +#include "libcamera/internal/framebuffer.h" + +#include +#include +#include + +#include "../camera_device.h" +#include "../frame_buffer_allocator.h" + +using namespace libcamera; + +LOG_DECLARE_CATEGORY(HAL) + +namespace { +class GenericFrameBufferData : public FrameBuffer::Private +{ + LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) + +public: + GenericFrameBufferData(struct alloc_device_t *allocDevice, + buffer_handle_t handle) + : allocDevice_(allocDevice), handle_(handle) + { + ASSERT(allocDevice_); + ASSERT(handle_); + } + + ~GenericFrameBufferData() override + { + /* + * allocDevice_ is used to destroy handle_. allocDevice_ is + * owned by PlatformFrameBufferAllocator::Private. + * GenericFrameBufferData must be destroyed before it is + * destroyed. + * + * \todo: Consider managing alloc_device_t with std::shared_ptr + * if this is difficult to maintain. + * + * Q: Thread safety against alloc_device_t is not documented. + * Is it no problem to call alloc/free in parallel? + */ + ASSERT(allocDevice_); + allocDevice_->free(allocDevice_, handle_); + } + +private: + struct alloc_device_t *allocDevice_; + const buffer_handle_t handle_; +}; +} /* namespace */ + +class PlatformFrameBufferAllocator::Private : public Extensible::Private +{ + LIBCAMERA_DECLARE_PUBLIC(PlatformFrameBufferAllocator) + +public: + Private([[maybe_unused]] PlatformFrameBufferAllocator *allocator, + CameraDevice *const cameraDevice) + : cameraDevice_(cameraDevice), + hardwareModule_(cameraDevice->camera3Device()->common.module), + allocDevice_(nullptr) + { + ASSERT(hardwareModule_); + } + + ~Private() override; + + std::unique_ptr allocate( + int halPixelFormat, const libcamera::Size &size, uint32_t usage); + +private: + const CameraDevice *const cameraDevice_; + struct hw_module_t *const hardwareModule_; + struct alloc_device_t *allocDevice_; +}; + +PlatformFrameBufferAllocator::Private::~Private() +{ + if (allocDevice_) + gralloc_close(allocDevice_); +} + +std::unique_ptr +PlatformFrameBufferAllocator::Private::allocate( + int halPixelFormat, const libcamera::Size &size, uint32_t usage) +{ + if (!allocDevice_) { + int ret = gralloc_open(hardwareModule_, &allocDevice_); + if (ret) { + LOG(HAL, Fatal) << "gralloc_open() failed: " << ret; + return nullptr; + } + } + + int stride = 0; + buffer_handle_t handle = nullptr; + int ret = allocDevice_->alloc(allocDevice_, size.width, size.height, + halPixelFormat, usage, &handle, &stride); + if (ret) { + LOG(HAL, Error) << "failed buffer allocating: " << ret; + return nullptr; + } + if (!handle) { + LOG(HAL, Fatal) << "buffer_handle_t is empty on success"; + return nullptr; + } + + const libcamera::PixelFormat pixelFormat = + cameraDevice_->capabilities()->toPixelFormat(halPixelFormat); + const auto &info = PixelFormatInfo::info(pixelFormat); + const unsigned int numPlanes = info.numPlanes(); + std::vector planes(numPlanes); + + /* This code assumes the planes are mapped consecutively. */ + FileDescriptor fd{ handle->data[0] }; + size_t offset = 0; + for (auto [i, plane] : utils::enumerate(planes)) { + const size_t planeSize = info.planeSize(size.height, i, stride); + + planes[i].fd = fd; + planes[i].offset = offset; + planes[i].length = planeSize; + offset += planeSize; + } + + return std::make_unique( + std::make_unique(allocDevice_, handle), + planes); +} + +PUBLIC_FRAME_BUFFER_ALLOCATOR_IMPLEMENTATION diff --git a/src/android/mm/meson.build b/src/android/mm/meson.build index eeb5cc2e..d40a3b0b 100644 --- a/src/android/mm/meson.build +++ b/src/android/mm/meson.build @@ -2,8 +2,10 @@ platform = get_option('android_platform') if platform == 'generic' - android_hal_sources += files(['generic_camera_buffer.cpp']) + android_hal_sources += files(['generic_camera_buffer.cpp', + 'generic_frame_buffer_allocator.cpp']) elif platform == 'cros' - android_hal_sources += files(['cros_camera_buffer.cpp']) + android_hal_sources += files(['cros_camera_buffer.cpp', + 'cros_frame_buffer_allocator.cpp']) android_deps += [dependency('libcros_camera')] endif