Patch Detail
Show a patch.
GET /api/patches/3197/?format=api
{ "id": 3197, "url": "https://patchwork.libcamera.org/api/patches/3197/?format=api", "web_url": "https://patchwork.libcamera.org/patch/3197/", "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": "<20200319132919.9563-2-laurent.pinchart@ideasonboard.com>", "date": "2020-03-19T13:29:17", "name": "[libcamera-devel,v3,1/3] libcamera: v4l2_videodevice: Add V4L2PixelFormat class", "commit_ref": "a7f24a8d9ab5512abb04b12c1feb6972633961e5", "pull_url": null, "state": "accepted", "archived": false, "hash": "25ed4a2139817f5641e9381a137884e75661f350", "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/3197/mbox/", "series": [ { "id": 741, "url": "https://patchwork.libcamera.org/api/series/741/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=741", "date": "2020-03-19T13:29:16", "name": "Add a V4L2PixelFormat class", "version": 3, "mbox": "https://patchwork.libcamera.org/series/741/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/3197/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/3197/checks/", "tags": {}, "headers": { "Return-Path": "<laurent.pinchart@ideasonboard.com>", "Received": [ "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 59B5560418\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 19 Mar 2020 14:29:32 +0100 (CET)", "from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E92B9DC4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 19 Mar 2020 14:29:31 +0100 (CET)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1584624572;\n\tbh=bUTuSOV5wXoHGNDUOjiPzK8aicUrZSsPVTo7YDe+vlA=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=eP50FjtDmoad7iUiW3tvjG81ZL7NjamfO1ijtqI3J3knSycockxaB+7Eq5Ddqnvwx\n\tax0XTkEUtqHYGom31AJQZwABOtLhpgJN0pybkhf+T4jH/Z6Yw4pFUedCqP6JPq0V8a\n\t4mBdH+cFhj1vtgjvmRBXmxLuIc34d331Z6Q0GyCw=", "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Thu, 19 Mar 2020 15:29:17 +0200", "Message-Id": "<20200319132919.9563-2-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.24.1", "In-Reply-To": "<20200319132919.9563-1-laurent.pinchart@ideasonboard.com>", "References": "<20200319132919.9563-1-laurent.pinchart@ideasonboard.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v3 1/3] libcamera: v4l2_videodevice: Add\n\tV4L2PixelFormat class", "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>", "X-List-Received-Date": "Thu, 19 Mar 2020 13:29:32 -0000" }, "content": "The V4L2PixelFormat class describes the pixel format of a V4L2 buffer.\nIt wraps the V4L2 numerical FourCC, and shall be used in all APIs that\ndeal with V4L2 pixel formats. Its purpose is to prevent unintentional\nconfusion of V4L2 and DRM FourCCs in code by catching implicit\nconversion attempts at compile time.\n\nThe constructor taking a V4L2 FourCC integer value will be made explicit\nin a further commit to minimize the size of this change and keep it\nreviewable.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n---\nChanges since v2:\n\n- Renamed value() to fourcc()\n- Documentation updates\n\nChanges since v1:\n\n- Add and use V4L2PixelFormat::toString()\n---\n src/libcamera/include/v4l2_videodevice.h | 39 +++++++---\n src/libcamera/pipeline/uvcvideo.cpp | 4 +-\n src/libcamera/v4l2_videodevice.cpp | 91 ++++++++++++++++++++----\n 3 files changed, 109 insertions(+), 25 deletions(-)", "diff": "diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h\nindex bc1c6a4d10c7..2a380c0e61cd 100644\n--- a/src/libcamera/include/v4l2_videodevice.h\n+++ b/src/libcamera/include/v4l2_videodevice.h\n@@ -149,10 +149,33 @@ private:\n \tunsigned int missCounter_;\n };\n \n+class V4L2PixelFormat\n+{\n+public:\n+\tV4L2PixelFormat()\n+\t\t: fourcc_(0)\n+\t{\n+\t}\n+\n+\tV4L2PixelFormat(uint32_t fourcc)\n+\t\t: fourcc_(fourcc)\n+\t{\n+\t}\n+\n+\tbool isValid() const { return fourcc_ != 0; }\n+\tuint32_t fourcc() const { return fourcc_; }\n+\toperator uint32_t() const { return fourcc_; }\n+\n+\tstd::string toString() const;\n+\n+private:\n+\tuint32_t fourcc_;\n+};\n+\n class V4L2DeviceFormat\n {\n public:\n-\tuint32_t fourcc;\n+\tV4L2PixelFormat fourcc;\n \tSize size;\n \n \tstruct {\n@@ -184,7 +207,7 @@ public:\n \n \tint getFormat(V4L2DeviceFormat *format);\n \tint setFormat(V4L2DeviceFormat *format);\n-\tImageFormats formats();\n+\tstd::map<V4L2PixelFormat, std::vector<SizeRange>> formats();\n \n \tint setCrop(Rectangle *rect);\n \tint setCompose(Rectangle *rect);\n@@ -205,10 +228,10 @@ public:\n \tstatic V4L2VideoDevice *fromEntityName(const MediaDevice *media,\n \t\t\t\t\t const std::string &entity);\n \n-\tstatic PixelFormat toPixelFormat(uint32_t v4l2Fourcc);\n-\tuint32_t toV4L2Fourcc(const PixelFormat &pixelFormat);\n-\tstatic uint32_t toV4L2Fourcc(const PixelFormat &pixelFormat,\n-\t\t\t\t bool multiplanar);\n+\tstatic PixelFormat toPixelFormat(V4L2PixelFormat v4l2Fourcc);\n+\tV4L2PixelFormat toV4L2Fourcc(const PixelFormat &pixelFormat);\n+\tstatic V4L2PixelFormat toV4L2Fourcc(const PixelFormat &pixelFormat,\n+\t\t\t\t\t bool multiplanar);\n \n protected:\n \tstd::string logPrefix() const;\n@@ -223,8 +246,8 @@ private:\n \tint getFormatSingleplane(V4L2DeviceFormat *format);\n \tint setFormatSingleplane(V4L2DeviceFormat *format);\n \n-\tstd::vector<unsigned int> enumPixelformats();\n-\tstd::vector<SizeRange> enumSizes(unsigned int pixelFormat);\n+\tstd::vector<V4L2PixelFormat> enumPixelformats();\n+\tstd::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);\n \n \tint setSelection(unsigned int target, Rectangle *rect);\n \ndiff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\nindex 731149755728..67750fbc7c0c 100644\n--- a/src/libcamera/pipeline/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo.cpp\n@@ -154,8 +154,8 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,\n \tif (roles.empty())\n \t\treturn config;\n \n-\tstd::map<unsigned int, std::vector<SizeRange>> v4l2Formats =\n-\t\tdata->video_->formats().data();\n+\tstd::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats =\n+\t\tdata->video_->formats();\n \tstd::map<PixelFormat, std::vector<SizeRange>> deviceFormats;\n \tstd::transform(v4l2Formats.begin(), v4l2Formats.end(),\n \t\t std::inserter(deviceFormats, deviceFormats.begin()),\ndiff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp\nindex 56251a465807..1c60014caa6f 100644\n--- a/src/libcamera/v4l2_videodevice.cpp\n+++ b/src/libcamera/v4l2_videodevice.cpp\n@@ -278,6 +278,65 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const\n \treturn true;\n }\n \n+/**\n+ * \\class V4L2PixelFormat\n+ * \\brief V4L2 pixel format FourCC wrapper\n+ *\n+ * The V4L2PixelFormat class describes the pixel format of a V4L2 buffer. It\n+ * wraps the V4L2 numerical FourCC, and shall be used in all APIs that deal with\n+ * V4L2 pixel formats. Its purpose is to prevent unintentional confusion of\n+ * V4L2 and DRM FourCCs in code by catching implicit conversion attempts at\n+ * compile time.\n+ */\n+\n+/**\n+ * \\fn V4L2PixelFormat::V4L2PixelFormat()\n+ * \\brief Construct a V4L2PixelFormat with an invalid format\n+ *\n+ * V4L2PixelFormat instances constructed with the default constructor are\n+ * invalid, calling the isValid() function returns false.\n+ */\n+\n+/**\n+ * \\fn V4L2PixelFormat::V4L2PixelFormat(uint32_t fourcc)\n+ * \\brief Construct a V4L2PixelFormat from a FourCC value\n+ * \\param[in] fourcc The pixel format FourCC numerical value\n+ */\n+\n+/**\n+ * \\fn bool V4L2PixelFormat::isValid() const\n+ * \\brief Check if the pixel format is valid\n+ *\n+ * V4L2PixelFormat instances constructed with the default constructor are\n+ * invalid. Instances constructed with a FourCC defined in the V4L2 API are\n+ * valid. The behaviour is undefined otherwise.\n+ *\n+ * \\return True if the pixel format is valid, false otherwise\n+ */\n+\n+/**\n+ * \\fn uint32_t V4L2PixelFormat::fourcc() const\n+ * \\brief Retrieve the pixel format FourCC numerical value\n+ * \\return The pixel format FourCC numerical value\n+ */\n+\n+/**\n+ * \\fn V4L2PixelFormat::operator uint32_t() const\n+ * \\brief Convert to the pixel format FourCC numerical value\n+ * \\return The pixel format FourCC numerical value\n+ */\n+\n+/**\n+ * \\brief Assemble and return a string describing the pixel format\n+ * \\return A string describing the pixel format\n+ */\n+std::string V4L2PixelFormat::toString() const\n+{\n+\tchar str[11];\n+\tsnprintf(str, 11, \"0x%08x\", fourcc_);\n+\treturn str;\n+}\n+\n /**\n * \\class V4L2DeviceFormat\n * \\brief The V4L2 video device image format and sizes\n@@ -386,7 +445,7 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const\n const std::string V4L2DeviceFormat::toString() const\n {\n \tstd::stringstream ss;\n-\tss << size.toString() << \"-\" << utils::hex(fourcc);\n+\tss << size.toString() << \"-\" << fourcc.toString();\n \treturn ss.str();\n }\n \n@@ -901,29 +960,31 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)\n *\n * \\return A list of the supported video device formats\n */\n-ImageFormats V4L2VideoDevice::formats()\n+std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats()\n {\n-\tImageFormats formats;\n+\tstd::map<V4L2PixelFormat, std::vector<SizeRange>> formats;\n \n-\tfor (unsigned int pixelformat : enumPixelformats()) {\n-\t\tstd::vector<SizeRange> sizes = enumSizes(pixelformat);\n+\tfor (V4L2PixelFormat pixelFormat : enumPixelformats()) {\n+\t\tstd::vector<SizeRange> sizes = enumSizes(pixelFormat);\n \t\tif (sizes.empty())\n \t\t\treturn {};\n \n-\t\tif (formats.addFormat(pixelformat, sizes)) {\n+\t\tif (formats.find(pixelFormat) != formats.end()) {\n \t\t\tLOG(V4L2, Error)\n \t\t\t\t<< \"Could not add sizes for pixel format \"\n-\t\t\t\t<< pixelformat;\n+\t\t\t\t<< pixelFormat;\n \t\t\treturn {};\n \t\t}\n+\n+\t\tformats.emplace(pixelFormat, sizes);\n \t}\n \n \treturn formats;\n }\n \n-std::vector<unsigned int> V4L2VideoDevice::enumPixelformats()\n+std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats()\n {\n-\tstd::vector<unsigned int> formats;\n+\tstd::vector<V4L2PixelFormat> formats;\n \tint ret;\n \n \tfor (unsigned int index = 0; ; index++) {\n@@ -948,7 +1009,7 @@ std::vector<unsigned int> V4L2VideoDevice::enumPixelformats()\n \treturn formats;\n }\n \n-std::vector<SizeRange> V4L2VideoDevice::enumSizes(unsigned int pixelFormat)\n+std::vector<SizeRange> V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat)\n {\n \tstd::vector<SizeRange> sizes;\n \tint ret;\n@@ -1563,7 +1624,7 @@ V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media,\n * \\param[in] v4l2Fourcc The V4L2 pixel format (V4L2_PIX_FORMAT_*)\n * \\return The PixelFormat corresponding to \\a v4l2Fourcc\n */\n-PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)\n+PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc)\n {\n \tswitch (v4l2Fourcc) {\n \t/* RGB formats. */\n@@ -1612,7 +1673,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)\n \t\tlibcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),\n \t\t\t\tLogError).stream()\n \t\t\t<< \"Unsupported V4L2 pixel format \"\n-\t\t\t<< utils::hex(v4l2Fourcc);\n+\t\t\t<< v4l2Fourcc.toString();\n \t\treturn PixelFormat();\n \t}\n }\n@@ -1628,7 +1689,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)\n *\n * \\return The V4L2_PIX_FMT_* pixel format code corresponding to \\a pixelFormat\n */\n-uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)\n+V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)\n {\n \treturn V4L2VideoDevice::toV4L2Fourcc(pixelFormat, caps_.isMultiplanar());\n }\n@@ -1646,8 +1707,8 @@ uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)\n *\n * \\return The V4L2_PIX_FMT_* pixel format code corresponding to \\a pixelFormat\n */\n-uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat,\n-\t\t\t\t bool multiplanar)\n+V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat,\n+\t\t\t\t\t bool multiplanar)\n {\n \tswitch (pixelFormat) {\n \t/* RGB formats. */\n", "prefixes": [ "libcamera-devel", "v3", "1/3" ] }