From patchwork Wed Aug 11 12:40:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13302 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 D18EFBD87D for ; Wed, 11 Aug 2021 12:40:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8233E68889; Wed, 11 Aug 2021 14:40:27 +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="hd6C0FON"; dkim-atps=neutral Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5BD1568887 for ; Wed, 11 Aug 2021 14:40:26 +0200 (CEST) Received: by mail-pj1-x1033.google.com with SMTP id mq2-20020a17090b3802b0290178911d298bso4625321pjb.1 for ; Wed, 11 Aug 2021 05:40:26 -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=lQiq0GEAYbCg/uzaZZgmDr/dO8jHINNLWTeG67DI18o=; b=hd6C0FONK/vS5+HpPPYsf0mBhNkEnZOs8OJoiaB8gQa6oCCkczZfWDtstvpaUxR1gq znFicgImUqrbkmZegTm6T2uXqzFKeXSyDv11WTed2t6ZVYc1qJrd76ob3Hjm6tHe829J V/nmCyW3mb9tPYG1wGSq/VGBpaTLsEQVrvraU= 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=lQiq0GEAYbCg/uzaZZgmDr/dO8jHINNLWTeG67DI18o=; b=K1/1+TvjcW0Gqx5VL4dIabxun2jck3TYyPM7CCVsVfb9xjvBpeerBmcePcCIjuW0TR i976kelDKPLAtrprSphvrR+6hBHiCuOUqmmTwveBfzClG0VDmoBTduZ4lRyTgfO6ourG 73FY5klJtgK2s3pHhFHLFb52c5RAnUsv9kTJ+1B30c1w1lDGjwXPR9zneh39bzhxZuV0 zIIAGoQM2MaoZ4Rl5mtXcKZJOylfvQmGyVNC0P9iZE44KRVF6ZxEosV0dN1jI7sPV4xL c8FwzfXjN4DOkkRODyIz9oo2Fsya8KkwHexvN8OUFnwjQFtZiFrzixpX9efwugSGjhLK Yb5g== X-Gm-Message-State: AOAM530iWXJP8XNJW7gKzXi5qaT4o3ly6Py3eE65C5XwgcpFrGufzeGw sOSJvxZ0pbWh7wDizcc1U4YgNda4/9sSng== X-Google-Smtp-Source: ABdhPJxzuCIgI0O0Zdun4srfar6sya/FsJJ7LimAsUo9YpaSQDyd4MkYgMVEcnCYjBMLBN/9CLTzIA== X-Received: by 2002:a17:90b:3014:: with SMTP id hg20mr25539426pjb.140.1628685624641; Wed, 11 Aug 2021 05:40:24 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:ba11:c25e:242c:485d]) by smtp.gmail.com with ESMTPSA id p30sm15722876pfh.116.2021.08.11.05.40.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Aug 2021 05:40:24 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Wed, 11 Aug 2021 21:40:11 +0900 Message-Id: <20210811124015.2116188-2-hiroh@chromium.org> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog In-Reply-To: <20210811124015.2116188-1-hiroh@chromium.org> References: <20210811124015.2116188-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 1/5] 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 --- .../libcamera/internal/mapped_framebuffer.h | 4 +- src/libcamera/mapped_framebuffer.cpp | 59 +++++++++++++++---- 2 files changed, 52 insertions(+), 11 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/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp index 2ebe9fdb..5d5b02f1 100644 --- a/src/libcamera/mapped_framebuffer.cpp +++ b/src/libcamera/mapped_framebuffer.cpp @@ -9,6 +9,7 @@ #include #include +#include #include @@ -79,6 +80,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 +129,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 +177,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,18 +188,46 @@ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags) if (flags & MapFlag::Write) mmapFlags |= PROT_WRITE; + size_t offset = 0; + int prevFd = -1; 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(); + if (prevFd != fd) { + const size_t length = lseek(fd, 0, SEEK_END); + void *address = mmap(nullptr, length, mmapFlags, + MAP_SHARED, fd, 0); + if (address == MAP_FAILED) { + error_ = -errno; + LOG(Buffer, Error) << "Failed to mmap plane: " + << strerror(-error_); + break; + } + maps_.emplace_back(static_cast(address), + length); + prevFd = fd; } - maps_.emplace_back(static_cast(address), plane.length); + ASSERT(!maps_.empty()); + uint8_t *buf = maps_.back().data(); + const size_t length = maps_.back().size(); + + /* + * This offset calculation assumes planes are consecutive. + * \todo remove this assumption once offset is introduced to + * FrameBuffer::Plane. + */ + planes_.emplace_back(buf + offset, plane.length); + offset += plane.length; + + if (offset > length) { + LOG(Buffer, Fatal) + << "plane length is too large: plane lengths=" + << offset << ", buffer length=" << length; + break; + } } + + ASSERT(maps_.size() == 1); } } /* namespace libcamera */ From patchwork Wed Aug 11 12:40:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13303 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 2C13FBD87D for ; Wed, 11 Aug 2021 12:40:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DA2376888C; Wed, 11 Aug 2021 14:40:29 +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="AiagiqC1"; dkim-atps=neutral Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0428468887 for ; Wed, 11 Aug 2021 14:40:28 +0200 (CEST) Received: by mail-pj1-x102a.google.com with SMTP id lw7-20020a17090b1807b029017881cc80b7so9297041pjb.3 for ; Wed, 11 Aug 2021 05:40:27 -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=loAwEKmkTZ2pc3VR3JLr5v3gT+NaKdhxObYxcW9rqlI=; b=AiagiqC1cHWqHXMRoHnNZLZ5DWn+wyhWZ7QH8wpa6OB+d2c+BHi3xs99z17f2VNLFf IokR3Tje0NFQXuOzpHxi7kjsGdcpCE8EX8ERjugE7zo5HyPzkgzvuMlqCAcfT3B/8icb 9e8d0dwG2Mhl/e8IaXmL6XQlOt6TzQw5RRjLA= 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=loAwEKmkTZ2pc3VR3JLr5v3gT+NaKdhxObYxcW9rqlI=; b=Xyp8VC44BBxfErYH9+U1x2k6SbB9mqNgKXwTXMH4KsTFfDH/nLZ/Df49tGoG2l9jzu cBPD6tsRKdF5o9wXd2L45GTMQIi0FsW4Z5XQAY4tilSuo4Yg0DhHvTlCK+wQ9GG0kHFJ VUMy9OdfLZogD6PniNuWkeSyp7uDZmVI2sUvC9mAiT9j4RdsH1lEcMH/OuFYJSi5hReW CecAsjSc8bg0Sp6sNUYypfFk64UEaeJkxXgv5/fV1V2X3CBFW/ExJw3/XowYeZSb1eP8 ZgYoKpvMhtJfUzqysAkfCJC6jFtSPj5NBSuwiZvekg3V93TlUOrH6FicieN6u4MePnFF YxDA== X-Gm-Message-State: AOAM531HDeiF/QvLZTTXgQNDy4B8HgV2ZoTjMbQ52dnKWBN8DueUTkK8 lR8BeiBe44t5VcE+dXV3KuQZraXp9uZ/sg== X-Google-Smtp-Source: ABdhPJwMetrLR6tN6wG3toFICjLlwaMgU8y1Z/J1srwMU1/aR8ON92Dy8ohqqDp1970qeDa8In3w+w== X-Received: by 2002:a17:90b:903:: with SMTP id bo3mr19232948pjb.103.1628685626304; Wed, 11 Aug 2021 05:40:26 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:ba11:c25e:242c:485d]) by smtp.gmail.com with ESMTPSA id p30sm15722876pfh.116.2021.08.11.05.40.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Aug 2021 05:40:25 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Wed, 11 Aug 2021 21:40:12 +0900 Message-Id: <20210811124015.2116188-3-hiroh@chromium.org> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog In-Reply-To: <20210811124015.2116188-1-hiroh@chromium.org> References: <20210811124015.2116188-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 2/5] cam: file_sink: Fix wrong mapping planes 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" FileSink maps FrameBuffer in a wrong way that the mapped data points the address of a buffer, not plane. This fixes it. Signed-off-by: Hirokazu Honda --- src/cam/file_sink.cpp | 30 +++++++++++++++++++++++++----- src/cam/file_sink.h | 1 + 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/cam/file_sink.cpp b/src/cam/file_sink.cpp index 2d30694a..267f7ea2 100644 --- a/src/cam/file_sink.cpp +++ b/src/cam/file_sink.cpp @@ -51,12 +51,32 @@ int FileSink::configure(const libcamera::CameraConfiguration &config) void FileSink::mapBuffer(FrameBuffer *buffer) { + /* \todo Use MappedFrameBuffer. */ + size_t offset = 0; + int prevFd = -1; for (const FrameBuffer::Plane &plane : buffer->planes()) { - void *memory = mmap(NULL, plane.length, PROT_READ, MAP_SHARED, - plane.fd.fd(), 0); + const int fd = plane.fd.fd(); + if (prevFd != fd) { + const size_t length = lseek(fd, 0, SEEK_END); + void *address = mmap(nullptr, length, PROT_READ, + MAP_SHARED, fd, 0); + if (address == MAP_FAILED) { + std::cerr << "Failed to mmap plane: " + << strerror(errno) << std::endl; + return; + } + mappedBuffers_[fd] = std::make_pair(address, length); + prevFd = fd; + } - mappedBuffers_[plane.fd.fd()] = - std::make_pair(memory, plane.length); + uint8_t *buf = static_cast(mappedBuffers_[fd].first); + /* + * This offset calculation assumes planes are consecutive. + * \todo remove this assumption once offset is introduced to + * FrameBuffer::Plane. + */ + planeData_[fd] = static_cast(buf + offset); + offset += plane.length; } } @@ -102,7 +122,7 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer) const FrameBuffer::Plane &plane = buffer->planes()[i]; const FrameMetadata::Plane &meta = buffer->metadata().planes[i]; - void *data = mappedBuffers_[plane.fd.fd()].first; + void *data = planeData_[plane.fd.fd()]; unsigned int length = std::min(meta.bytesused, plane.length); if (meta.bytesused > plane.length) diff --git a/src/cam/file_sink.h b/src/cam/file_sink.h index c3eb230a..d236d6d8 100644 --- a/src/cam/file_sink.h +++ b/src/cam/file_sink.h @@ -33,6 +33,7 @@ private: std::map streamNames_; std::string pattern_; std::map> mappedBuffers_; + std::map planeData_; }; #endif /* __CAM_FILE_SINK_H__ */ From patchwork Wed Aug 11 12:40:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13304 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 81698C3240 for ; Wed, 11 Aug 2021 12:40:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3B5BD68855; Wed, 11 Aug 2021 14:40:32 +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="K3f0lco7"; dkim-atps=neutral Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CD02868887 for ; Wed, 11 Aug 2021 14:40:29 +0200 (CEST) Received: by mail-pl1-x62d.google.com with SMTP id d17so2496299plr.12 for ; Wed, 11 Aug 2021 05:40:29 -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=HiIbadVkUYWpBSWximDdu0NkuYjyYDssTrmu7Q5oHf0=; b=K3f0lco7ifLXjpNIKrcvTI5ecZGaQJr2IfOhEOPUkrMwishWKiPfe6jJb++lNtxDwU D9DJ+0Qla1hQPb/NnoL8uAHxsa6NhMT6SCE3Shi4EsJxgGKQAOvHHMTEGsn5QhpMBW+B 2l7td3F30QPxFIhhVb2A1ASJ+cxMaeoDrOWmE= 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=HiIbadVkUYWpBSWximDdu0NkuYjyYDssTrmu7Q5oHf0=; b=s8zOuJcRReWqAyHKRY4BZDnRyXBCFc0nzDqRskgCmEa075DQxz6Uuxm9O0gZ+eVw3m 93Kv8+jqk9KtTefaWQ1haLU9JXtXygUkRFig61GTIfAxRX3HauPSsVWdZF1CP8WhwHJt RZmyUdzF9Bv7+ipQw0a4BAyo4DDh0xEGI5KqgHm3/us8rRc9hIb/CLG85HGigLgXMj1I mCIWCgSt+v7sbRyE+NUPiRbudGhGxkr0nhdtU1cFQRcFCZObQLPBVtMufKm6Nv83Tcw5 tzBuIqE8n9AFjLho/F5a0HJ6T38YSzc61vNdBSLwk0GKUQRNrCA7+ITgHp60jXWhqdLA 0Uuw== X-Gm-Message-State: AOAM530LqCn3NQL+UTHkgZQ+6RKuiFIuzkdsB3ezKrOM9ZDb034B7iEJ eWkLjfkxkT8wAD3lfiv7yNL6boe7u8c/Lg== X-Google-Smtp-Source: ABdhPJw09cPcpvWfcgNWE/onk1Z9GrXuA8x9kpcYNd0xm/CPMwCY8osWxa+T8J58o6BVXCFLRKO7tw== X-Received: by 2002:aa7:8b07:0:b029:3c7:c29f:9822 with SMTP id f7-20020aa78b070000b02903c7c29f9822mr27449149pfd.33.1628685627993; Wed, 11 Aug 2021 05:40:27 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:ba11:c25e:242c:485d]) by smtp.gmail.com with ESMTPSA id p30sm15722876pfh.116.2021.08.11.05.40.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Aug 2021 05:40:27 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Wed, 11 Aug 2021 21:40:13 +0900 Message-Id: <20210811124015.2116188-4-hiroh@chromium.org> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog In-Reply-To: <20210811124015.2116188-1-hiroh@chromium.org> References: <20210811124015.2116188-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 3/5] android: camera_device: Fills the size of plane to FrameBuffer::Plane::length 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" CameraDevice fills the size of a buffer to FrameBuffer::Plane::length. It should rather fill the size of a plane to it. Signed-off-by: Hirokazu Honda --- src/android/camera_device.cpp | 37 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index a69b687a..f10f27b7 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -746,29 +747,31 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer) { - std::vector planes; + FileDescriptor fd; + /* This assumes all the planes are in the same buffer. */ for (int i = 0; i < camera3buffer->numFds; i++) { /* Skip unused planes. */ - if (camera3buffer->data[i] == -1) + if (camera3buffer->data[i] != -1) { + fd = FileDescriptor(camera3buffer->data[i]); break; - - FrameBuffer::Plane plane; - plane.fd = FileDescriptor(camera3buffer->data[i]); - if (!plane.fd.isValid()) { - LOG(HAL, Error) << "Failed to obtain FileDescriptor (" - << camera3buffer->data[i] << ") " - << " on plane " << i; - return nullptr; } + } - off_t length = lseek(plane.fd.fd(), 0, SEEK_END); - if (length == -1) { - LOG(HAL, Error) << "Failed to query plane length"; - return nullptr; - } + if (!fd.isValid()) { + LOG(HAL, Fatal) << "No valid fd"; + return nullptr; + } + + CameraBuffer buf(camera3buffer, PROT_READ); + if (!buf.isValid()) { + LOG(HAL, Fatal) << "Failed mapping buffer"; + return nullptr; + } - plane.length = length; - planes.push_back(std::move(plane)); + std::vector planes(buf.numPlanes()); + for (size_t i = 0; i < buf.numPlanes(); ++i) { + planes[i].fd = fd; + planes[i].length = buf.plane(i).size(); } return new FrameBuffer(std::move(planes)); From patchwork Wed Aug 11 12:40:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13305 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 CDF79C3241 for ; Wed, 11 Aug 2021 12:40:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8AE9668889; Wed, 11 Aug 2021 14:40:32 +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="GRtFzgKG"; dkim-atps=neutral Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 73F0768855 for ; Wed, 11 Aug 2021 14:40:31 +0200 (CEST) Received: by mail-pj1-x1029.google.com with SMTP id w13-20020a17090aea0db029017897a5f7bcso4585433pjy.5 for ; Wed, 11 Aug 2021 05:40:31 -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=WBUGIjr+wc7ofyPPRfY1jSJxy/NlmDYAAjxmkELPkXY=; b=GRtFzgKGzQB911DjENlPHZs3p4Pdj43SOGbMmErgRaHKIycEJCxHz71HQs94YsSapK I8FwSm25CnCyS2/fsbhKJjCA97j1yR4mFsJRqQ/PP8dxAz/6zR4vj/6Yefk1ghOFaudZ b+qTIh2/M3RhUCsP+PxNaOg3Pgffe3RJXCIWQ= 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=WBUGIjr+wc7ofyPPRfY1jSJxy/NlmDYAAjxmkELPkXY=; b=YnH4urc85Ez7SFUAxeMIYGdRlrLO8PCqi4DPWVQ1FgW7I3t0vWF0Jt6BNtoBA+1QdO AL++MaNl1cBvP02KDZa2iCk1XN7tYhzujeFYzeC4+Ht0rv+9QChdJ9dm7N64xjz6mc4m OqGJUcHMa8y0E2AJ9qUrHAfEnPf13qOVRtJnUG4gBwnbJuycNS2kN7tTelaFzSF6oADl kkjYoDxulwqevyJ0a1/J0hV2EGEUYnrZyS0vTcy7oSUjHvzPCMyGMTjwkyPbQyb7g3Yq BXG+5n2I29hmwOsnodQdUXHX6grUQxhqGIXixhE2rJfJ0Dflw5P7Rcta4gFeJq0Nc50a zS2w== X-Gm-Message-State: AOAM530/vP9XOQGwC4bQgNiVynMUm6bfWfDBP4/UCwP6/FUZLFCr1JPl nAtB5usLaPDch21DYd5lpZtWM7q8iIAaTA== X-Google-Smtp-Source: ABdhPJwctDQaZFE/ajeV1RGtWgcRPzBoZCcp30HGWz3gt8SvQ1sWU+5Hquqfwy7dtsOlr4IWUMXJnw== X-Received: by 2002:aa7:9f12:0:b029:3e0:3224:6cd5 with SMTP id g18-20020aa79f120000b02903e032246cd5mr1976379pfr.43.1628685629748; Wed, 11 Aug 2021 05:40:29 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:ba11:c25e:242c:485d]) by smtp.gmail.com with ESMTPSA id p30sm15722876pfh.116.2021.08.11.05.40.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Aug 2021 05:40:29 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Wed, 11 Aug 2021 21:40:14 +0900 Message-Id: <20210811124015.2116188-5-hiroh@chromium.org> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog In-Reply-To: <20210811124015.2116188-1-hiroh@chromium.org> References: <20210811124015.2116188-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 4/5] WIP: libcamera: V4L2VideoDevice: Fix a bug in CreateBuffer() 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" FrameBuffer created in V4L2VideoDevice::CreateBuffer() has the same number of planes as v4l2 buffer planes. However, if the format is a single planar format, the number of planes is one. FrameBuffer should have the same number of planes as color format planes. Signed-off-by: Hirokazu Honda --- src/libcamera/v4l2_videodevice.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index ce60dff6..e70076f3 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -1269,7 +1269,6 @@ std::unique_ptr V4L2VideoDevice::createBuffer(unsigned int index) const bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type); const unsigned int numPlanes = multiPlanar ? buf.length : 1; - if (numPlanes == 0 || numPlanes > VIDEO_MAX_PLANES) { LOG(V4L2, Error) << "Invalid number of planes"; return nullptr; @@ -1289,6 +1288,20 @@ std::unique_ptr V4L2VideoDevice::createBuffer(unsigned int index) planes.push_back(std::move(plane)); } + + V4L2DeviceFormat format{}; + ret = getFormat(&format); + if (ret < 0) { + LOG(V4L2, Error) << "Failed to get buffer format"; + return nullptr; + } + if (format.fourcc == V4L2_PIX_FMT_NV12) { + planes.resize(2); + planes[0].length = format.size.width * format.size.height; + planes[1].fd = planes[0].fd; + planes[1].length = format.size.width * ((format.size.height + 1) / 2); + } + return std::make_unique(std::move(planes)); } From patchwork Wed Aug 11 12:40:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13306 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 48BFEC3242 for ; Wed, 11 Aug 2021 12:40:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DF4C96888F; Wed, 11 Aug 2021 14:40:34 +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="kkHIv9xN"; dkim-atps=neutral Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AA6906884D for ; Wed, 11 Aug 2021 14:40:33 +0200 (CEST) Received: by mail-pj1-x102e.google.com with SMTP id hv22-20020a17090ae416b0290178c579e424so4587628pjb.3 for ; Wed, 11 Aug 2021 05:40: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=7KSQpt515bp2ZRdRFLOpnhZCNt2r9Wb+3ftNdr4TIMA=; b=kkHIv9xNK009p3ansmvWn/+iW6ipCnTdqL3quEfGxLqL7Z3XrOMo11XpvcChsX6hzZ b9QVpwPsUtV7Df44dLO/BEV7Q9v4KBG/saN8L/MSrq1M/tx+tPjDzjLNIDsTduPh7+Ir yUKcrQeUo6e6OQx3p9LYg1+FJR8wkIWqGrc3E= 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=7KSQpt515bp2ZRdRFLOpnhZCNt2r9Wb+3ftNdr4TIMA=; b=YFh7i4xT2pzmTNTJHdAxugyjUj2bFLv9Mqy2Uxu/tTB8eRlJnhVwLV8KMwxRBXKQKa icTKKBPVrCP//q9GqVK+IEj8U7wKure6AB8c/wDTq2WjKcumeXo0DO8rjkjsfe9CLEsS uiyQnK0c2N8f96KOEhnAI681MENGvleV6nH/cJEe2d4hg3+ZkL/2am0lMAeeWPzWl2lC R2R2J05MG2pQ33/Y7zPv1Rrjri6aTUfQP+UA5da/JEa69b1bml0xcXuNmN04OL58ZIvy Ip/LnaAZJNYBIchl5lge+5Zkd5adrqspc9F1VNX1Fjw2KH2qEwhzLqLCJbWwIdxneWeX uW2A== X-Gm-Message-State: AOAM531RtGFxNjtx5LR3YxqsiJZHG+ZMcYl7BSs6KdSsXFkSrzen8KTT IzYsFWvGP/bxLD95GyCF8Pi1/aQtqkGlSw== X-Google-Smtp-Source: ABdhPJw9Aup2jFjCmI8wOd8N3UaVggincMC6Of0XL4y8N0/4IWcmRH8RH0oRPSxYUpLOctQAjI+gpw== X-Received: by 2002:a63:2217:: with SMTP id i23mr820672pgi.448.1628685631929; Wed, 11 Aug 2021 05:40:31 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:ba11:c25e:242c:485d]) by smtp.gmail.com with ESMTPSA id p30sm15722876pfh.116.2021.08.11.05.40.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Aug 2021 05:40:31 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Wed, 11 Aug 2021 21:40:15 +0900 Message-Id: <20210811124015.2116188-6-hiroh@chromium.org> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog In-Reply-To: <20210811124015.2116188-1-hiroh@chromium.org> References: <20210811124015.2116188-1-hiroh@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 5/5] WIP: android: jpeg: Use maps() and clean up 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" WIP Signed-off-by: Hirokazu Honda --- src/android/jpeg/encoder.h | 7 +++-- src/android/jpeg/encoder_libjpeg.cpp | 32 ++++++--------------- src/android/jpeg/encoder_libjpeg.h | 10 ++----- src/android/jpeg/post_processor_jpeg.cpp | 21 ++++++++++---- src/android/jpeg/thumbnailer.cpp | 36 ++++++++++++++++++++---- src/android/jpeg/thumbnailer.h | 4 ++- src/libcamera/mapped_framebuffer.cpp | 2 ++ 7 files changed, 66 insertions(+), 46 deletions(-) diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h index a28522f4..2b9b8fca 100644 --- a/src/android/jpeg/encoder.h +++ b/src/android/jpeg/encoder.h @@ -8,17 +8,18 @@ #define __ANDROID_JPEG_ENCODER_H__ #include - -#include #include +#include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/mapped_framebuffer.h" + class Encoder { public: virtual ~Encoder() = default; virtual int configure(const libcamera::StreamConfiguration &cfg) = 0; - virtual int encode(const libcamera::FrameBuffer &source, + virtual int encode(const libcamera::MappedFrameBuffer &source, libcamera::Span destination, libcamera::Span exifData, unsigned int quality) = 0; diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index a7a63601..188aabdb 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -94,7 +94,6 @@ int EncoderLibJpeg::configure(const StreamConfiguration &cfg) compress_.input_components = info.colorSpace == JCS_GRAYSCALE ? 1 : 3; jpeg_set_defaults(&compress_); - pixelFormatInfo_ = &info.pixelFormatInfo; nv_ = pixelFormatInfo_->numPlanes() == 2; @@ -103,9 +102,9 @@ int EncoderLibJpeg::configure(const StreamConfiguration &cfg) return 0; } -void EncoderLibJpeg::compressRGB(Span frame) +void EncoderLibJpeg::compressRGB(const libcamera::MappedFrameBuffer &frame) { - unsigned char *src = const_cast(frame.data()); + unsigned char *src = const_cast(frame.maps()[0].data()); /* \todo Stride information should come from buffer configuration. */ unsigned int stride = pixelFormatInfo_->stride(compress_.image_width, 0); @@ -121,7 +120,7 @@ void EncoderLibJpeg::compressRGB(Span frame) * Compress the incoming buffer from a supported NV format. * This naively unpacks the semi-planar NV12 to a YUV888 format for libjpeg. */ -void EncoderLibJpeg::compressNV(Span frame) +void EncoderLibJpeg::compressNV(const libcamera::MappedFrameBuffer &frame) { uint8_t tmprowbuf[compress_.image_width * 3]; @@ -143,8 +142,8 @@ void EncoderLibJpeg::compressNV(Span frame) unsigned int cb_pos = nvSwap_ ? 1 : 0; unsigned int cr_pos = nvSwap_ ? 0 : 1; - const unsigned char *src = frame.data(); - const unsigned char *src_c = src + y_stride * compress_.image_height; + const unsigned char *src = frame.maps()[0].data(); + const unsigned char *src_c = frame.maps()[1].data(); JSAMPROW row_pointer[1]; row_pointer[0] = &tmprowbuf[0]; @@ -152,7 +151,7 @@ void EncoderLibJpeg::compressNV(Span frame) for (unsigned int y = 0; y < compress_.image_height; y++) { unsigned char *dst = &tmprowbuf[0]; - const unsigned char *src_y = src + y * compress_.image_width; + const unsigned char *src_y = src + y * y_stride; const unsigned char *src_cb = src_c + (y / vertSubSample) * c_stride + cb_pos; const unsigned char *src_cr = src_c + (y / vertSubSample) * c_stride + cr_pos; @@ -178,20 +177,7 @@ void EncoderLibJpeg::compressNV(Span frame) } } -int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, - Span exifData, unsigned int quality) -{ - MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); - if (!frame.isValid()) { - LOG(JPEG, Error) << "Failed to map FrameBuffer : " - << strerror(frame.error()); - return frame.error(); - } - - return encode(frame.maps()[0], dest, exifData, quality); -} - -int EncoderLibJpeg::encode(Span src, Span dest, +int EncoderLibJpeg::encode(const MappedFrameBuffer &source, Span dest, Span exifData, unsigned int quality) { unsigned char *destination = dest.data(); @@ -221,9 +207,9 @@ int EncoderLibJpeg::encode(Span src, Span dest, << "x" << compress_.image_height; if (nv_) - compressNV(src); + compressNV(source); else - compressRGB(src); + compressRGB(source); jpeg_finish_compress(&compress_); diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index 61fbd1a6..588756aa 100644 --- a/src/android/jpeg/encoder_libjpeg.h +++ b/src/android/jpeg/encoder_libjpeg.h @@ -20,18 +20,14 @@ public: ~EncoderLibJpeg(); int configure(const libcamera::StreamConfiguration &cfg) override; - int encode(const libcamera::FrameBuffer &source, + int encode(const libcamera::MappedFrameBuffer &source, libcamera::Span destination, libcamera::Span exifData, unsigned int quality) override; - int encode(libcamera::Span source, - libcamera::Span destination, - libcamera::Span exifData, - unsigned int quality); private: - void compressRGB(libcamera::Span frame); - void compressNV(libcamera::Span frame); + void compressRGB(const libcamera::MappedFrameBuffer &frame); + void compressNV(const libcamera::MappedFrameBuffer &frame); struct jpeg_compress_struct compress_; struct jpeg_error_mgr jerr_; diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 3160a784..354e4fdd 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -56,8 +56,7 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source, std::vector *thumbnail) { /* Stores the raw scaled-down thumbnail bytes. */ - std::vector rawThumbnail; - + std::unique_ptr rawThumbnail; thumbnailer_.createThumbnail(source, targetSize, &rawThumbnail); StreamConfiguration thCfg; @@ -65,14 +64,17 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source, thCfg.pixelFormat = thumbnailer_.pixelFormat(); int ret = thumbnailEncoder_.configure(thCfg); - if (!rawThumbnail.empty() && !ret) { + if (rawThumbnail && !ret) { /* * \todo Avoid value-initialization of all elements of the * vector. */ - thumbnail->resize(rawThumbnail.size()); + size_t thumbnail_size = 0; + for (const MappedBuffer::Plane &plane : rawThumbnail->maps()) + thumbnail_size += plane.size(); + thumbnail->resize(thumbnail_size); - int jpeg_size = thumbnailEncoder_.encode(rawThumbnail, + int jpeg_size = thumbnailEncoder_.encode(*rawThumbnail, *thumbnail, {}, quality); thumbnail->resize(jpeg_size); @@ -177,7 +179,14 @@ int PostProcessorJpeg::process(const FrameBuffer &source, const uint8_t quality = ret ? *entry.data.u8 : 95; resultMetadata->addEntry(ANDROID_JPEG_QUALITY, quality); - int jpeg_size = encoder_->encode(source, destination->plane(0), + MappedFrameBuffer mapped(&source, MappedFrameBuffer::MapFlag::Read); + if (!mapped.isValid()) { + LOG(JPEG, Error) << "Failed to map FrameBuffer : " + << strerror(mapped.error()); + return mapped.error(); + } + + int jpeg_size = encoder_->encode(mapped, destination->plane(0), exif.data(), quality); if (jpeg_size < 0) { LOG(JPEG, Error) << "Failed to encode stream image"; diff --git a/src/android/jpeg/thumbnailer.cpp b/src/android/jpeg/thumbnailer.cpp index 79d83926..e8fa9f84 100644 --- a/src/android/jpeg/thumbnailer.cpp +++ b/src/android/jpeg/thumbnailer.cpp @@ -8,6 +8,7 @@ #include "thumbnailer.h" #include +#include #include @@ -17,6 +18,24 @@ using namespace libcamera; LOG_DEFINE_CATEGORY(Thumbnailer) +namespace { +class MappedThumbnailBuffer : public MappedFrameBuffer +{ +public: + MappedThumbnailBuffer(std::vector buffer, + const std::vector> &planes) + : MappedFrameBuffer(nullptr, MapFlag::Read), + buffer_(std::move(buffer)) + { + planes_ = planes; + } + +private: + std::vector buffer_; +}; + +} // namespace + Thumbnailer::Thumbnailer() : valid_(false) { @@ -39,7 +58,7 @@ void Thumbnailer::configure(const Size &sourceSize, PixelFormat pixelFormat) void Thumbnailer::createThumbnail(const FrameBuffer &source, const Size &targetSize, - std::vector *destination) + std::unique_ptr *destination) { MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); if (!frame.isValid()) { @@ -63,14 +82,19 @@ void Thumbnailer::createThumbnail(const FrameBuffer &source, /* Image scaling block implementing nearest-neighbour algorithm. */ unsigned char *src = static_cast(frame.maps()[0].data()); - unsigned char *srcC = src + sh * sw; + unsigned char *srcC = static_cast(frame.maps()[1].data()); unsigned char *srcCb, *srcCr; unsigned char *dstY, *srcY; - size_t dstSize = (th * tw) + ((th / 2) * tw); - destination->resize(dstSize); - unsigned char *dst = destination->data(); - unsigned char *dstC = dst + th * tw; + std::vector buffer(th * tw + (th / 2) * tw); + std::vector> dstPlanes = { + { buffer.data(), th * tw }, + { buffer.data() + th * tw, (th / 2) * tw } + }; + unsigned char *dst = static_cast(dstPlanes[0].data()); + unsigned char *dstC = static_cast(dstPlanes[1].data()); + *destination = std::make_unique(std::move(buffer), + dstPlanes); for (unsigned int y = 0; y < th; y += 2) { unsigned int sourceY = (sh * y + th / 2) / th; diff --git a/src/android/jpeg/thumbnailer.h b/src/android/jpeg/thumbnailer.h index 4d086c49..9c938588 100644 --- a/src/android/jpeg/thumbnailer.h +++ b/src/android/jpeg/thumbnailer.h @@ -11,6 +11,7 @@ #include #include "libcamera/internal/formats.h" +#include "libcamera/internal/mapped_framebuffer.h" class Thumbnailer { @@ -21,7 +22,8 @@ public: libcamera::PixelFormat pixelFormat); void createThumbnail(const libcamera::FrameBuffer &source, const libcamera::Size &targetSize, - std::vector *dest); + std::unique_ptr *dest); + const libcamera::PixelFormat &pixelFormat() const { return pixelFormat_; } private: diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp index 5d5b02f1..e5647127 100644 --- a/src/libcamera/mapped_framebuffer.cpp +++ b/src/libcamera/mapped_framebuffer.cpp @@ -177,6 +177,8 @@ MappedBuffer::~MappedBuffer() */ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags) { + if (!buffer) + return; ASSERT(!buffer->planes().empty()); planes_.reserve(buffer->planes().size());