From patchwork Mon Aug 23 12:43:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13433 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 C7133BD87C for ; Mon, 23 Aug 2021 12:43:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 87FBF688A3; Mon, 23 Aug 2021 14:43:36 +0200 (CEST) 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="OHAzmt/9"; dkim-atps=neutral Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D755A688AC for ; Mon, 23 Aug 2021 14:43:33 +0200 (CEST) Received: by mail-pl1-x630.google.com with SMTP id a5so10085005plh.5 for ; Mon, 23 Aug 2021 05:43:33 -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=PLLR3hebxfmwGxx8ycAFSj/gcCJJAYskwcHt/K1rz+A=; b=OHAzmt/9FHPLTq89oNoqLxdsXBgShcs6e1R1Qmgp2eVO5hPI3EjOFzUBELLgj1qWXR h9GK26OaI/cveEhEdkwzs0eF7z4vTvylfj/Id5qez7AcDLtUScgI2p8z7wHZzTQgTlha 7HatFI0Ti8AQiXfKYEIhzTuow+5efueukjAYk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PLLR3hebxfmwGxx8ycAFSj/gcCJJAYskwcHt/K1rz+A=; b=dkb/G7cAYD9nS94vm/aeDtqzTJipA6rAG8tmBGcwwi84b3WBHu823g9HPhx7cAFAHn Tbldywr7z3ihW+3JVCuu8Fsz1Ipcnm74YHN/twy2VFgVDaIst4rZuaMov1GWBmoYzJ9M N8zP2BYtMmotR70l0gO86osqTC4FZhZJKjMwuPi8dj2CjoKCsJz+aGW3yJSJmA8/U3Y4 yJzsNoeXrQSXiFokRt9xdJBGgi4AuMbqHy5QuiVL3tzxLJBzsrJU64IfyrTL9kKuClRl HDoOsCkmdkN8XTth6Lh42ZPFjh/AfpMdOCw9exgn2YSHw2LrfL74IOrmYVDlSHARaNqj wOeg== X-Gm-Message-State: AOAM530Sk17bdPQFpD56ePkT4EAmKXjiIT0p2OO6OvkslUBuPmMHhFIt 25CkdaFSjxhIcQwDlBEzQqvZURybqgbZdA== X-Google-Smtp-Source: ABdhPJxXAw+hyvYmzO2L8DGJ0B1h6tu1k5q0Xiesq2C5/qugtXoXjze6x/UHhhPGWINdum45FNitPA== X-Received: by 2002:a17:902:8346:b0:131:bb78:7a9e with SMTP id z6-20020a170902834600b00131bb787a9emr12404997pln.28.1629722611831; Mon, 23 Aug 2021 05:43:31 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:184e:5d20:8fcb:dfcd]) by smtp.gmail.com with ESMTPSA id o2sm12103107pgu.76.2021.08.23.05.43.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Aug 2021 05:43:31 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Mon, 23 Aug 2021 21:43:20 +0900 Message-Id: <20210823124321.980847-3-hiroh@chromium.org> X-Mailer: git-send-email 2.33.0.rc2.250.ged5fa647cd-goog In-Reply-To: <20210823124321.980847-1-hiroh@chromium.org> References: <20210823124321.980847-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 2/3] android: camera_buffer: Map buffer in the first plane() call 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" CameraBuffer implementation maps a given buffer_handle_t in constructor. Mapping is redundant to only know the plane info like stride and offset. Mapping should be executed rater in the first plane() call. Signed-off-by: Hirokazu Honda --- src/android/mm/cros_camera_buffer.cpp | 71 ++++++++++-------- src/android/mm/generic_camera_buffer.cpp | 93 +++++++++++++++--------- 2 files changed, 100 insertions(+), 64 deletions(-) diff --git a/src/android/mm/cros_camera_buffer.cpp b/src/android/mm/cros_camera_buffer.cpp index 50732637..85ef6480 100644 --- a/src/android/mm/cros_camera_buffer.cpp +++ b/src/android/mm/cros_camera_buffer.cpp @@ -25,7 +25,7 @@ public: int flags); ~Private(); - bool isValid() const { return valid_; } + bool isValid() const { return registered_; } unsigned int numPlanes() const; @@ -34,10 +34,12 @@ public: size_t jpegBufferSize(size_t maxJpegBufferSize) const; private: + bool Map(); + cros::CameraBufferManager *bufferManager_; buffer_handle_t handle_; unsigned int numPlanes_; - bool valid_; + bool mapped_; bool registered_; union { void *addr; @@ -50,7 +52,7 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer, [[maybe_unused]] libcamera::PixelFormat pixelFormat, [[maybe_unused]] const libcamera::Size &size, [[maybe_unused]] int flags) - : handle_(camera3Buffer), numPlanes_(0), valid_(false), + : handle_(camera3Buffer), numPlanes_(0), mapped_(false), registered_(false) { bufferManager_ = cros::CameraBufferManager::GetInstance(); @@ -63,36 +65,11 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer, registered_ = true; numPlanes_ = bufferManager_->GetNumPlanes(camera3Buffer); - switch (numPlanes_) { - case 1: { - 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: { - 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() { - if (valid_) + if (mapped_) bufferManager_->Unlock(handle_); if (registered_) bufferManager_->Deregister(handle_); @@ -105,6 +82,12 @@ unsigned int CameraBuffer::Private::numPlanes() const Span CameraBuffer::Private::plane(unsigned int plane) { + if (!mapped_) { + mapped_ = Map(); + if (!mapped_) + return {}; + } + void *addr; switch (numPlanes()) { @@ -134,4 +117,34 @@ size_t CameraBuffer::Private::jpegBufferSize([[maybe_unused]] size_t maxJpegBuff return bufferManager_->GetPlaneSize(handle_, 0); } +bool CameraBuffer::Private::Map() +{ + int ret; + switch (numPlanes_) { + case 1: { + ret = bufferManager_->Lock(handle_, 0, 0, 0, 0, 0, &mem.addr); + if (ret) { + LOG(HAL, Error) << "Single plane buffer mapping failed"; + return false; + } + break; + } + case 2: + case 3: { + ret = bufferManager_->LockYCbCr(handle_, 0, 0, 0, 0, 0, + &mem.ycbcr); + if (ret) { + LOG(HAL, Error) << "YCbCr buffer mapping failed"; + return false; + } + break; + } + default: + LOG(HAL, Error) << "Invalid number of planes: " << numPlanes_; + return false; + } + + return true; +} + PUBLIC_CAMERA_BUFFER_IMPLEMENTATION diff --git a/src/android/mm/generic_camera_buffer.cpp b/src/android/mm/generic_camera_buffer.cpp index 3127069f..6c1e4611 100644 --- a/src/android/mm/generic_camera_buffer.cpp +++ b/src/android/mm/generic_camera_buffer.cpp @@ -37,6 +37,12 @@ public: size_t jpegBufferSize(size_t maxJpegBufferSize) const; private: + bool Map(); + + int fd_; + int flags_; + libcamera::Size size_; + libcamera::PixelFormatInfo info_; /* \todo remove planes_ is added to MappedBuffer. */ std::vector> planes_; }; @@ -45,83 +51,100 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer, buffer_handle_t camera3Buffer, libcamera::PixelFormat pixelFormat, const libcamera::Size &size, int flags) + : fd_(-1), flags_(flags), size_(size) { error_ = 0; - int fd = -1; for (int i = 0; i < camera3Buffer->numFds; i++) { if (camera3Buffer->data[i] != -1) { - fd = camera3Buffer->data[i]; + fd_ = camera3Buffer->data[i]; break; } } - if (fd != -1) { + if (fd_ != -1) { error_ = EINVAL; LOG(HAL, Error) << "No valid file descriptor"; return; } - const auto &info = libcamera::PixelFormatInfo::info(pixelFormat); - if (!info.isValid()) { + info_ = libcamera::PixelFormatInfo::info(pixelFormat); + if (!info_.isValid()) { error_ = EINVAL; LOG(HAL, Error) << "Invalid pixel format: " << pixelFormat.toString(); return; } +} + +CameraBuffer::Private::~Private() +{ +} + +unsigned int CameraBuffer::Private::numPlanes() const +{ + return info_.numPlanes(); +} + +Span CameraBuffer::Private::plane(unsigned int plane) +{ + if (planes_.empty() && !Map()) + return {}; - size_t bufferLength = lseek(fd, 0, SEEK_END); + if (plane >= planes_.size()) + return {}; + + return planes_[plane]; +} + +size_t CameraBuffer::Private::jpegBufferSize(size_t maxJpegBufferSize) const +{ + if (maps_.empty()) { + size_t bufferLength = lseek(fd_, 0, SEEK_END); + if (bufferLength < 0) + LOG(HAL, Error) << "Failed to get buffer length"; + return 0; + } + + return std::min(maps_[0].size(), + maxJpegBufferSize); +} + +bool CameraBuffer::Private::Map() +{ + ASSERT(fd_ != -1); + + size_t bufferLength = lseek(fd_, 0, SEEK_END); if (bufferLength < 0) { error_ = -errno; LOG(HAL, Error) << "Failed to get buffer length"; - return; + return false; } - void *address = mmap(nullptr, bufferLength, flags, MAP_SHARED, fd, 0); + void *address = mmap(nullptr, bufferLength, flags_, MAP_SHARED, fd_, 0); if (address == MAP_FAILED) { error_ = -errno; LOG(HAL, Error) << "Failed to mmap plane"; - return; + return false; } maps_.emplace_back(static_cast(address), bufferLength); - const unsigned int numPlanes = info.numPlanes(); + const unsigned int numPlanes = info_.numPlanes(); planes_.resize(numPlanes); unsigned int offset = 0; for (unsigned int i = 0; i < numPlanes; ++i) { - const unsigned int vertSubSample = info.planes[i].verticalSubSampling; - const unsigned int stride = info.stride(size.width, i, 1u); + const unsigned int vertSubSample = info_.planes[i].verticalSubSampling; + const unsigned int stride = info_.stride(size_.width, i, 1u); const unsigned int planeSize = - stride * ((size.height + vertSubSample - 1) / vertSubSample); + stride * ((size_.height + vertSubSample - 1) / vertSubSample); planes_[i] = libcamera::Span( static_cast(address) + offset, planeSize); offset += planeSize; } -} - -CameraBuffer::Private::~Private() -{ -} - -unsigned int CameraBuffer::Private::numPlanes() const -{ - return planes_.size(); -} -Span CameraBuffer::Private::plane(unsigned int plane) -{ - if (plane >= planes_.size()) - return {}; - - return planes_[plane]; -} - -size_t CameraBuffer::Private::jpegBufferSize(size_t maxJpegBufferSize) const -{ - return std::min(maps_[0].size(), - maxJpegBufferSize); + return true; } PUBLIC_CAMERA_BUFFER_IMPLEMENTATION