{"id":17569,"url":"https://patchwork.libcamera.org/api/patches/17569/?format=json","web_url":"https://patchwork.libcamera.org/patch/17569/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20221010131744.513261-3-xavier.roumegue@oss.nxp.com>","date":"2022-10-10T13:17:44","name":"[libcamera-devel,2/2] libcamera: pipeline: simple: converter: Use generic converter interface","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"8ce1133d5599a64457578584315de6904650ff94","submitter":{"id":107,"url":"https://patchwork.libcamera.org/api/people/107/?format=json","name":"Xavier Roumegue","email":"xavier.roumegue@oss.nxp.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/17569/mbox/","series":[{"id":3547,"url":"https://patchwork.libcamera.org/api/series/3547/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=3547","date":"2022-10-10T13:17:42","name":"Use a generic converter interface in simple pipeline.","version":1,"mbox":"https://patchwork.libcamera.org/series/3547/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/17569/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/17569/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 14368C0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 10 Oct 2022 13:18:20 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B7ABF62D68;\n\tMon, 10 Oct 2022 15:18:19 +0200 (CEST)","from EUR05-VI1-obe.outbound.protection.outlook.com\n\t(mail-vi1eur05on2058.outbound.protection.outlook.com [40.107.21.58])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D69D362D5D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 10 Oct 2022 15:18:17 +0200 (CEST)","from PAXPR04MB8703.eurprd04.prod.outlook.com\n\t(2603:10a6:102:21e::22)\n\tby PA4PR04MB7933.eurprd04.prod.outlook.com (2603:10a6:102:b9::13)\n\twith Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5676.34;\n\tMon, 10 Oct 2022 13:18:16 +0000","from PAXPR04MB8703.eurprd04.prod.outlook.com\n\t([fe80::4f72:a35a:8c60:63f1]) by\n\tPAXPR04MB8703.eurprd04.prod.outlook.com\n\t([fe80::4f72:a35a:8c60:63f1%6]) with mapi id 15.20.5709.015;\n\tMon, 10 Oct 2022 13:18:15 +0000"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1665407899;\n\tbh=xoUHWiByL5iR0r4lJHtd8J8dPJVxQbNtI/Jche+j+PI=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=yL7dfSnIlXfBwkOGv2KJfgjDJ2BIxVWh4MXvboDrkKRwQRAHX1NLm4UVEtwD4ZtPr\n\tfIHx2pZRY7L01cC2j8KFrOdBrU2gooNICcOUQYVYJ2nLZYWByXlILLOpeVkmJwHPRV\n\tcGP7FXCF7S4r+08NBUaPKd8K4cpxVI/ySgfdFaHOnpF4cpE6dEOOVO0LeDjVxSju1p\n\t17FDCK1CFSSvcbZXxb2jGeKK/aLCV3Eq4IHl3fQIAEAWivnrTEZo/sa5qN2DA/yol6\n\tVZ8EsSpQJ2rW4se1dNBFpEWFBMg/iVWINpWCAIp6ohvEe83ypOrDsimq8rnO9RaqE4\n\tE/8vgeWA+78vw==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com;\n\ts=selector2-NXP1-onmicrosoft-com;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=HLrehMPuVvkFpk5mpBrx88HpMG3uRy31HqjWXXv+Ajg=;\n\tb=lhTaymqe8wrvZw7FQBdxGPqOvPsy/55/lnnQsSzrn2xYpfRt+DuXHcHegkZjBt1oqTI+Kl8DGhc0hHdgRGYIsvDAVMjBg8iPENdasqqRl2fyMKhG4fBfYAkmNAsjvwJFTdPvJj61wqQtoEwdvZJy09SYMR3BTdQPsHAkSroCK8Y="],"Authentication-Results":["lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=NXP1.onmicrosoft.com\n\theader.i=@NXP1.onmicrosoft.com\n\theader.b=\"lhTaymqe\"; dkim-atps=neutral","dkim=none (message not signed)\n\theader.d=none;dmarc=none action=none header.from=oss.nxp.com;"],"ARC-Seal":"i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n\tb=lah+2ZnwM91XMKChrdhmGppRjPyvXwxX66c1FLNvX+5pjlkDE3CW3TlYMzIR1w/mXq38Fdo5kaeP7HPp68tsNzc9DCNAhL1IdclbXtLEtJimiD7IlmpBDveGR7xc6CSjMVAny6PU15y5GF6nBSHP0nTBJ2wY77UgfA0EnwdQMGP/Hhtc2IedjhTMODvpN3AfHwY1Oco5SHxacDUbpMRX9nEb4Q10J1SIS397CEKdlmxaq76XFddrWVt3fup/tr+UfBfGNfq3CHoM0rE83gnH0l7a8owNErqRsS1EwMa9bCsBlLlQgr4OCsTnZsX/CtBbEg75V9v6QM/2pDYxFpILiw==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n\ts=arcselector9901;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n\tbh=HLrehMPuVvkFpk5mpBrx88HpMG3uRy31HqjWXXv+Ajg=;\n\tb=EkauyfngAEPuXrxg6Ep6A4BT3luJqj8IE4I3Qy3QC3YiaorJs5yjX/w8tlTXefGTTPrx2Y9XVI71lmy+mj3mX85xqj+wOkJiUzlpG+9pSSM2e7/2k+FuTBK9MbM+ytyM5HTBX2c8K/BwgTKDY8AJ1hDT4Vyc+vcLFtztk/EOgzunjT1zkqsnLA/1c2qxn6lHSx/c10Ue+/ejG3n2rnAZU2v5gr0lOlEwdAvdNC6jOon+lkl4xRyn0PmwHyzlxcQ2xR5JrrmxNBib2XoOp9Mx73WfHWX68HsmnPT5jPJe/Ti6vcCMOwg5NX3Xnz+5tnYwOShe+uKjzUnpyV0qn1swmw==","ARC-Authentication-Results":"i=1; mx.microsoft.com 1; spf=pass\n\tsmtp.mailfrom=oss.nxp.com;\n\tdmarc=pass action=none header.from=oss.nxp.com; \n\tdkim=pass header.d=oss.nxp.com; arc=none","To":"jacopo@jmondi.org, laurent.pinchart@ideasonboard.com,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 10 Oct 2022 15:17:44 +0200","Message-Id":"<20221010131744.513261-3-xavier.roumegue@oss.nxp.com>","X-Mailer":"git-send-email 2.37.3","In-Reply-To":"<20221010131744.513261-1-xavier.roumegue@oss.nxp.com>","References":"<20221010131744.513261-1-xavier.roumegue@oss.nxp.com>","Content-Transfer-Encoding":"8bit","Content-Type":"text/plain","X-ClientProxiedBy":"BY5PR17CA0058.namprd17.prod.outlook.com\n\t(2603:10b6:a03:167::35) To PAXPR04MB8703.eurprd04.prod.outlook.com\n\t(2603:10a6:102:21e::22)","MIME-Version":"1.0","X-MS-Exchange-MessageSentRepresentingType":"1","X-MS-PublicTrafficType":"Email","X-MS-TrafficTypeDiagnostic":"PAXPR04MB8703:EE_|PA4PR04MB7933:EE_","X-MS-Office365-Filtering-Correlation-Id":"6979081e-4abe-4dc1-58a1-08daaac1e3d8","X-MS-Exchange-SharedMailbox-RoutingAgent-Processed":"True","X-MS-Exchange-SenderADCheck":"1","X-MS-Exchange-AntiSpam-Relay":"0","X-Microsoft-Antispam":"BCL:0;","X-Microsoft-Antispam-Message-Info":"OEj1nURJQ1ciwoJj2buk0B8BH+JzQ1ynPSrHOdZFlqCfYKz8jvx0fOiqzzAXQY5z4mFyB0duLroRpqbh6mSS3KHHeb9OiFcPwZbL2hm/Nslx2MlEtkE6y8mFuolRm8kcSVZJ9dLteFGaMGsSeXfRWzcLpxpWrql1q4A1B9QQ6jM0uCzC7Vb+U0U2ZCHlT/GcJCtyPx/OG0c0MRWaRx1/KuE1CWbQiRxxjyAVGFH6zLejA3VB1pJiO1VNzS56mBRln47Gt1VO5P9tJL5eGgGtkusx7kY8iIdB7JpMEk34NSciOIIcd6OdE9V1sHNOplhUzGrHHMy61aYa4fP5ieCt2kLVm7Z3R848i603FbeSjZ36x6s/4rIsVf+aQTkFCoNxpoYHKWDHGJV/rNJ6NYv5oT2NdszMlKuJTMEm6mvqiActK8I4z7lenKhMiLEbrIv/460zGPhxTjzS1RucmxRPck3FlnEZYH2EaiFmYTXIjTJmv5r2Vle5n9OpNTALdR3ZFzWYwE3RSkedN1s9XJgQSIef7dru1pRhVWigDVH9BywsVVsslL4T7Q2NscUycb17/EvgfrIZiOYGGAbSGwZTxQg86H/V3j1Ln3bQ28/WaOG0+cKOO59A4zY7h0UeeTAqvnnWj/RY2i642sz975dayHwFSo6P7m3qPyuQ9UW8qNZAmwlH+yx1bxy1eF9A9AoCd+vc7JLbC5ju/qIO4S4JuP2aKef4f9w+6RSsC98uXhShzVQf655x6PKtkoSLG9OjLMtKhrtMlNeqPom4oeR4W2FWM+Io8RdhCovopmDf3yc=","X-Forefront-Antispam-Report":"CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n\tIPV:NLI; SFV:NSPM; H:PAXPR04MB8703.eurprd04.prod.outlook.com; PTR:;\n\tCAT:NONE; \n\tSFS:(13230022)(4636009)(376002)(396003)(366004)(136003)(39860400002)(346002)(451199015)(55236004)(66476007)(8676002)(5660300002)(66556008)(4326008)(66946007)(316002)(38350700002)(38100700002)(41300700001)(8936002)(30864003)(2906002)(6486002)(478600001)(6666004)(1076003)(186003)(6512007)(26005)(52116002)(83380400001)(6506007)(86362001)(2616005)(41533002);\n\tDIR:OUT; SFP:1101; ","X-MS-Exchange-AntiSpam-MessageData-ChunkCount":"1","X-MS-Exchange-AntiSpam-MessageData-0":"MvLI3/sYN0JtKUZ3k9SOmQrMoRJKMXZNe/vaZviTCsTpLWBDsbRhaByzA7fSpomsP/MiYm6rGL21ZJ6KLtjCZEpwZluOJnOCd/44vnXqEjVia8IXrNAlbY8KoCpzQ5IGX2S+stgAYrrTwT0FYsFzLYgHuH6Z0vhGDTxEq098eHeWLH542R+5M5vaYNpdnqFyVjbEuk3cnZ0D0Vfj8EenvQelH1EYow/eAneYexJrFsyTy2baM2LD/tzqBkOQKxrQClLXhGtTESPak9Gi46eVmReYESIiQqXH8s9VtUHIa141wHwzjeFQCPhDDL2bjGrEwNKEDJLqXGTEHX20Uba8BwCSZr3iaPj6raMZ/LJ//nt98+IUJbYL6SRfZIwnETEvqzrCDn2mG0JGlnsAOMgCAbGQAhR67LXrh6l7ryPy520TX4UqUNLlTpHN0AJ9vIdJxpe0VgfPxPNulrJWJ/xtflZ6RN+uvyOcu7BQgVz+tdb7TrGLqWKsshUXwU2Euv0bIFtWb16QSStqdILUG2eBm37GWmKJ6U8me3/17gcrAcQ/ACqKonAwlL6GMFhY+kZG+T+/2k+CbeLIYZPN/DrYLtdb/IlrkR7pkQM+K9zWxg8TgAAQRAHhoEWrIE0hUxqHDz1Gls736hOv23j3mVHsXbuQR3gIV2MmAQbwTn4RxbXGH6w+grYKNBYsPsqQLV3xIujEnHU0gcrwKoNg14OiFTXMyz9xzjO4vEqkJxlMBQ3/iRvbjP6dyUM7VNY7RZxSNYtDTneRyRK7+vlhP2NMr9RuBlVxHHAF+foQzSBt0V0SjT6Pn2zdUYyxHSgxLd7cNVvPVMhUQKBzNXZFoh9i1h7GnPamYskDoZTBNSpG/E87S76dHZ3Af8sJ84e8+PUsl2+6/lkG/kuS0DILDjH546irQH+WQB1fxI1h2ah3epJOP/OLsqhQjye0dELcu8M4ERqnxiZ/Y/dFH5jz8OjzyutfA0+wCJXUj+K6ag2u90CO+bcLA5q7LdMFDx2I/7zwO1B9MxTgF0OJkD/3KA7S8nUKlM5Th4M1gzUyP3hGgRHN9Fz8a9QveWA2XpV4kDaZa8EyTN4zgSYu3AvzKnbwtly/h941uRaXWTJabbR6V6P5zz9tn6iWz+b8MMfLJbCxMp+CxJ4FeY3anDesOsAwfFfRcuWp+qB9WNVG/dRgaDp7xJC84jo0UBVN+Re7Y7il9C2ygrEbVAVBeLg/UGx5J78AlnvEXXTZDfGNc4QERyFM71stpejPwSgxlKvNS3bvCzSP7QhOaoxndkpia+uEEtvlBZA7+LO6oG0iB3/80MHk8fnu43Ip4bYPxxrg5f68VaX05HgG+4BRbxAPcK/4YsdR0OWU54Eej1z2S+HfrJFvzP9MV8vMuc0M+lOuhxFRpw6KAVfiXRrzQVaYHguwY+QoztW8fdYCt282+NTVBINfcu+QpBuzcnBhXN0YRiHzKcgO3LcDEQAUTXTN8ITHrZot2zPCq2s4s8vzgRkTPnvjHLhKUlIdJ2ZjKlEA+Sw8l9aps5Cs0CftMS0GG4g1lmzIb/fh/26AInuItnBETf4escpbDMaWv4oEPoNfQydUER+PbuDUtogdxVZExJCGQA==","X-OriginatorOrg":"oss.nxp.com","X-MS-Exchange-CrossTenant-Network-Message-Id":"6979081e-4abe-4dc1-58a1-08daaac1e3d8","X-MS-Exchange-CrossTenant-AuthSource":"PAXPR04MB8703.eurprd04.prod.outlook.com","X-MS-Exchange-CrossTenant-AuthAs":"Internal","X-MS-Exchange-CrossTenant-OriginalArrivalTime":"10 Oct 2022 13:18:15.9064\n\t(UTC)","X-MS-Exchange-CrossTenant-FromEntityHeader":"Hosted","X-MS-Exchange-CrossTenant-Id":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635","X-MS-Exchange-CrossTenant-MailboxType":"HOSTED","X-MS-Exchange-CrossTenant-UserPrincipalName":"nvGnXfBdWkNGg3YT2NnI/Yhc2jAsQIwRskleHvlxR8mkLWf5e6rSOok39zYG772KBYbTqGeLJs/ee6xePfZ8ug==","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"PA4PR04MB7933","Subject":"[libcamera-devel] [PATCH 2/2] libcamera: pipeline: simple:\n\tconverter: Use generic converter interface","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>","From":"\"Xavier Roumegue \\(OSS\\) via libcamera-devel\"\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"\"Xavier Roumegue \\(OSS\\)\" <xavier.roumegue@oss.nxp.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"From: Xavier Roumegue <xavier.roumegue@oss.nxp.com>\n\nMove the simple converter implementation to a generic V4L2 M2M class\nderived from the converter interface. This latter could be used by\nother pipeline implementations and as base class for customized V4L2 M2M\nconverters.\n\nSigned-off-by: Xavier Roumegue <xavier.roumegue@oss.nxp.com>\n---\n .../internal/converter/converter_v4l2_m2m.h   |  18 +--\n .../libcamera/internal/converter/meson.build  |   5 +\n include/libcamera/internal/meson.build        |   2 +\n .../converter_v4l2_m2m.cpp}                   | 149 +++++++++++-------\n src/libcamera/converter/meson.build           |   5 +\n src/libcamera/meson.build                     |   1 +\n src/libcamera/pipeline/simple/meson.build     |   1 -\n src/libcamera/pipeline/simple/simple.cpp      |   6 +-\n 8 files changed, 119 insertions(+), 68 deletions(-)\n rename src/libcamera/pipeline/simple/converter.h => include/libcamera/internal/converter/converter_v4l2_m2m.h (83%)\n create mode 100644 include/libcamera/internal/converter/meson.build\n rename src/libcamera/{pipeline/simple/converter.cpp => converter/converter_v4l2_m2m.cpp} (69%)\n create mode 100644 src/libcamera/converter/meson.build","diff":"diff --git a/src/libcamera/pipeline/simple/converter.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h\nsimilarity index 83%\nrename from src/libcamera/pipeline/simple/converter.h\nrename to include/libcamera/internal/converter/converter_v4l2_m2m.h\nindex f0ebe2e0..ef31eeba 100644\n--- a/src/libcamera/pipeline/simple/converter.h\n+++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h\n@@ -1,8 +1,9 @@\n /* SPDX-License-Identifier: LGPL-2.1-or-later */\n /*\n  * Copyright (C) 2020, Laurent Pinchart\n+ * Copyright 2022 NXP\n  *\n- * converter.h - Format converter for simple pipeline handler\n+ * converter_v4l2_m2m.h - V4l2 M2M Format converter interface\n  */\n \n #pragma once\n@@ -19,6 +20,8 @@\n #include <libcamera/base/log.h>\n #include <libcamera/base/signal.h>\n \n+#include \"libcamera/internal/converter.h\"\n+\n namespace libcamera {\n \n class FrameBuffer;\n@@ -28,11 +31,12 @@ class SizeRange;\n struct StreamConfiguration;\n class V4L2M2MDevice;\n \n-class SimpleConverter\n+class V4L2M2MConverter : public Converter\n {\n public:\n-\tSimpleConverter(MediaDevice *media);\n+\tV4L2M2MConverter(MediaDevice *media);\n \n+\tint loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; }\n \tbool isValid() const { return m2m_ != nullptr; }\n \n \tstd::vector<PixelFormat> formats(PixelFormat input);\n@@ -52,14 +56,11 @@ public:\n \tint queueBuffers(FrameBuffer *input,\n \t\t\t const std::map<unsigned int, FrameBuffer *> &outputs);\n \n-\tSignal<FrameBuffer *> inputBufferReady;\n-\tSignal<FrameBuffer *> outputBufferReady;\n-\n private:\n \tclass Stream : protected Loggable\n \t{\n \tpublic:\n-\t\tStream(SimpleConverter *converter, unsigned int index);\n+\t\tStream(V4L2M2MConverter *converter, unsigned int index);\n \n \t\tbool isValid() const { return m2m_ != nullptr; }\n \n@@ -80,7 +81,7 @@ private:\n \t\tvoid captureBufferReady(FrameBuffer *buffer);\n \t\tvoid outputBufferReady(FrameBuffer *buffer);\n \n-\t\tSimpleConverter *converter_;\n+\t\tV4L2M2MConverter *converter_;\n \t\tunsigned int index_;\n \t\tstd::unique_ptr<V4L2M2MDevice> m2m_;\n \n@@ -88,7 +89,6 @@ private:\n \t\tunsigned int outputBufferCount_;\n \t};\n \n-\tstd::string deviceNode_;\n \tstd::unique_ptr<V4L2M2MDevice> m2m_;\n \n \tstd::vector<Stream> streams_;\ndiff --git a/include/libcamera/internal/converter/meson.build b/include/libcamera/internal/converter/meson.build\nnew file mode 100644\nindex 00000000..891e79e7\n--- /dev/null\n+++ b/include/libcamera/internal/converter/meson.build\n@@ -0,0 +1,5 @@\n+# SPDX-License-Identifier: CC0-1.0\n+\n+libcamera_internal_headers += files([\n+    'converter_v4l2_m2m.h',\n+])\ndiff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build\nindex 8f50d755..b9db5a8c 100644\n--- a/include/libcamera/internal/meson.build\n+++ b/include/libcamera/internal/meson.build\n@@ -45,3 +45,5 @@ libcamera_internal_headers = files([\n     'v4l2_videodevice.h',\n     'yaml_parser.h',\n ])\n+\n+subdir('converter')\ndiff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp\nsimilarity index 69%\nrename from src/libcamera/pipeline/simple/converter.cpp\nrename to src/libcamera/converter/converter_v4l2_m2m.cpp\nindex acaaa64c..5af054be 100644\n--- a/src/libcamera/pipeline/simple/converter.cpp\n+++ b/src/libcamera/converter/converter_v4l2_m2m.cpp\n@@ -1,12 +1,11 @@\n /* SPDX-License-Identifier: LGPL-2.1-or-later */\n /*\n  * Copyright (C) 2020, Laurent Pinchart\n+ * Copyright 2022 NXP\n  *\n- * converter.cpp - Format converter for simple pipeline handler\n+ * converter_v4l2_m2m.cpp - V4L2 M2M Format converter\n  */\n \n-#include \"converter.h\"\n-\n #include <algorithm>\n #include <limits.h>\n \n@@ -20,19 +19,32 @@\n \n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/v4l2_videodevice.h\"\n+#include \"libcamera/internal/converter/converter_v4l2_m2m.h\"\n+\n+/**\n+ * \\file internal/converter/converter_v4l2_m2m.h\n+ * \\brief V4L2 M2M based converter\n+ */\n \n namespace libcamera {\n \n-LOG_DECLARE_CATEGORY(SimplePipeline)\n+LOG_DECLARE_CATEGORY(Converter)\n+\n+/**\n+ * \\class V4L2M2MConverter\n+ * \\brief V4L2 M2M based converter\n+ *\n+ * The V4L2 M2M converter implements the converter interface based on V4L2 M2M device.\n+ */\n \n /* -----------------------------------------------------------------------------\n- * SimpleConverter::Stream\n+ * V4L2M2MConverter::Stream\n  */\n \n-SimpleConverter::Stream::Stream(SimpleConverter *converter, unsigned int index)\n+V4L2M2MConverter::Stream::Stream(V4L2M2MConverter *converter, unsigned int index)\n \t: converter_(converter), index_(index)\n {\n-\tm2m_ = std::make_unique<V4L2M2MDevice>(converter->deviceNode_);\n+\tm2m_ = std::make_unique<V4L2M2MDevice>(converter->deviceNode());\n \n \tm2m_->output()->bufferReady.connect(this, &Stream::outputBufferReady);\n \tm2m_->capture()->bufferReady.connect(this, &Stream::captureBufferReady);\n@@ -42,8 +54,8 @@ SimpleConverter::Stream::Stream(SimpleConverter *converter, unsigned int index)\n \t\tm2m_.reset();\n }\n \n-int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg,\n-\t\t\t\t       const StreamConfiguration &outputCfg)\n+int V4L2M2MConverter::Stream::configure(const StreamConfiguration &inputCfg,\n+\t\t\t\t\tconst StreamConfiguration &outputCfg)\n {\n \tV4L2PixelFormat videoFormat =\n \t\tm2m_->output()->toV4L2PixelFormat(inputCfg.pixelFormat);\n@@ -56,14 +68,14 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg,\n \n \tint ret = m2m_->output()->setFormat(&format);\n \tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Failed to set input format: \" << strerror(-ret);\n \t\treturn ret;\n \t}\n \n \tif (format.fourcc != videoFormat || format.size != inputCfg.size ||\n \t    format.planes[0].bpl != inputCfg.stride) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Input format not supported (requested \"\n \t\t\t<< inputCfg.size << \"-\" << videoFormat\n \t\t\t<< \", got \" << format << \")\";\n@@ -78,13 +90,13 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg,\n \n \tret = m2m_->capture()->setFormat(&format);\n \tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Failed to set output format: \" << strerror(-ret);\n \t\treturn ret;\n \t}\n \n \tif (format.fourcc != videoFormat || format.size != outputCfg.size) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Output format not supported\";\n \t\treturn -EINVAL;\n \t}\n@@ -95,13 +107,13 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg,\n \treturn 0;\n }\n \n-int SimpleConverter::Stream::exportBuffers(unsigned int count,\n-\t\t\t\t\t   std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n+int V4L2M2MConverter::Stream::exportBuffers(unsigned int count,\n+\t\t\t\t\t    std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \treturn m2m_->capture()->exportBuffers(count, buffers);\n }\n \n-int SimpleConverter::Stream::start()\n+int V4L2M2MConverter::Stream::start()\n {\n \tint ret = m2m_->output()->importBuffers(inputBufferCount_);\n \tif (ret < 0)\n@@ -128,7 +140,7 @@ int SimpleConverter::Stream::start()\n \treturn 0;\n }\n \n-void SimpleConverter::Stream::stop()\n+void V4L2M2MConverter::Stream::stop()\n {\n \tm2m_->capture()->streamOff();\n \tm2m_->output()->streamOff();\n@@ -136,8 +148,7 @@ void SimpleConverter::Stream::stop()\n \tm2m_->output()->releaseBuffers();\n }\n \n-int SimpleConverter::Stream::queueBuffers(FrameBuffer *input,\n-\t\t\t\t\t  FrameBuffer *output)\n+int V4L2M2MConverter::Stream::queueBuffers(FrameBuffer *input, FrameBuffer *output)\n {\n \tint ret = m2m_->output()->queueBuffer(input);\n \tif (ret < 0)\n@@ -150,12 +161,12 @@ int SimpleConverter::Stream::queueBuffers(FrameBuffer *input,\n \treturn 0;\n }\n \n-std::string SimpleConverter::Stream::logPrefix() const\n+std::string V4L2M2MConverter::Stream::logPrefix() const\n {\n \treturn \"stream\" + std::to_string(index_);\n }\n \n-void SimpleConverter::Stream::outputBufferReady(FrameBuffer *buffer)\n+void V4L2M2MConverter::Stream::outputBufferReady(FrameBuffer *buffer)\n {\n \tauto it = converter_->queue_.find(buffer);\n \tif (it == converter_->queue_.end())\n@@ -167,32 +178,26 @@ void SimpleConverter::Stream::outputBufferReady(FrameBuffer *buffer)\n \t}\n }\n \n-void SimpleConverter::Stream::captureBufferReady(FrameBuffer *buffer)\n+void V4L2M2MConverter::Stream::captureBufferReady(FrameBuffer *buffer)\n {\n \tconverter_->outputBufferReady.emit(buffer);\n }\n \n /* -----------------------------------------------------------------------------\n- * SimpleConverter\n+ * V4L2M2MConverter\n  */\n \n-SimpleConverter::SimpleConverter(MediaDevice *media)\n+/**\n+ * \\brief Construct a V4L2M2MConverter instance\n+ * \\param[in] media The media device implementing the converter\n+ */\n+V4L2M2MConverter::V4L2M2MConverter(MediaDevice *media)\n+\t: Converter(media)\n {\n-\t/*\n-\t * Locate the video node. There's no need to validate the pipeline\n-\t * further, the caller guarantees that this is a V4L2 mem2mem device.\n-\t */\n-\tconst std::vector<MediaEntity *> &entities = media->entities();\n-\tauto it = std::find_if(entities.begin(), entities.end(),\n-\t\t\t       [](MediaEntity *entity) {\n-\t\t\t\t       return entity->function() == MEDIA_ENT_F_IO_V4L;\n-\t\t\t       });\n-\tif (it == entities.end())\n+\tif (deviceNode().empty())\n \t\treturn;\n \n-\tdeviceNode_ = (*it)->deviceNode();\n-\n-\tm2m_ = std::make_unique<V4L2M2MDevice>(deviceNode_);\n+\tm2m_ = std::make_unique<V4L2M2MDevice>(deviceNode());\n \tint ret = m2m_->open();\n \tif (ret < 0) {\n \t\tm2m_.reset();\n@@ -200,7 +205,18 @@ SimpleConverter::SimpleConverter(MediaDevice *media)\n \t}\n }\n \n-std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)\n+/**\n+ * \\copydoc libcamera::Converter::loadConfiguration\n+ */\n+\n+/**\n+ * \\copydoc libcamera::Converter::isValid\n+ */\n+\n+/**\n+ * \\copydoc libcamera::Converter::formats\n+ */\n+std::vector<PixelFormat> V4L2M2MConverter::formats(PixelFormat input)\n {\n \tif (!m2m_)\n \t\treturn {};\n@@ -215,13 +231,13 @@ std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)\n \n \tint ret = m2m_->output()->setFormat(&v4l2Format);\n \tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Failed to set format: \" << strerror(-ret);\n \t\treturn {};\n \t}\n \n \tif (v4l2Format.fourcc != m2m_->output()->toV4L2PixelFormat(input)) {\n-\t\tLOG(SimplePipeline, Debug)\n+\t\tLOG(Converter, Debug)\n \t\t\t<< \"Input format \" << input << \" not supported.\";\n \t\treturn {};\n \t}\n@@ -237,7 +253,10 @@ std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)\n \treturn pixelFormats;\n }\n \n-SizeRange SimpleConverter::sizes(const Size &input)\n+/**\n+ * \\copydoc libcamera::Converter::sizes\n+ */\n+SizeRange V4L2M2MConverter::sizes(const Size &input)\n {\n \tif (!m2m_)\n \t\treturn {};\n@@ -252,7 +271,7 @@ SizeRange SimpleConverter::sizes(const Size &input)\n \n \tint ret = m2m_->output()->setFormat(&format);\n \tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Failed to set format: \" << strerror(-ret);\n \t\treturn {};\n \t}\n@@ -262,7 +281,7 @@ SizeRange SimpleConverter::sizes(const Size &input)\n \tformat.size = { 1, 1 };\n \tret = m2m_->capture()->setFormat(&format);\n \tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Failed to set format: \" << strerror(-ret);\n \t\treturn {};\n \t}\n@@ -272,7 +291,7 @@ SizeRange SimpleConverter::sizes(const Size &input)\n \tformat.size = { UINT_MAX, UINT_MAX };\n \tret = m2m_->capture()->setFormat(&format);\n \tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n+\t\tLOG(Converter, Error)\n \t\t\t<< \"Failed to set format: \" << strerror(-ret);\n \t\treturn {};\n \t}\n@@ -282,9 +301,12 @@ SizeRange SimpleConverter::sizes(const Size &input)\n \treturn sizes;\n }\n \n+/**\n+ * \\copydoc libcamera::Converter::strideAndFrameSize\n+ */\n std::tuple<unsigned int, unsigned int>\n-SimpleConverter::strideAndFrameSize(const PixelFormat &pixelFormat,\n-\t\t\t\t    const Size &size)\n+V4L2M2MConverter::strideAndFrameSize(const PixelFormat &pixelFormat,\n+\t\t\t\t     const Size &size)\n {\n \tV4L2DeviceFormat format;\n \tformat.fourcc = m2m_->capture()->toV4L2PixelFormat(pixelFormat);\n@@ -297,8 +319,11 @@ SimpleConverter::strideAndFrameSize(const PixelFormat &pixelFormat,\n \treturn std::make_tuple(format.planes[0].bpl, format.planes[0].size);\n }\n \n-int SimpleConverter::configure(const StreamConfiguration &inputCfg,\n-\t\t\t       const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs)\n+/**\n+ * \\copydoc libcamera::Converter::configure\n+ */\n+int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg,\n+\t\t\t\tconst std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs)\n {\n \tint ret = 0;\n \n@@ -309,7 +334,7 @@ int SimpleConverter::configure(const StreamConfiguration &inputCfg,\n \t\tStream &stream = streams_.emplace_back(this, i);\n \n \t\tif (!stream.isValid()) {\n-\t\t\tLOG(SimplePipeline, Error)\n+\t\t\tLOG(Converter, Error)\n \t\t\t\t<< \"Failed to create stream \" << i;\n \t\t\tret = -EINVAL;\n \t\t\tbreak;\n@@ -328,8 +353,11 @@ int SimpleConverter::configure(const StreamConfiguration &inputCfg,\n \treturn 0;\n }\n \n-int SimpleConverter::exportBuffers(unsigned int output, unsigned int count,\n-\t\t\t\t   std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n+/**\n+ * \\copydoc libcamera::Converter::exportBuffers\n+ */\n+int V4L2M2MConverter::exportBuffers(unsigned int output, unsigned int count,\n+\t\t\t\t    std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n {\n \tif (output >= streams_.size())\n \t\treturn -EINVAL;\n@@ -337,7 +365,10 @@ int SimpleConverter::exportBuffers(unsigned int output, unsigned int count,\n \treturn streams_[output].exportBuffers(count, buffers);\n }\n \n-int SimpleConverter::start()\n+/**\n+ * \\copydoc libcamera::Converter::start\n+ */\n+int V4L2M2MConverter::start()\n {\n \tint ret;\n \n@@ -352,14 +383,20 @@ int SimpleConverter::start()\n \treturn 0;\n }\n \n-void SimpleConverter::stop()\n+/**\n+ * \\copydoc libcamera::Converter::stop\n+ */\n+void V4L2M2MConverter::stop()\n {\n \tfor (Stream &stream : utils::reverse(streams_))\n \t\tstream.stop();\n }\n \n-int SimpleConverter::queueBuffers(FrameBuffer *input,\n-\t\t\t\t  const std::map<unsigned int, FrameBuffer *> &outputs)\n+/**\n+ * \\copydoc libcamera::Converter::queueBuffers\n+ */\n+int V4L2M2MConverter::queueBuffers(FrameBuffer *input,\n+\t\t\t\t   const std::map<unsigned int, FrameBuffer *> &outputs)\n {\n \tunsigned int mask = 0;\n \tint ret;\n@@ -402,4 +439,6 @@ int SimpleConverter::queueBuffers(FrameBuffer *input,\n \treturn 0;\n }\n \n+REGISTER_CONVERTER(\"v4l2_m2m\", V4L2M2MConverter, \"pxp\")\n+\n } /* namespace libcamera */\ndiff --git a/src/libcamera/converter/meson.build b/src/libcamera/converter/meson.build\nnew file mode 100644\nindex 00000000..2aa72fe4\n--- /dev/null\n+++ b/src/libcamera/converter/meson.build\n@@ -0,0 +1,5 @@\n+# SPDX-License-Identifier: CC0-1.0\n+\n+libcamera_sources += files([\n+        'converter_v4l2_m2m.cpp'\n+])\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 3a9fc31f..d2f75741 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -62,6 +62,7 @@ libatomic = cc.find_library('atomic', required : false)\n libthreads = dependency('threads')\n \n subdir('base')\n+subdir('converter')\n subdir('ipa')\n subdir('pipeline')\n subdir('proxy')\ndiff --git a/src/libcamera/pipeline/simple/meson.build b/src/libcamera/pipeline/simple/meson.build\nindex 9c99b32f..42b0896d 100644\n--- a/src/libcamera/pipeline/simple/meson.build\n+++ b/src/libcamera/pipeline/simple/meson.build\n@@ -1,6 +1,5 @@\n # SPDX-License-Identifier: CC0-1.0\n \n libcamera_sources += files([\n-    'converter.cpp',\n     'simple.cpp',\n ])\ndiff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex 37b3e7ac..5cc6bc6a 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -30,13 +30,13 @@\n \n #include \"libcamera/internal/camera.h\"\n #include \"libcamera/internal/camera_sensor.h\"\n+#include \"libcamera/internal/converter.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/v4l2_subdevice.h\"\n #include \"libcamera/internal/v4l2_videodevice.h\"\n \n-#include \"converter.h\"\n \n namespace libcamera {\n \n@@ -266,7 +266,7 @@ public:\n \tstd::vector<Configuration> configs_;\n \tstd::map<PixelFormat, std::vector<const Configuration *>> formats_;\n \n-\tstd::unique_ptr<SimpleConverter> converter_;\n+\tstd::unique_ptr<Converter> converter_;\n \tstd::vector<std::unique_ptr<FrameBuffer>> converterBuffers_;\n \tbool useConverter_;\n \tstd::queue<std::map<unsigned int, FrameBuffer *>> converterQueue_;\n@@ -492,7 +492,7 @@ int SimpleCameraData::init()\n \t/* Open the converter, if any. */\n \tMediaDevice *converter = pipe->converter();\n \tif (converter) {\n-\t\tconverter_ = std::make_unique<SimpleConverter>(converter);\n+\t\tconverter_ = ConverterFactoryBase::create(converter);\n \t\tif (!converter_->isValid()) {\n \t\t\tLOG(SimplePipeline, Warning)\n \t\t\t\t<< \"Failed to create converter, disabling format conversion\";\n","prefixes":["libcamera-devel","2/2"]}