From patchwork Thu Aug 26 11:25:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13503 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 2E019BD87C for ; Thu, 26 Aug 2021 11:25:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E8C4D688E5; Thu, 26 Aug 2021 13:25:53 +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="ilKQd1gz"; dkim-atps=neutral Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 007316888F for ; Thu, 26 Aug 2021 13:25:51 +0200 (CEST) Received: by mail-pg1-x536.google.com with SMTP id s11so2767524pgr.11 for ; Thu, 26 Aug 2021 04:25:50 -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=cIFc40HtWtIL1OXXk5WK2FVqnWkKAedNtYJqkR0Jv9o=; b=ilKQd1gzKKrqtL2RB0XR0+1LuddO+uRvU6Yi2Cg6ol34AMpW4VYzlSkZe4Xm7Ommas 3xJruwhmBZdwxALFlVgQIPPiq7scVO7LYNu7i0zMDBRVoBkhiT6vKTE6F1ii6kqi1l5V LhWhWlmrui9V/8WWHxY6Nhv3Sw2fm/pErh2cY= 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=cIFc40HtWtIL1OXXk5WK2FVqnWkKAedNtYJqkR0Jv9o=; b=OMZnRlXK3T7L7UUbR1vH3Ia66GY2o7GufTAxpsB8JzOCKZlpx3aMNqc0/v3ZUlHB6S 7jBJ6wTh1H4BkpVBMDbU1OlcsrpuHXi20DaeTaF9p/iVm9x3vpkw0nNTGO7vrpqPwFK0 WD0mIKK4r62jPr4MtixMCGfLHiVgl11Bwba4KcT3mlicJNJX2l2dmSKcvEeL22Ppo5iZ MjwXYV253sp+Svvkm/SiB3JRPlP6rkqoESsuX7tOLJgADlC5ESn6t1YlsW/dEWqnuy2t wyhB/nPWK19heKddLLFUp6zRBL50pZdEm/pv8bOcSls+tmfWT1ZaEyVGuBILaQF/UlVj hvbQ== X-Gm-Message-State: AOAM5323YI/828tmg0CKKSG0vc3WxWAfEk8tmaEXEq6pz6uMCseUWyIh G/rkndAFVieW1w6Zwc86JQMQHGhBEJP5gQ== X-Google-Smtp-Source: ABdhPJwQBxs+c58Adv7oOLpc6yXiCMztbBLJCZBzymldjl3+aYTeGaXhDKZJqe0fE20ZGuj+qPb/ig== X-Received: by 2002:a62:58c2:0:b0:3eb:31ee:cfb9 with SMTP id m185-20020a6258c2000000b003eb31eecfb9mr3412374pfb.31.1629977149163; Thu, 26 Aug 2021 04:25:49 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:a5bc:b3dd:7208:bec1]) by smtp.gmail.com with ESMTPSA id s29sm3472057pgl.38.2021.08.26.04.25.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Aug 2021 04:25:48 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Thu, 26 Aug 2021 20:25:32 +0900 Message-Id: <20210826112539.170694-3-hiroh@chromium.org> X-Mailer: git-send-email 2.33.0.rc2.250.ged5fa647cd-goog In-Reply-To: <20210826112539.170694-1-hiroh@chromium.org> References: <20210826112539.170694-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/9] libcamera: mapped_framebuffer: Return plane begin address by MappedBuffer::maps() 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" MappedBuffer::maps() returns std::vector. Plane has the address, but the address points the beginning of the buffer containing the plane. This makes the Plane point the beginning of the plane. So MappedBuffer::maps()[i].data() returns the address of i-th plane. Signed-off-by: Hirokazu Honda Reviewed-by: Laurent Pinchart --- .../libcamera/internal/mapped_framebuffer.h | 4 +- src/android/mm/generic_camera_buffer.cpp | 2 - src/libcamera/mapped_framebuffer.cpp | 71 ++++++++++++++++--- src/libcamera/v4l2_videodevice.cpp | 6 ++ 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h index 3401a9fc..42479541 100644 --- a/include/libcamera/internal/mapped_framebuffer.h +++ b/include/libcamera/internal/mapped_framebuffer.h @@ -30,12 +30,14 @@ public: bool isValid() const { return error_ == 0; } int error() const { return error_; } - const std::vector &maps() const { return maps_; } + /* \todo rename to planes(). */ + const std::vector &maps() const { return planes_; } protected: MappedBuffer(); int error_; + std::vector planes_; std::vector maps_; private: diff --git a/src/android/mm/generic_camera_buffer.cpp b/src/android/mm/generic_camera_buffer.cpp index d4f3f22b..299a5496 100644 --- a/src/android/mm/generic_camera_buffer.cpp +++ b/src/android/mm/generic_camera_buffer.cpp @@ -53,8 +53,6 @@ private: int flags_; off_t bufferLength_; std::vector planeInfo_; - /* \todo Remove planes_ when it will be added to MappedBuffer */ - std::vector> planes_; }; CameraBuffer::Private::Private([[maybe_unused]] CameraBuffer *cameraBuffer, diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp index 2ebe9fdb..1dc88647 100644 --- a/src/libcamera/mapped_framebuffer.cpp +++ b/src/libcamera/mapped_framebuffer.cpp @@ -7,8 +7,11 @@ #include "libcamera/internal/mapped_framebuffer.h" +#include #include +#include #include +#include #include @@ -79,6 +82,7 @@ MappedBuffer::MappedBuffer(MappedBuffer &&other) MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other) { error_ = other.error_; + planes_ = std::move(other.planes_); maps_ = std::move(other.maps_); other.error_ = -ENOENT; @@ -127,10 +131,18 @@ MappedBuffer::~MappedBuffer() */ /** - * \var MappedBuffer::maps_ + * \var MappedBuffer::planes_ * \brief Stores the internal mapped planes * * MappedBuffer derived classes shall store the mappings they create in this + * vector which points the beginning of mapped plane addresses. + */ + +/** + * \var MappedBuffer::maps_ + * \brief Stores the mapped buffer + * + * MappedBuffer derived classes shall store the mappings they create in this * vector which is parsed during destruct to unmap any memory mappings which * completed successfully. */ @@ -167,7 +179,8 @@ MappedBuffer::~MappedBuffer() */ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags) { - maps_.reserve(buffer->planes().size()); + ASSERT(!buffer->planes().empty()); + planes_.reserve(buffer->planes().size()); int mmapFlags = 0; @@ -177,17 +190,55 @@ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags) if (flags & MapFlag::Write) mmapFlags |= PROT_WRITE; + struct MappedBufferInfo { + uint8_t *address = nullptr; + size_t mapLength = 0; + size_t dmabufLength = 0; + }; + std::map mappedBuffers; + + for (const FrameBuffer::Plane &plane : buffer->planes()) { + const int fd = plane.fd.fd(); + if (mappedBuffers.find(fd) == mappedBuffers.end()) { + const size_t length = lseek(fd, 0, SEEK_END); + mappedBuffers[fd] = MappedBufferInfo{ nullptr, 0, length }; + } + + const size_t length = mappedBuffers[fd].dmabufLength; + + if (plane.offset > length || + plane.offset + plane.length > length) { + LOG(Buffer, Fatal) << "plane is out of buffer: " + << "buffer length=" << length + << ", plane offset=" << plane.offset + << ", plane length=" << plane.length; + return; + } + size_t &mapLength = mappedBuffers[fd].mapLength; + mapLength = std::max(mapLength, + static_cast(plane.offset + plane.length)); + } + for (const FrameBuffer::Plane &plane : buffer->planes()) { - void *address = mmap(nullptr, plane.length, mmapFlags, - MAP_SHARED, plane.fd.fd(), 0); - if (address == MAP_FAILED) { - error_ = -errno; - LOG(Buffer, Error) << "Failed to mmap plane: " - << strerror(-error_); - break; + const int fd = plane.fd.fd(); + auto &info = mappedBuffers[fd]; + if (!info.address) { + void *address = + static_cast( + mmap(nullptr, info.mapLength, mmapFlags, + MAP_SHARED, fd, 0)); + if (address == MAP_FAILED) { + error_ = -errno; + LOG(Buffer, Error) << "Failed to mmap plane: " + << strerror(-error_); + return; + } + + info.address = static_cast(address); + maps_.emplace_back(info.address, info.mapLength); } - maps_.emplace_back(static_cast(address), plane.length); + planes_.emplace_back(info.address + plane.offset, plane.length); } } diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index ce60dff6..2ff25af2 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -1283,6 +1283,12 @@ std::unique_ptr V4L2VideoDevice::createBuffer(unsigned int index) FrameBuffer::Plane plane; plane.fd = std::move(fd); + /* + * V4L2 API doesn't provide dmabuf offset information of plane. + * Set 0 as a placeholder offset. + * \todo Set the right offset once V4L2 API provides a way. + */ + plane.offset = 0; plane.length = multiPlanar ? buf.m.planes[nplane].length : buf.length;