From patchwork Fri May 17 23:06:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 1225 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8DCF661866 for ; Sat, 18 May 2019 01:06:45 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 323EC336 for ; Sat, 18 May 2019 01:06:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1558134405; bh=/+NingGLt7ZKKaetggvdpsCB4O4Cf1Wr4zBdDH4zi9M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=BzZSmZSSU/1cJpUjZUG/cG9/Lb3s2kOfOvIlvKipG9cjq2DSlIleS7+8Ujnjv9k6+ zqs9pptjiRPUQGq7vHEu3fmF0KKXCLRPS5ds1r2rV3tTSJ7fvbqab55rJQAjDh/78Q BLiLK7h3Tp4fTsKBSQPuptaUq5bCAqQk0mzxB2hY= From: Laurent Pinchart 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 Subject: [libcamera-devel] [PATCH/RFC 08/12] libcamera: stream: Add StreamFormats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 May 2019 23:06:48 -0000 From: Niklas Söderlund Add a StreamFormats which describes all the formats a stream can support. The object does not collect any formation itself but can simplify users interaction with formats as it's able to translate a stream format range into discrete steps. Signed-off-by: Niklas Söderlund --- include/libcamera/stream.h | 30 ++++++ src/libcamera/stream.cpp | 191 +++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index 47c007ed52e2..138ed649ba8c 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_STREAM_H__ #define __LIBCAMERA_STREAM_H__ +#include #include #include @@ -39,6 +40,35 @@ enum StreamRole { Viewfinder, }; +class StreamFormats +{ +public: + struct Range { + Size min; + Size max; + unsigned int stepWidth; + unsigned int stepHeight; + }; + + StreamFormats() {} + + StreamFormats(const std::map &rangeSizes) + : rangeSizes_(rangeSizes) {} + + StreamFormats(const std::map> &discreteSizes) + : discreteSizes_(discreteSizes) {} + + std::vector formats() const; + std::vector sizes(unsigned int pixelformat) const; + + bool isRange() const { return !rangeSizes_.empty(); } + Range range(unsigned int pixelformat) const; + +private: + std::map> discreteSizes_; + std::map rangeSizes_; +}; + using StreamRoles = std::vector; class Stream diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp index 0c59a31a3a05..e82fa8143b8f 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -7,6 +7,7 @@ #include +#include #include #include @@ -122,6 +123,196 @@ std::string StreamConfiguration::toString() const * \brief A vector of StreamRole */ +/** + * \class StreamFormats + * \brief Hold information about supported stream formats + * + * The StreamFormats class holds information about pixel formats and frame + * sizes a stream supports. The class groups size information by the pixel + * format which can produce it. There are two types of size information which + * can be described in the StreamFormats object discrete and range sizes. + * + * The discrete sizes are a list of fixed sizes of the only resolutions the + * stream can produce. While the range description contains a max and min + * size together with a stepping. The range information can either be consumed + * raw which allows users to calculate a size which the stream could support + * or be accessed thru the sizes() helper which will compute a list of common + * discrete sizes which can be produced within the range. + */ + +/** + * \class StreamFormats::Range + * \brief Hold information about stream format range + */ + +/** + * \var StreamFormats::Range::min + * \brief Range minimum size + */ + +/** + * \var StreamFormats::Range::max + * \brief Range maximum size + */ + +/** + * \var StreamFormats::Range::stepWidth + * \brief Range width step length in pixels + */ + +/** + * \var StreamFormats::Range::stepHeight + * \brief Range height step length in pixels + */ + +/** + * \fn StreamFormats::StreamFormats(const std::map< unsigned int, Range > &rangeSizes) + * \brief Constrict a ranged based StreamFormats object + * \param[in] rangeSizes A map of pixel format to a ranged description + * \sa StreamFormats::Range + */ + +/** + * \fn StreamFormats::StreamFormats(const std::map< unsigned int, std::vector< Size >> &discreteSizes) + * \brief Constrict a discrete based StreamFormats object + * \param[in] discreteSizes A map of pixel format to a list of frame sizes + */ + +/** + * \brief Retrive a list of pixel formats supported by the stram + * \returns A list of pixel formats + */ +std::vector StreamFormats::formats() const +{ + std::vector formats; + + if (isRange()) { + for (auto const &it : rangeSizes_) + formats.push_back(it.first); + } else { + for (auto const &it : discreteSizes_) + formats.push_back(it.first); + } + + return formats; +} + +/** + * \brief Retrive a list of frame sizes + * \param[in] pixelformat Pixel format to retrive sizes for + * \returns A list of frame sizes + */ +std::vector StreamFormats::sizes(unsigned int pixelformat) const +{ + std::vector sizes; + + /* + * Sizes to try and extract from ranges. + * \todo Verify list of resolutions are good + */ + static const std::vector rangeDescreteSizes = { + Size(160, 120), + Size(240, 160), + Size(320, 240), + Size(400, 240), + Size(480, 320), + Size(640, 360), + Size(640, 480), + Size(720, 480), + Size(720, 576), + Size(768, 480), + Size(800, 600), + Size(854, 480), + Size(960, 540), + Size(960, 640), + Size(1024, 576), + Size(1024, 600), + Size(1024, 768), + Size(1152, 864), + Size(1280, 1024), + Size(1280, 1080), + Size(1280, 720), + Size(1280, 800), + Size(1360, 768), + Size(1366, 768), + Size(1400, 1050), + Size(1440, 900), + Size(1536, 864), + Size(1600, 1200), + Size(1600, 900), + Size(1680, 1050), + Size(1920, 1080), + Size(1920, 1200), + Size(2048, 1080), + Size(2048, 1152), + Size(2048, 1536), + Size(2160, 1080), + Size(2560, 1080), + Size(2560, 1440), + Size(2560, 1600), + Size(2560, 2048), + Size(2960, 1440), + Size(3200, 1800), + Size(3200, 2048), + Size(3200, 2400), + Size(3440, 1440), + Size(3840, 1080), + Size(3840, 1600), + Size(3840, 2160), + Size(3840, 2400), + Size(4096, 2160), + Size(5120, 2160), + Size(5120, 2880), + Size(7680, 4320), + }; + + if (!isRange()) { + auto const &it = discreteSizes_.find(pixelformat); + if (it == discreteSizes_.end()) + return {}; + sizes = it->second; + } else { + Range limit = range(pixelformat); + + for (const Size &size : rangeDescreteSizes) { + if (size.width < limit.min.width || + size.width > limit.max.width || + size.height < limit.min.height || + size.height > limit.max.height || + size.width % limit.stepWidth || + size.height % limit.stepHeight) + continue; + + sizes.push_back(size); + } + } + + std::sort(sizes.begin(), sizes.end()); + + return sizes; +} + +/** + * \fn StreamFormats::isRange() + * \brief Check if the StreamFormat is a range description + * \returns True if the description is a range, false otherwise + */ + +/** + * \brief Retrive the range description + * \param[in] pixelformat Pixel format to retrive description for + * \returns The range description + */ +StreamFormats::Range StreamFormats::range(unsigned int pixelformat) const +{ + auto const it = rangeSizes_.find(pixelformat); + + if (it == rangeSizes_.end()) + return {}; + + return it->second; +} + /** * \class Stream * \brief Video stream for a camera