Patch Detail
Show a patch.
GET /api/patches/1225/?format=api
{ "id": 1225, "url": "https://patchwork.libcamera.org/api/patches/1225/?format=api", "web_url": "https://patchwork.libcamera.org/patch/1225/", "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": "<20190517230621.24668-9-laurent.pinchart@ideasonboard.com>", "date": "2019-05-17T23:06:17", "name": "[libcamera-devel,PATCH/RFC,08/12] libcamera: stream: Add StreamFormats", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "e561ae0bdf4cc75cf59cf5622566a84ece8eb741", "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/1225/mbox/", "series": [ { "id": 307, "url": "https://patchwork.libcamera.org/api/series/307/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=307", "date": "2019-05-17T23:06:09", "name": "Rework camera configuration to introduce negotiation of parameters", "version": 1, "mbox": "https://patchwork.libcamera.org/series/307/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/1225/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/1225/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 8DCF661866\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 18 May 2019 01:06:45 +0200 (CEST)", "from pendragon.bb.dnainternet.fi\n\t(dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 323EC336\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 18 May 2019 01:06:45 +0200 (CEST)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1558134405;\n\tbh=/+NingGLt7ZKKaetggvdpsCB4O4Cf1Wr4zBdDH4zi9M=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=BzZSmZSSU/1cJpUjZUG/cG9/Lb3s2kOfOvIlvKipG9cjq2DSlIleS7+8Ujnjv9k6+\n\tzqs9pptjiRPUQGq7vHEu3fmF0KKXCLRPS5ds1r2rV3tTSJ7fvbqab55rJQAjDh/78Q\n\tBLiLK7h3Tp4fTsKBSQPuptaUq5bCAqQk0mzxB2hY=", "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Sat, 18 May 2019 02:06:17 +0300", "Message-Id": "<20190517230621.24668-9-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.21.0", "In-Reply-To": "<20190517230621.24668-1-laurent.pinchart@ideasonboard.com>", "References": "<20190517230621.24668-1-laurent.pinchart@ideasonboard.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH/RFC 08/12] libcamera: stream: Add\n\tStreamFormats", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.23", "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": "Fri, 17 May 2019 23:06:48 -0000" }, "content": "From: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\nAdd a StreamFormats which describes all the formats a stream can\nsupport. The object does not collect any formation itself but can\nsimplify users interaction with formats as it's able to translate a\nstream format range into discrete steps.\n\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n---\n include/libcamera/stream.h | 30 ++++++\n src/libcamera/stream.cpp | 191 +++++++++++++++++++++++++++++++++++++\n 2 files changed, 221 insertions(+)", "diff": "diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h\nindex 47c007ed52e2..138ed649ba8c 100644\n--- a/include/libcamera/stream.h\n+++ b/include/libcamera/stream.h\n@@ -7,6 +7,7 @@\n #ifndef __LIBCAMERA_STREAM_H__\n #define __LIBCAMERA_STREAM_H__\n \n+#include <map>\n #include <string>\n #include <vector>\n \n@@ -39,6 +40,35 @@ enum StreamRole {\n \tViewfinder,\n };\n \n+class StreamFormats\n+{\n+public:\n+\tstruct Range {\n+\t\tSize min;\n+\t\tSize max;\n+\t\tunsigned int stepWidth;\n+\t\tunsigned int stepHeight;\n+\t};\n+\n+\tStreamFormats() {}\n+\n+\tStreamFormats(const std::map<unsigned int, Range> &rangeSizes)\n+\t\t: rangeSizes_(rangeSizes) {}\n+\n+\tStreamFormats(const std::map<unsigned int, std::vector<Size>> &discreteSizes)\n+\t\t: discreteSizes_(discreteSizes) {}\n+\n+\tstd::vector<unsigned int> formats() const;\n+\tstd::vector<Size> sizes(unsigned int pixelformat) const;\n+\n+\tbool isRange() const { return !rangeSizes_.empty(); }\n+\tRange range(unsigned int pixelformat) const;\n+\n+private:\n+\tstd::map<unsigned int, std::vector<Size>> discreteSizes_;\n+\tstd::map<unsigned int, Range> rangeSizes_;\n+};\n+\n using StreamRoles = std::vector<StreamRole>;\n \n class Stream\ndiff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp\nindex 0c59a31a3a05..e82fa8143b8f 100644\n--- a/src/libcamera/stream.cpp\n+++ b/src/libcamera/stream.cpp\n@@ -7,6 +7,7 @@\n \n #include <libcamera/stream.h>\n \n+#include <algorithm>\n #include <iomanip>\n #include <sstream>\n \n@@ -122,6 +123,196 @@ std::string StreamConfiguration::toString() const\n * \\brief A vector of StreamRole\n */\n \n+/**\n+ * \\class StreamFormats\n+ * \\brief Hold information about supported stream formats\n+ *\n+ * The StreamFormats class holds information about pixel formats and frame\n+ * sizes a stream supports. The class groups size information by the pixel\n+ * format which can produce it. There are two types of size information which\n+ * can be described in the StreamFormats object discrete and range sizes.\n+ *\n+ * The discrete sizes are a list of fixed sizes of the only resolutions the\n+ * stream can produce. While the range description contains a max and min\n+ * size together with a stepping. The range information can either be consumed\n+ * raw which allows users to calculate a size which the stream could support\n+ * or be accessed thru the sizes() helper which will compute a list of common\n+ * discrete sizes which can be produced within the range.\n+ */\n+\n+/**\n+ * \\class StreamFormats::Range\n+ * \\brief Hold information about stream format range\n+ */\n+\n+/**\n+ * \\var StreamFormats::Range::min\n+ * \\brief Range minimum size\n+ */\n+\n+/**\n+ * \\var StreamFormats::Range::max\n+ * \\brief Range maximum size\n+ */\n+\n+/**\n+ * \\var StreamFormats::Range::stepWidth\n+ * \\brief Range width step length in pixels\n+ */\n+\n+/**\n+ * \\var StreamFormats::Range::stepHeight\n+ * \\brief Range height step length in pixels\n+ */\n+\n+/**\n+ * \\fn StreamFormats::StreamFormats(const std::map< unsigned int, Range > &rangeSizes)\n+ * \\brief Constrict a ranged based StreamFormats object\n+ * \\param[in] rangeSizes A map of pixel format to a ranged description\n+ * \\sa StreamFormats::Range\n+ */\n+\n+/**\n+ * \\fn StreamFormats::StreamFormats(const std::map< unsigned int, std::vector< Size >> &discreteSizes)\n+ * \\brief Constrict a discrete based StreamFormats object\n+ * \\param[in] discreteSizes A map of pixel format to a list of frame sizes\n+ */\n+\n+/**\n+ * \\brief Retrive a list of pixel formats supported by the stram\n+ * \\returns A list of pixel formats\n+ */\n+std::vector<unsigned int> StreamFormats::formats() const\n+{\n+\tstd::vector<unsigned int> formats;\n+\n+\tif (isRange()) {\n+\t\tfor (auto const &it : rangeSizes_)\n+\t\t\tformats.push_back(it.first);\n+\t} else {\n+\t\tfor (auto const &it : discreteSizes_)\n+\t\t\tformats.push_back(it.first);\n+\t}\n+\n+\treturn formats;\n+}\n+\n+/**\n+ * \\brief Retrive a list of frame sizes\n+ * \\param[in] pixelformat Pixel format to retrive sizes for\n+ * \\returns A list of frame sizes\n+ */\n+std::vector<Size> StreamFormats::sizes(unsigned int pixelformat) const\n+{\n+\tstd::vector<Size> sizes;\n+\n+\t/*\n+\t * Sizes to try and extract from ranges.\n+\t * \\todo Verify list of resolutions are good\n+\t */\n+\tstatic const std::vector<Size> rangeDescreteSizes = {\n+\t\tSize(160, 120),\n+\t\tSize(240, 160),\n+\t\tSize(320, 240),\n+\t\tSize(400, 240),\n+\t\tSize(480, 320),\n+\t\tSize(640, 360),\n+\t\tSize(640, 480),\n+\t\tSize(720, 480),\n+\t\tSize(720, 576),\n+\t\tSize(768, 480),\n+\t\tSize(800, 600),\n+\t\tSize(854, 480),\n+\t\tSize(960, 540),\n+\t\tSize(960, 640),\n+\t\tSize(1024, 576),\n+\t\tSize(1024, 600),\n+\t\tSize(1024, 768),\n+\t\tSize(1152, 864),\n+\t\tSize(1280, 1024),\n+\t\tSize(1280, 1080),\n+\t\tSize(1280, 720),\n+\t\tSize(1280, 800),\n+\t\tSize(1360, 768),\n+\t\tSize(1366, 768),\n+\t\tSize(1400, 1050),\n+\t\tSize(1440, 900),\n+\t\tSize(1536, 864),\n+\t\tSize(1600, 1200),\n+\t\tSize(1600, 900),\n+\t\tSize(1680, 1050),\n+\t\tSize(1920, 1080),\n+\t\tSize(1920, 1200),\n+\t\tSize(2048, 1080),\n+\t\tSize(2048, 1152),\n+\t\tSize(2048, 1536),\n+\t\tSize(2160, 1080),\n+\t\tSize(2560, 1080),\n+\t\tSize(2560, 1440),\n+\t\tSize(2560, 1600),\n+\t\tSize(2560, 2048),\n+\t\tSize(2960, 1440),\n+\t\tSize(3200, 1800),\n+\t\tSize(3200, 2048),\n+\t\tSize(3200, 2400),\n+\t\tSize(3440, 1440),\n+\t\tSize(3840, 1080),\n+\t\tSize(3840, 1600),\n+\t\tSize(3840, 2160),\n+\t\tSize(3840, 2400),\n+\t\tSize(4096, 2160),\n+\t\tSize(5120, 2160),\n+\t\tSize(5120, 2880),\n+\t\tSize(7680, 4320),\n+\t};\n+\n+\tif (!isRange()) {\n+\t\tauto const &it = discreteSizes_.find(pixelformat);\n+\t\tif (it == discreteSizes_.end())\n+\t\t\treturn {};\n+\t\tsizes = it->second;\n+\t} else {\n+\t\tRange limit = range(pixelformat);\n+\n+\t\tfor (const Size &size : rangeDescreteSizes) {\n+\t\t\tif (size.width < limit.min.width ||\n+\t\t\t size.width > limit.max.width ||\n+\t\t\t size.height < limit.min.height ||\n+\t\t\t size.height > limit.max.height ||\n+\t\t\t size.width % limit.stepWidth ||\n+\t\t\t size.height % limit.stepHeight)\n+\t\t\t\tcontinue;\n+\n+\t\t\tsizes.push_back(size);\n+\t\t}\n+\t}\n+\n+\tstd::sort(sizes.begin(), sizes.end());\n+\n+\treturn sizes;\n+}\n+\n+/**\n+ * \\fn StreamFormats::isRange()\n+ * \\brief Check if the StreamFormat is a range description\n+ * \\returns True if the description is a range, false otherwise\n+ */\n+\n+/**\n+ * \\brief Retrive the range description\n+ * \\param[in] pixelformat Pixel format to retrive description for\n+ * \\returns The range description\n+ */\n+StreamFormats::Range StreamFormats::range(unsigned int pixelformat) const\n+{\n+\tauto const it = rangeSizes_.find(pixelformat);\n+\n+\tif (it == rangeSizes_.end())\n+\t\treturn {};\n+\n+\treturn it->second;\n+}\n+\n /**\n * \\class Stream\n * \\brief Video stream for a camera\n", "prefixes": [ "libcamera-devel", "PATCH/RFC", "08/12" ] }