{"id":13499,"url":"https://patchwork.libcamera.org/api/patches/13499/?format=json","web_url":"https://patchwork.libcamera.org/patch/13499/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20210826080021.3454520-3-hiroh@chromium.org>","date":"2021-08-26T08:00:20","name":"[libcamera-devel,v3,2/3] android: camera_buffer: Map buffer in the first plane() call","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"a908b0af947a93dbca50c317ae953f137d71c0cf","submitter":{"id":63,"url":"https://patchwork.libcamera.org/api/people/63/?format=json","name":"Hirokazu Honda","email":"hiroh@chromium.org"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/13499/mbox/","series":[{"id":2397,"url":"https://patchwork.libcamera.org/api/series/2397/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=2397","date":"2021-08-26T08:00:18","name":"Improve CameraBuffer implementation","version":3,"mbox":"https://patchwork.libcamera.org/series/2397/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/13499/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/13499/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 05830C3241\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 26 Aug 2021 08:00:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9BC216891A;\n\tThu, 26 Aug 2021 10:00:35 +0200 (CEST)","from mail-pf1-x430.google.com (mail-pf1-x430.google.com\n\t[IPv6:2607:f8b0:4864:20::430])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1075C688AC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 26 Aug 2021 10:00:33 +0200 (CEST)","by mail-pf1-x430.google.com with SMTP id r13so1677192pff.7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 26 Aug 2021 01:00:32 -0700 (PDT)","from hiroh2.tok.corp.google.com\n\t([2401:fa00:8f:203:a5bc:b3dd:7208:bec1])\n\tby smtp.gmail.com with ESMTPSA id\n\tg3sm2570805pgj.66.2021.08.26.01.00.29\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 26 Aug 2021 01:00:30 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"K0yN/I9P\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=KFMQKfJhtjmZS1LVznkULl8g1sD+PYxZXq14LjoblVk=;\n\tb=K0yN/I9PNEPw5W+c/HtTZpgylqOg9/tzfqkauUPQdn37+zdZ0SWyhIyD8BjzvoBvFk\n\tX+NEbWGP+GlxueftGvWXXy5wVZAK0JSylObYvYYozMqo2MU6DO9730om4VCMesYoa65R\n\t88c+2Bo/QC4LccMKyhuj+pyNxbI5v0QVrGHSY=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=KFMQKfJhtjmZS1LVznkULl8g1sD+PYxZXq14LjoblVk=;\n\tb=p0y+FvsViU14UUOVArrbiy228QoUNpHfnq5yaBNY15w5zoJGkI/epnogWGFAzo0P/I\n\tkhhj/aEsYT4+ZCQS2HgPhXqU+knPNt4TliPUhQDhIrWLbesUDy/gP021wC4EVB3U0Kks\n\taHTZdqE5xg3MlirIYU1egrsvNoyvjA2aXCnoCtxxWa6rF/emQohJ5Oowwf63ZV0DejEA\n\tGzFuBuhYx7Sq92DRxTalxzadICgAvF02faLxn413ZMSrFcMG83HFQ1u+JDCO1oN09DW8\n\tQNvw1HviuqNdMGISD1KL7whyV6r8jrlaRjbxFXmS7Feb9969jnEwoG/n8z1xNhSSCyTX\n\tSn1w==","X-Gm-Message-State":"AOAM533hhumg4aMX9yJNsoXWNlTxUInC2I2/e7GGqq/apYyyDR9j6ZL0\n\tlbcr+MgkqDJ6a+eyYiyEQMDV/oiayS7cCA==","X-Google-Smtp-Source":"ABdhPJxWR6jaUIFF0a3sTSTweMH6HWmQTDWq3BHVPMTXvYcgArgjFW1ciD2R8zyfxwN471wSLg2Unw==","X-Received":"by 2002:a63:134e:: with SMTP id 14mr2233600pgt.312.1629964831286;\n\tThu, 26 Aug 2021 01:00:31 -0700 (PDT)","From":"Hirokazu Honda <hiroh@chromium.org>","To":"libcamera-devel@lists.libcamera.org","Date":"Thu, 26 Aug 2021 17:00:20 +0900","Message-Id":"<20210826080021.3454520-3-hiroh@chromium.org>","X-Mailer":"git-send-email 2.33.0.rc2.250.ged5fa647cd-goog","In-Reply-To":"<20210826080021.3454520-1-hiroh@chromium.org>","References":"<20210826080021.3454520-1-hiroh@chromium.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH v3 2/3] android: camera_buffer: Map buffer\n\tin the first plane() call","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"CameraBuffer implementation maps a given buffer_handle_t in\nconstructor. Mapping is redundant to only know the plane info like\nstride and offset. Mapping should be executed rater in the first\nplane() call.\n\nSigned-off-by: Hirokazu Honda <hiroh@chromium.org>\n---\n src/android/mm/cros_camera_buffer.cpp    | 71 +++++++++++--------\n src/android/mm/generic_camera_buffer.cpp | 86 ++++++++++++++++--------\n 2 files changed, 100 insertions(+), 57 deletions(-)","diff":"diff --git a/src/android/mm/cros_camera_buffer.cpp b/src/android/mm/cros_camera_buffer.cpp\nindex 50732637..ba6650cf 100644\n--- a/src/android/mm/cros_camera_buffer.cpp\n+++ b/src/android/mm/cros_camera_buffer.cpp\n@@ -25,7 +25,7 @@ public:\n \t\tint flags);\n \t~Private();\n \n-\tbool isValid() const { return valid_; }\n+\tbool isValid() const { return registered_; }\n \n \tunsigned int numPlanes() const;\n \n@@ -34,10 +34,12 @@ public:\n \tsize_t jpegBufferSize(size_t maxJpegBufferSize) const;\n \n private:\n+\tvoid map();\n+\n \tcros::CameraBufferManager *bufferManager_;\n \tbuffer_handle_t handle_;\n \tunsigned int numPlanes_;\n-\tbool valid_;\n+\tbool mapped_;\n \tbool registered_;\n \tunion {\n \t\tvoid *addr;\n@@ -50,7 +52,7 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer,\n \t\t\t       [[maybe_unused]] libcamera::PixelFormat pixelFormat,\n \t\t\t       [[maybe_unused]] const libcamera::Size &size,\n \t\t\t       [[maybe_unused]] int flags)\n-\t: handle_(camera3Buffer), numPlanes_(0), valid_(false),\n+\t: handle_(camera3Buffer), numPlanes_(0), mapped_(false),\n \t  registered_(false)\n {\n \tbufferManager_ = cros::CameraBufferManager::GetInstance();\n@@ -63,36 +65,11 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer,\n \n \tregistered_ = true;\n \tnumPlanes_ = bufferManager_->GetNumPlanes(camera3Buffer);\n-\tswitch (numPlanes_) {\n-\tcase 1: {\n-\t\tret = bufferManager_->Lock(handle_, 0, 0, 0, 0, 0, &mem.addr);\n-\t\tif (ret) {\n-\t\t\tLOG(HAL, Error) << \"Single plane buffer mapping failed\";\n-\t\t\treturn;\n-\t\t}\n-\t\tbreak;\n-\t}\n-\tcase 2:\n-\tcase 3: {\n-\t\tret = bufferManager_->LockYCbCr(handle_, 0, 0, 0, 0, 0,\n-\t\t\t\t\t\t&mem.ycbcr);\n-\t\tif (ret) {\n-\t\t\tLOG(HAL, Error) << \"YCbCr buffer mapping failed\";\n-\t\t\treturn;\n-\t\t}\n-\t\tbreak;\n-\t}\n-\tdefault:\n-\t\tLOG(HAL, Error) << \"Invalid number of planes: \" << numPlanes_;\n-\t\treturn;\n-\t}\n-\n-\tvalid_ = true;\n }\n \n CameraBuffer::Private::~Private()\n {\n-\tif (valid_)\n+\tif (mapped_)\n \t\tbufferManager_->Unlock(handle_);\n \tif (registered_)\n \t\tbufferManager_->Deregister(handle_);\n@@ -105,6 +82,11 @@ unsigned int CameraBuffer::Private::numPlanes() const\n \n Span<uint8_t> CameraBuffer::Private::plane(unsigned int plane)\n {\n+\tif (!mapped_)\n+\t\tmap();\n+\tif (!mapped_)\n+\t\treturn {};\n+\n \tvoid *addr;\n \n \tswitch (numPlanes()) {\n@@ -134,4 +116,35 @@ size_t CameraBuffer::Private::jpegBufferSize([[maybe_unused]] size_t maxJpegBuff\n \treturn bufferManager_->GetPlaneSize(handle_, 0);\n }\n \n+void CameraBuffer::Private::map()\n+{\n+\tint ret;\n+\tswitch (numPlanes_) {\n+\tcase 1: {\n+\t\tret = bufferManager_->Lock(handle_, 0, 0, 0, 0, 0, &mem.addr);\n+\t\tif (ret) {\n+\t\t\tLOG(HAL, Error) << \"Single plane buffer mapping failed\";\n+\t\t\treturn;\n+\t\t}\n+\t\tbreak;\n+\t}\n+\tcase 2:\n+\tcase 3: {\n+\t\tret = bufferManager_->LockYCbCr(handle_, 0, 0, 0, 0, 0,\n+\t\t\t\t\t\t&mem.ycbcr);\n+\t\tif (ret) {\n+\t\t\tLOG(HAL, Error) << \"YCbCr buffer mapping failed\";\n+\t\t\treturn;\n+\t\t}\n+\t\tbreak;\n+\t}\n+\tdefault:\n+\t\tLOG(HAL, Error) << \"Invalid number of planes: \" << numPlanes_;\n+\t\treturn;\n+\t}\n+\n+\tmapped_ = true;\n+\treturn;\n+}\n+\n PUBLIC_CAMERA_BUFFER_IMPLEMENTATION\ndiff --git a/src/android/mm/generic_camera_buffer.cpp b/src/android/mm/generic_camera_buffer.cpp\nindex 22753490..cfe55b69 100644\n--- a/src/android/mm/generic_camera_buffer.cpp\n+++ b/src/android/mm/generic_camera_buffer.cpp\n@@ -37,6 +37,18 @@ public:\n \tsize_t jpegBufferSize(size_t maxJpegBufferSize) const;\n \n private:\n+\tstruct PlaneInfo {\n+\t\tunsigned int offset;\n+\t\tunsigned int size;\n+\t};\n+\n+\tvoid map();\n+\n+\tint fd_;\n+\tint flags_;\n+\toff_t bufferLength_;\n+\tbool mapped_;\n+\tstd::vector<PlaneInfo> planeInfo_;\n \t/* \\todo Remove planes_ when it will be added to MappedBuffer */\n \tstd::vector<Span<uint8_t>> planes_;\n };\n@@ -45,6 +57,7 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer,\n \t\t\t       buffer_handle_t camera3Buffer,\n \t\t\t       libcamera::PixelFormat pixelFormat,\n \t\t\t       const libcamera::Size &size, int flags)\n+\t: fd_(-1), flags_(flags), mapped_(false)\n {\n \terror_ = 0;\n \n@@ -61,43 +74,35 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer,\n \t * now that the buffer is backed by a single dmabuf, with planes being\n \t * stored contiguously.\n \t */\n-\tint fd = -1;\n \tfor (int i = 0; i < camera3Buffer->numFds; i++) {\n-\t\tif (camera3Buffer->data[i] == -1 || camera3Buffer->data[i] == fd)\n+\t\tif (camera3Buffer->data[i] == -1 || camera3Buffer->data[i] == fd_)\n \t\t\tcontinue;\n \n-\t\tif (fd != -1) {\n+\t\tif (fd_ != -1) {\n \t\t\terror_ = -EINVAL;\n \t\t\tLOG(HAL, Error) << \"Discontiguous planes are not supported\";\n \t\t\treturn;\n \t\t}\n \n-\t\tfd = camera3Buffer->data[i];\n+\t\tfd_ = camera3Buffer->data[i];\n \t}\n \n-\tif (fd == -1) {\n+\tif (fd_ == -1) {\n \t\terror_ = -EINVAL;\n \t\tLOG(HAL, Error) << \"No valid file descriptor\";\n \t\treturn;\n \t}\n \n-\toff_t bufferLength = lseek(fd, 0, SEEK_END);\n-\tif (bufferLength < 0) {\n+\tbufferLength_ = lseek(fd_, 0, SEEK_END);\n+\tif (bufferLength_ < 0) {\n \t\terror_ = -errno;\n \t\tLOG(HAL, Error) << \"Failed to get buffer length\";\n \t\treturn;\n \t}\n \n-\tvoid *address = mmap(nullptr, bufferLength, flags, MAP_SHARED, fd, 0);\n-\tif (address == MAP_FAILED) {\n-\t\terror_ = -errno;\n-\t\tLOG(HAL, Error) << \"Failed to mmap plane\";\n-\t\treturn;\n-\t}\n-\tmaps_.emplace_back(static_cast<uint8_t *>(address), bufferLength);\n-\n \tconst unsigned int numPlanes = info.numPlanes();\n-\tplanes_.resize(numPlanes);\n+\tplaneInfo_.resize(numPlanes);\n+\n \tunsigned int offset = 0;\n \tfor (unsigned int i = 0; i < numPlanes; ++i) {\n \t\t/*\n@@ -109,17 +114,17 @@ CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer,\n \t\tconst unsigned int planeSize =\n \t\t\tstride * ((size.height + vertSubSample - 1) / vertSubSample);\n \n-\t\tplanes_[i] = libcamera::Span<uint8_t>(\n-\t\t\tstatic_cast<uint8_t *>(address) + offset, planeSize);\n+\t\tplaneInfo_[i].offset = offset;\n+\t\tplaneInfo_[i].size = planeSize;\n \n-\t\tif (bufferLength < offset + planeSize) {\n-\t\t\terror_ = -EINVAL;\n-\t\t\tLOG(HAL, Error) << \"Plane \" << i << \" is out of buffer\"\n-\t\t\t\t\t<< \", buffer length=\" << bufferLength\n-\t\t\t\t\t<< \", offset=\" << offset\n-\t\t\t\t\t<< \", size=\" << planeSize;\n+\t\tif (bufferLength_ < offset + planeSize) {\n+\t\t\tLOG(HAL, Error) << \"Plane \" << i << \" is out of buffer:\"\n+\t\t\t\t\t<< \" plane offset=\" << offset\n+\t\t\t\t\t<< \", plane size=\" << planeSize\n+\t\t\t\t\t<< \", buffer length=\" << bufferLength_;\n \t\t\treturn;\n \t\t}\n+\n \t\toffset += planeSize;\n \t}\n }\n@@ -130,12 +135,14 @@ CameraBuffer::Private::~Private()\n \n unsigned int CameraBuffer::Private::numPlanes() const\n {\n-\treturn planes_.size();\n+\treturn planeInfo_.size();\n }\n \n Span<uint8_t> CameraBuffer::Private::plane(unsigned int plane)\n {\n-\tif (plane >= planes_.size())\n+\tif (!mapped_)\n+\t\tmap();\n+\tif (!mapped_)\n \t\treturn {};\n \n \treturn planes_[plane];\n@@ -143,8 +150,31 @@ Span<uint8_t> CameraBuffer::Private::plane(unsigned int plane)\n \n size_t CameraBuffer::Private::jpegBufferSize(size_t maxJpegBufferSize) const\n {\n-\treturn std::min<unsigned int>(maps_[0].size(),\n-\t\t\t\t      maxJpegBufferSize);\n+\tASSERT(bufferLength_ >= 0);\n+\n+\treturn std::min<unsigned int>(bufferLength_, maxJpegBufferSize);\n+}\n+\n+void CameraBuffer::Private::map()\n+{\n+\tASSERT(fd_ != -1);\n+\tASSERT(bufferLength_ >= 0);\n+\n+\tvoid *address = mmap(nullptr, bufferLength_, flags_, MAP_SHARED, fd_, 0);\n+\tif (address == MAP_FAILED) {\n+\t\terror_ = -errno;\n+\t\tLOG(HAL, Error) << \"Failed to mmap plane\";\n+\t\treturn;\n+\t}\n+\tmaps_.emplace_back(static_cast<uint8_t *>(address), bufferLength_);\n+\n+\tplanes_.reserve(planeInfo_.size());\n+\tfor (const auto &info : planeInfo_) {\n+\t\tplanes_.emplace_back(\n+\t\t\tstatic_cast<uint8_t *>(address) + info.offset, info.size);\n+\t}\n+\n+\tmapped_ = true;\n }\n \n PUBLIC_CAMERA_BUFFER_IMPLEMENTATION\n","prefixes":["libcamera-devel","v3","2/3"]}