Patch Detail
Show a patch.
GET /api/patches/13693/?format=api
{ "id": 13693, "url": "https://patchwork.libcamera.org/api/patches/13693/?format=api", "web_url": "https://patchwork.libcamera.org/patch/13693/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20210906225636.14683-27-laurent.pinchart@ideasonboard.com>", "date": "2021-09-06T22:56:33", "name": "[libcamera-devel,v3,27/30] qcam: Use Image class to access pixel data", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "0bbcd972fbefec2eae0d26872ebc1425422d00d1", "submitter": { "id": 2, "url": "https://patchwork.libcamera.org/api/people/2/?format=api", "name": "Laurent Pinchart", "email": "laurent.pinchart@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/13693/mbox/", "series": [ { "id": 2482, "url": "https://patchwork.libcamera.org/api/series/2482/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2482", "date": "2021-09-06T22:54:20", "name": "libcamera: Handle fallout of FrameBuffer offset support", "version": 3, "mbox": "https://patchwork.libcamera.org/series/2482/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/13693/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/13693/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 B35E9BE175\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 6 Sep 2021 22:57:50 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6888F69168;\n\tTue, 7 Sep 2021 00:57:50 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B7C9A6918E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 7 Sep 2021 00:57:09 +0200 (CEST)", "from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 52530891;\n\tTue, 7 Sep 2021 00:57:09 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"IYy/keTp\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1630969029;\n\tbh=FQyMhKOgdpFBah23uV5iA8J43CwjXu3uyYsE0tW5buY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=IYy/keTpUyxqEEzGXzorhpTFKLExh4wPHG3RjADb4IAR8ZhImtZo65mHK4zl7yhMc\n\tW2HuVjn9HY8bbEC2GosWcZijKmMyEMZgYTSZkPFVMHTYyOmGl+z0HBjsfa8zuRBjeF\n\t/s6xUBq2mvOtAktzydjhjoTdAARD175poWAsTtvs=", "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Tue, 7 Sep 2021 01:56:33 +0300", "Message-Id": "<20210906225636.14683-27-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.32.0", "In-Reply-To": "<20210906225420.13275-1-laurent.pinchart@ideasonboard.com>", "References": "<20210906225420.13275-1-laurent.pinchart@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v3 27/30] qcam: Use Image class to access\n\tpixel data", "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": "Replace the manual implementation of frame buffer mapping with the Image\nclass to improve code sharing. The ViewFinder API is updated to take an\nImage pointer in the render() function to prepare for multi-planar\nbuffer support.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n---\n src/qcam/main_window.cpp | 31 ++++++++-----------------------\n src/qcam/main_window.h | 4 ++--\n src/qcam/meson.build | 1 +\n src/qcam/viewfinder.h | 6 +++---\n src/qcam/viewfinder_gl.cpp | 7 ++++---\n src/qcam/viewfinder_gl.h | 2 +-\n src/qcam/viewfinder_qt.cpp | 6 +++---\n src/qcam/viewfinder_qt.h | 2 +-\n 8 files changed, 23 insertions(+), 36 deletions(-)", "diff": "diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\nindex 0a00b1001570..168dd5ce30e3 100644\n--- a/src/qcam/main_window.cpp\n+++ b/src/qcam/main_window.cpp\n@@ -7,10 +7,9 @@\n \n #include \"main_window.h\"\n \n+#include <assert.h>\n #include <iomanip>\n #include <string>\n-#include <sys/mman.h>\n-#include <unistd.h>\n \n #include <QComboBox>\n #include <QCoreApplication>\n@@ -29,6 +28,7 @@\n #include <libcamera/camera_manager.h>\n #include <libcamera/version.h>\n \n+#include \"../cam/image.h\"\n #include \"dng_writer.h\"\n #ifndef QT_NO_OPENGL\n #include \"viewfinder_gl.h\"\n@@ -473,15 +473,10 @@ int MainWindow::startCapture()\n \n \t\tfor (const std::unique_ptr<FrameBuffer> &buffer : allocator_->buffers(stream)) {\n \t\t\t/* Map memory buffers and cache the mappings. */\n-\t\t\tconst FrameBuffer::Plane &plane = buffer->planes().front();\n-\t\t\tsize_t length = lseek(plane.fd.fd(), 0, SEEK_END);\n-\t\t\tvoid *memory = mmap(NULL, length, PROT_READ, MAP_SHARED,\n-\t\t\t\t\t plane.fd.fd(), 0);\n-\n-\t\t\tmappedBuffers_[buffer.get()] = { static_cast<uint8_t *>(memory),\n-\t\t\t\t\t\t\t plane.length };\n-\t\t\tplaneData_[buffer.get()] = { static_cast<uint8_t *>(memory) + plane.offset,\n-\t\t\t\t\t\t plane.length };\n+\t\t\tstd::unique_ptr<Image> image =\n+\t\t\t\tImage::fromFrameBuffer(buffer.get(), Image::MapMode::ReadOnly);\n+\t\t\tassert(image != nullptr);\n+\t\t\tmappedBuffers_[buffer.get()] = std::move(image);\n \n \t\t\t/* Store buffers on the free list. */\n \t\t\tfreeBuffers_[stream].enqueue(buffer.get());\n@@ -543,12 +538,7 @@ error_disconnect:\n error:\n \trequests_.clear();\n \n-\tfor (auto &iter : mappedBuffers_) {\n-\t\tconst Span<uint8_t> &buffer = iter.second;\n-\t\tmunmap(buffer.data(), buffer.size());\n-\t}\n \tmappedBuffers_.clear();\n-\tplaneData_.clear();\n \n \tfreeBuffers_.clear();\n \n@@ -580,12 +570,7 @@ void MainWindow::stopCapture()\n \n \tcamera_->requestCompleted.disconnect(this);\n \n-\tfor (auto &iter : mappedBuffers_) {\n-\t\tconst Span<uint8_t> &buffer = iter.second;\n-\t\tmunmap(buffer.data(), buffer.size());\n-\t}\n \tmappedBuffers_.clear();\n-\tplaneData_.clear();\n \n \trequests_.clear();\n \tfreeQueue_.clear();\n@@ -682,7 +667,7 @@ void MainWindow::processRaw(FrameBuffer *buffer,\n \t\t\t\t\t\t\t\"DNG Files (*.dng)\");\n \n \tif (!filename.isEmpty()) {\n-\t\tuint8_t *memory = planeData_[buffer].data();\n+\t\tuint8_t *memory = mappedBuffers_[buffer]->data(0).data();\n \t\tDNGWriter::write(filename.toStdString().c_str(), camera_.get(),\n \t\t\t\t rawStream_->configuration(), metadata, buffer,\n \t\t\t\t memory);\n@@ -766,7 +751,7 @@ void MainWindow::processViewfinder(FrameBuffer *buffer)\n \t\t<< \"fps:\" << Qt::fixed << qSetRealNumberPrecision(2) << fps;\n \n \t/* Render the frame on the viewfinder. */\n-\tviewfinder_->render(buffer, planeData_[buffer]);\n+\tviewfinder_->render(buffer, mappedBuffers_[buffer].get());\n }\n \n void MainWindow::queueRequest(FrameBuffer *buffer)\ndiff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\nindex 28244bca58b2..a16bea09eadc 100644\n--- a/src/qcam/main_window.h\n+++ b/src/qcam/main_window.h\n@@ -34,6 +34,7 @@ using namespace libcamera;\n class QAction;\n class QComboBox;\n \n+class Image;\n class HotplugEvent;\n \n enum {\n@@ -106,8 +107,7 @@ private:\n \tFrameBufferAllocator *allocator_;\n \n \tstd::unique_ptr<CameraConfiguration> config_;\n-\tstd::map<FrameBuffer *, Span<uint8_t>> mappedBuffers_;\n-\tstd::map<FrameBuffer *, Span<uint8_t>> planeData_;\n+\tstd::map<FrameBuffer *, std::unique_ptr<Image>> mappedBuffers_;\n \n \t/* Capture state, buffers queue and statistics */\n \tbool isCapturing_;\ndiff --git a/src/qcam/meson.build b/src/qcam/meson.build\nindex 7d3621c93d41..c46f463130cd 100644\n--- a/src/qcam/meson.build\n+++ b/src/qcam/meson.build\n@@ -15,6 +15,7 @@ endif\n qcam_enabled = true\n \n qcam_sources = files([\n+ '../cam/image.cpp',\n '../cam/options.cpp',\n '../cam/stream_options.cpp',\n 'format_converter.cpp',\ndiff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h\nindex 42d40f1f33f0..fb462835fb5f 100644\n--- a/src/qcam/viewfinder.h\n+++ b/src/qcam/viewfinder.h\n@@ -11,11 +11,11 @@\n #include <QList>\n #include <QSize>\n \n-#include <libcamera/base/span.h>\n-\n #include <libcamera/formats.h>\n #include <libcamera/framebuffer.h>\n \n+class Image;\n+\n class ViewFinder\n {\n public:\n@@ -24,7 +24,7 @@ public:\n \tvirtual const QList<libcamera::PixelFormat> &nativeFormats() const = 0;\n \n \tvirtual int setFormat(const libcamera::PixelFormat &format, const QSize &size) = 0;\n-\tvirtual void render(libcamera::FrameBuffer *buffer, libcamera::Span<uint8_t> mem) = 0;\n+\tvirtual void render(libcamera::FrameBuffer *buffer, Image *image) = 0;\n \tvirtual void stop() = 0;\n \n \tvirtual QImage getCurrentImage() = 0;\ndiff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp\nindex d2ef036974f4..87e4fe03cb8d 100644\n--- a/src/qcam/viewfinder_gl.cpp\n+++ b/src/qcam/viewfinder_gl.cpp\n@@ -13,6 +13,8 @@\n \n #include <libcamera/formats.h>\n \n+#include \"../cam/image.h\"\n+\n static const QList<libcamera::PixelFormat> supportedFormats{\n \t/* YUV - packed (single plane) */\n \tlibcamera::formats::UYVY,\n@@ -110,8 +112,7 @@ QImage ViewFinderGL::getCurrentImage()\n \treturn grabFramebuffer();\n }\n \n-void ViewFinderGL::render(libcamera::FrameBuffer *buffer,\n-\t\t\t libcamera::Span<uint8_t> mem)\n+void ViewFinderGL::render(libcamera::FrameBuffer *buffer, Image *image)\n {\n \tif (buffer->planes().size() != 1) {\n \t\tqWarning() << \"Multi-planar buffers are not supported\";\n@@ -121,7 +122,7 @@ void ViewFinderGL::render(libcamera::FrameBuffer *buffer,\n \tif (buffer_)\n \t\trenderComplete(buffer_);\n \n-\tdata_ = mem.data();\n+\tdata_ = image->data(0).data();\n \t/*\n \t * \\todo Get the stride from the buffer instead of computing it naively\n \t */\ndiff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h\nindex 3334549e0be4..7cd8ef3316b9 100644\n--- a/src/qcam/viewfinder_gl.h\n+++ b/src/qcam/viewfinder_gl.h\n@@ -39,7 +39,7 @@ public:\n \tconst QList<libcamera::PixelFormat> &nativeFormats() const override;\n \n \tint setFormat(const libcamera::PixelFormat &format, const QSize &size) override;\n-\tvoid render(libcamera::FrameBuffer *buffer, libcamera::Span<uint8_t> mem) override;\n+\tvoid render(libcamera::FrameBuffer *buffer, Image *image) override;\n \tvoid stop() override;\n \n \tQImage getCurrentImage() override;\ndiff --git a/src/qcam/viewfinder_qt.cpp b/src/qcam/viewfinder_qt.cpp\nindex a0bf99b0b522..fef6d53eef5e 100644\n--- a/src/qcam/viewfinder_qt.cpp\n+++ b/src/qcam/viewfinder_qt.cpp\n@@ -19,6 +19,7 @@\n \n #include <libcamera/formats.h>\n \n+#include \"../cam/image.h\"\n #include \"format_converter.h\"\n \n static const QMap<libcamera::PixelFormat, QImage::Format> nativeFormats\n@@ -78,15 +79,14 @@ int ViewFinderQt::setFormat(const libcamera::PixelFormat &format,\n \treturn 0;\n }\n \n-void ViewFinderQt::render(libcamera::FrameBuffer *buffer,\n-\t\t\t libcamera::Span<uint8_t> mem)\n+void ViewFinderQt::render(libcamera::FrameBuffer *buffer, Image *image)\n {\n \tif (buffer->planes().size() != 1) {\n \t\tqWarning() << \"Multi-planar buffers are not supported\";\n \t\treturn;\n \t}\n \n-\tunsigned char *memory = mem.data();\n+\tunsigned char *memory = image->data(0).data();\n \tsize_t size = buffer->metadata().planes()[0].bytesused;\n \n \t{\ndiff --git a/src/qcam/viewfinder_qt.h b/src/qcam/viewfinder_qt.h\nindex 1a569b9cee6e..6b48ef48a7d1 100644\n--- a/src/qcam/viewfinder_qt.h\n+++ b/src/qcam/viewfinder_qt.h\n@@ -32,7 +32,7 @@ public:\n \tconst QList<libcamera::PixelFormat> &nativeFormats() const override;\n \n \tint setFormat(const libcamera::PixelFormat &format, const QSize &size) override;\n-\tvoid render(libcamera::FrameBuffer *buffer, libcamera::Span<uint8_t> mem) override;\n+\tvoid render(libcamera::FrameBuffer *buffer, Image *image) override;\n \tvoid stop() override;\n \n \tQImage getCurrentImage() override;\n", "prefixes": [ "libcamera-devel", "v3", "27/30" ] }