{"id":17352,"url":"https://patchwork.libcamera.org/api/patches/17352/?format=json","web_url":"https://patchwork.libcamera.org/patch/17352/","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":"<20220908184850.1874303-11-xavier.roumegue@oss.nxp.com>","date":"2022-09-08T18:48:46","name":"[libcamera-devel,10/14] libcamera: pipeline: simple: converter: Use generic converter interface","commit_ref":null,"pull_url":null,"state":"changes-requested","archived":false,"hash":"b2bcb77ee97c58443d72dcc9f53be5a93a5cc7ee","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/17352/mbox/","series":[{"id":3477,"url":"https://patchwork.libcamera.org/api/series/3477/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=3477","date":"2022-09-08T18:48:36","name":"Add dw100 dewarper support to simple/rkisp1 pipeline","version":1,"mbox":"https://patchwork.libcamera.org/series/3477/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/17352/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/17352/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 0EBE6C327E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  8 Sep 2022 18:49:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BC3DF6203B;\n\tThu,  8 Sep 2022 20:49:28 +0200 (CEST)","from EUR04-DB3-obe.outbound.protection.outlook.com\n\t(mail-eopbgr60070.outbound.protection.outlook.com [40.107.6.70])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 68695620AF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  8 Sep 2022 20:49:22 +0200 (CEST)","from PAXPR04MB8703.eurprd04.prod.outlook.com\n\t(2603:10a6:102:21e::22)\n\tby AS8PR04MB8852.eurprd04.prod.outlook.com (2603:10a6:20b:42f::14)\n\twith Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5612.19;\n\tThu, 8 Sep 2022 18:49:21 +0000","from PAXPR04MB8703.eurprd04.prod.outlook.com\n\t([fe80::485:adba:7081:715a]) by\n\tPAXPR04MB8703.eurprd04.prod.outlook.com\n\t([fe80::485:adba:7081:715a%3]) with mapi id 15.20.5612.019;\n\tThu, 8 Sep 2022 18:49:21 +0000"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1662662968;\n\tbh=bXFTFLYPc8xs5W+ZTXlG2P+wmN/hywT2knH1TyhTrqU=;\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=ZmehGSnJZyAPbV/BzrmWqpa/XXpf9hy8x2CcteyCVUrCRBfmQQnNZB2u5xW7Gz7SV\n\tpJYfPb8ilgFj4GKfNor4yJVonSKpUYevO3LEEhy6n8YAtdIgBNss48KEJjc87hCfkc\n\tMOw3pvxySXbHgGsx0t2XO0F9RZPCEgtd4+kIHWMgArAgroYunw/56DwXX1xurdDMmv\n\tkz7R2QebH/GwNMZGW/0Vo9Jk+LipzkhNRw75CqCyWESu4SUVdXSKBv8nSpb/p1QyU6\n\tty0LejIdcw4WZz5gQraliAymlcGMbL7PAGUOP/xsZFGSEPra5P3bm6QixJaFGo4bLo\n\t6v7O33/njK8rA==","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=yQKjXSBzqXyIduGILBjaZsOGxtx3tljw1EuJ+wiPwdM=;\n\tb=XjK67miQ9m94mJpXvalcrzTaTId7yN7IHrbZbouFM4AS5CEd8zbOo5DKl3HQctepzT36vP8aWCzTyMNIR7+aabpx1hN9oI3W5YRtnTlcNvGZxI25ZfJWCJKppl1nk3l4wLxMyN5T43VaC4R832mI/MzbSTSM5QkEY8gd5mlqQj0="],"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=\"XjK67miQ\"; 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=NQQCbsgmUGUYApkPU8QjEzy9/NcmMwd/gmeNk4lrioHZ7fjHTFhqArZ4xwZRJR2tpM8/qiu1Vnr9/SvFTVtHltmIJvK1fjkzCsvv2yNEOkt+3g1z5puDF8xmmU/i7wZi8f3vxUZWXs+Bkt2Rr4AKauaug7sLKrhG0gkCpDanCQNvTfvhx7y9TcxlgHTjPSR20HZVP6KePXvzJHVw0XGB9RBuvvxnbFyZzSBDKnAkV+vf6nuhX4Jy9Y0W6Pv4a6AAG8XlTyvYc1ZpdebkAR67o6BHF+FMi3tQ3taIXwlRCINKt4MITVUwvflEmeBl1k442MPie2bkTwUrnFWbqRsxJw==","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=yQKjXSBzqXyIduGILBjaZsOGxtx3tljw1EuJ+wiPwdM=;\n\tb=HU2aGOdX16HvrhAWANWHiK2QDx8dwPK6H43nVxzZYbRC2cOHMVWts9DUxT46vcKFlqy4r98FR2Z1axszfOHzEDWRjZEKLWFqvs1xDBLFdwJo6XIsO9ND0oprJ0m6T83C2mbeT4C/U8zZyEr3rom65O8ZkNpIxCu/CNhP+rNCr0tKLXrvxLRl+/4Vgu+KwXRgrKJgUQkVQXQK8RddCPKTg0/G1ob3AygG7B5msRzjt3+2/FhdR8DRnmFIxvh67YQZY/weHt/EaKz9q9HYTU+jEQliO/EKY44GVeRfhEj5D0Loh8iP/fFfO2jS0Gxr0G9ytQi6+nHuudqCeRDiyjDOaA==","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":"libcamera-devel@lists.libcamera.org","Date":"Thu,  8 Sep 2022 20:48:46 +0200","Message-Id":"<20220908184850.1874303-11-xavier.roumegue@oss.nxp.com>","X-Mailer":"git-send-email 2.37.3","In-Reply-To":"<20220908184850.1874303-1-xavier.roumegue@oss.nxp.com>","References":"<20220908184850.1874303-1-xavier.roumegue@oss.nxp.com>","Content-Transfer-Encoding":"8bit","Content-Type":"text/plain","X-ClientProxiedBy":"PR3P250CA0001.EURP250.PROD.OUTLOOK.COM\n\t(2603:10a6:102:57::6) 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_|AS8PR04MB8852:EE_","X-MS-Office365-Filtering-Correlation-Id":"09bf97ec-97bc-4715-de6a-08da91cad762","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":"Xx2QVhosLh2G6clg3MZOs2p6MEKCBOmvXlkNgdwndVjLlyDzF7m3rKW9xpao/eXaqocBl0jm22QFsTCbs1j+2I1varn9CddfsiH6QEBnD6moE0eGGhkl+KLz8nmY3z/kjnong1cOiikiPBIZBrKcrHC17jGv4uPtD2setzxFjyiDRww8WMeCtimmXle+2TOqbbwslT7kWZoAjQ8L8Ul1IUJvFpzM0dM+T1FPjukIMH7z+SfEs7TbMPJKbExAvFRXWt/mQxvSkENOK8srxOiXfOViZgGci5BQHXfDGcjt6DlYof2fDeeJaLNzKPXbbKOEWKq/lkFOaX/2wsbYVGu99ssu3otNmlb1hmMSaSAJGhRtxDgfM4qmWoUViJ2yNjJ6sI5EldZWAOphRhJ+B/jEWHH3AmR1ZHbsXsq9A+/2+ol6RZwOQJUTLfim0ABdQ24uWLD6PSFQwsOqW6h0zsa+4aKAfPjYyVPevclv4VmNZ6AI/vKa42c31hvK9y5QbfCf0EIPFet6ca1gYsjHLKTnw3JZo3TcP6+YACj6Su9gVcJ22mfPbitWrGK6D6Fqo5Kb44su/t4yKLV0IwVd84OSNgM53aMmsygXKMhz+4PTvdd3q8XdE4Y3t8qLoYmB34+NWxGXxR1DD1AydPd6YFpFlb907a2stCIo6VZvV2RxyKAYe2cgpBrszow0WQv8PBMGVWuf37yrSHsd0mCqNqi/5gdIJPMvnYI32yThCGGShsPtgzxHnOvnLjt3WwnJF91JcjmtL2IGh6o04Zo066cQJw==","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:(13230016)(4636009)(39860400002)(346002)(376002)(396003)(136003)(366004)(38100700002)(66556008)(66476007)(66946007)(8936002)(30864003)(44832011)(5660300002)(4326008)(8676002)(6916009)(316002)(41300700001)(186003)(1076003)(2616005)(2906002)(478600001)(6666004)(86362001)(6512007)(52116002)(6506007)(83380400001)(6486002)(41533002);\n\tDIR:OUT; SFP:1101; ","X-MS-Exchange-AntiSpam-MessageData-ChunkCount":"1","X-MS-Exchange-AntiSpam-MessageData-0":"qkANBpl4bYvcqiIpUd07ydfWSV2EYj1lkXUseSQbei3KqZniy4Bpnoyreqdm2EHBTNnxvPH2CyD0Wq0gWZqgidigLcx0s1rAoZXX1YgoHuVRaosOGZOPeZ+vWZ02GYpiZHTGoCC6fVR0cfXcNaKV9oxu5Hs6y6wHsakkGIEza/6q9sRrh2ttlHMjnHH3XJp6X3QhiKOl/oz4ezOTPzA/b7t0or/1pI02c2kxx8wkE1Hcv78U9Wa3BpFkjBkeQHaRH/DsK9A94raKaMIpdKECQz9FASFBXqwRWVLajeZUfbl7fPMp5Ng5AFdxLqrddvCxSaf1wWZ5VkfEnxpW0uj3AgGFaDm2q+IVLE34IGdj5fe7mYwRkWxzxzjlbnUXYSf3kthBmyzATY4cF2Ou+KLkhHiY+Xen3orV68y11oNmeGQYbWPOuH9EenhtVovRGo4h1WiXW+sd60s62b3bax7gxRdAknzgZk5QYuSfWkEx5/oh8Va0CpPemaKVHo2t9e80D8fVaKSQIPNr1t6T74EPaMxmBhfx9OcEkcmCyr1SBvPJpAcxznF+QHYBvam1Z1VsnvMTwPjF4041R2yWlNj2FrIuWNo/9q5fdKTWzjwXMKLXbK1Hk7x/w7QBHxkW/vZTrbwmoj6Ql1DsvXE3F19nHYqvTQKJwtX7bvpJa6vnJL/b9PUL9UVSdagVQ67nxvcKL5xFW2Y5/jlii8S7vjwRr6C1v2R8nheAYtNXxkw3Xp2gJIIMVXALZfJtGFGt0hd0QlF5AASHD4RO0SeshG9hIw0xLcK5paS5UiZIQKM8FLDvpSQGRIWm+9gitJlCpAdIQ/wQYMTeKPkbZRqfr26erAjruCBg6TcVWSpnHNmjxQZm/PiN/Q8jN21UUyshD6Ac1G+ZMIn9j/NNCZbYrwWCBPsrpaahyq8HDXFl1PBTQIPmuXxY6QkdmED+kK+6gM3V59dYo5kbzJEKFICyJj+PW/pbBiXSzE4c2l6PlR1lvrX0KyVSWxWDkL/NvK08JOS15oEZR7TJzOFWl3AAsT4cvWLT9nIc36gMeWzBfV5kg0zkmwGXX3bH62LEW54PqjLnLfKQup1Fgb+QibvRCA6QaObqFzXSTADOhWeaYmQ0qJHKXtE27wnyJILJbLe5fwMkzHW5pyq9M3nxeWIuODx35eqHoApmKFyAqFGBvp1K+L708JtaB4UEAvUi5hqH0OyDxOQBHTEkVVCAmmKminRCCkwiUCBwjyF8ckfYLk/hvQFN84eitMV4dzxXhYqgGLmpCml6QGGVqinuS4JsrFZYiHTfuKdJMRMuK46DisNq5yeeNGFCzZ85jQFpWyKyW9f48A5ch+3dxRyJjaQcsTFDu4QnH7E7SF4DyjsJ8iQIv+BQPggMqVtIFZ/sFZ8yZveNWaUhBIGQeAPl/RocyFD7IEJ1Ltmb68DxAjvtfjXZEl9GFcTjg/nZgZ178tmoWC1IrcA7GnUBC6eoeuTHCmiyFGyayox+kn3px+eT5PaXiK6a5CX3M+izDmWcNeZCijZFYV1Wkf0kDZ6jkMnxpRmX0tSR4AUTpjdInyxCOWHQh924KcGYRNHdxlG4u/0w8zcQMy18yxJUS7FoxU4truQokcD2sxi0GBX55PE9dZFG4Z0PN65+OglSFMk18XdpJdYs0pmp6qOcuMe+ij2Da7rtwQ==","X-OriginatorOrg":"oss.nxp.com","X-MS-Exchange-CrossTenant-Network-Message-Id":"09bf97ec-97bc-4715-de6a-08da91cad762","X-MS-Exchange-CrossTenant-AuthSource":"PAXPR04MB8703.eurprd04.prod.outlook.com","X-MS-Exchange-CrossTenant-AuthAs":"Internal","X-MS-Exchange-CrossTenant-OriginalArrivalTime":"08 Sep 2022 18:49:21.0910\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":"Xi6pKiyQnAY2TRc/2PdZ9jmq1ZglA/sBiZ8oHetA7Yktwli+lqGoUoiDMggOhtjRwJiw+AlfcxLdtzyLDwTo5Q==","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"AS8PR04MB8852","Subject":"[libcamera-devel] [PATCH 10/14] 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 via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Xavier Roumegue <xavier.roumegue@oss.nxp.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"Signed-off-by: Xavier Roumegue <xavier.roumegue@oss.nxp.com>\n---\n src/libcamera/pipeline/simple/converter.cpp | 405 --------------------\n src/libcamera/pipeline/simple/converter.h   |  98 -----\n src/libcamera/pipeline/simple/meson.build   |   1 -\n src/libcamera/pipeline/simple/simple.cpp    |   6 +-\n 4 files changed, 3 insertions(+), 507 deletions(-)\n delete mode 100644 src/libcamera/pipeline/simple/converter.cpp\n delete mode 100644 src/libcamera/pipeline/simple/converter.h","diff":"diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp\ndeleted file mode 100644\nindex acaaa64c..00000000\n--- a/src/libcamera/pipeline/simple/converter.cpp\n+++ /dev/null\n@@ -1,405 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2020, Laurent Pinchart\n- *\n- * converter.cpp - Format converter for simple pipeline handler\n- */\n-\n-#include \"converter.h\"\n-\n-#include <algorithm>\n-#include <limits.h>\n-\n-#include <libcamera/base/log.h>\n-#include <libcamera/base/signal.h>\n-#include <libcamera/base/utils.h>\n-\n-#include <libcamera/framebuffer.h>\n-#include <libcamera/geometry.h>\n-#include <libcamera/stream.h>\n-\n-#include \"libcamera/internal/media_device.h\"\n-#include \"libcamera/internal/v4l2_videodevice.h\"\n-\n-namespace libcamera {\n-\n-LOG_DECLARE_CATEGORY(SimplePipeline)\n-\n-/* -----------------------------------------------------------------------------\n- * SimpleConverter::Stream\n- */\n-\n-SimpleConverter::Stream::Stream(SimpleConverter *converter, unsigned int index)\n-\t: converter_(converter), index_(index)\n-{\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-\n-\tint ret = m2m_->open();\n-\tif (ret < 0)\n-\t\tm2m_.reset();\n-}\n-\n-int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg,\n-\t\t\t\t       const StreamConfiguration &outputCfg)\n-{\n-\tV4L2PixelFormat videoFormat =\n-\t\tm2m_->output()->toV4L2PixelFormat(inputCfg.pixelFormat);\n-\n-\tV4L2DeviceFormat format;\n-\tformat.fourcc = videoFormat;\n-\tformat.size = inputCfg.size;\n-\tformat.planesCount = 1;\n-\tformat.planes[0].bpl = inputCfg.stride;\n-\n-\tint ret = m2m_->output()->setFormat(&format);\n-\tif (ret < 0) {\n-\t\tLOG(SimplePipeline, 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\t\t<< \"Input format not supported (requested \"\n-\t\t\t<< inputCfg.size << \"-\" << videoFormat\n-\t\t\t<< \", got \" << format << \")\";\n-\t\treturn -EINVAL;\n-\t}\n-\n-\t/* Set the pixel format and size on the output. */\n-\tvideoFormat = m2m_->capture()->toV4L2PixelFormat(outputCfg.pixelFormat);\n-\tformat = {};\n-\tformat.fourcc = videoFormat;\n-\tformat.size = outputCfg.size;\n-\n-\tret = m2m_->capture()->setFormat(&format);\n-\tif (ret < 0) {\n-\t\tLOG(SimplePipeline, 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\t\t<< \"Output format not supported\";\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tinputBufferCount_ = inputCfg.bufferCount;\n-\toutputBufferCount_ = outputCfg.bufferCount;\n-\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-{\n-\treturn m2m_->capture()->exportBuffers(count, buffers);\n-}\n-\n-int SimpleConverter::Stream::start()\n-{\n-\tint ret = m2m_->output()->importBuffers(inputBufferCount_);\n-\tif (ret < 0)\n-\t\treturn ret;\n-\n-\tret = m2m_->capture()->importBuffers(outputBufferCount_);\n-\tif (ret < 0) {\n-\t\tstop();\n-\t\treturn ret;\n-\t}\n-\n-\tret = m2m_->output()->streamOn();\n-\tif (ret < 0) {\n-\t\tstop();\n-\t\treturn ret;\n-\t}\n-\n-\tret = m2m_->capture()->streamOn();\n-\tif (ret < 0) {\n-\t\tstop();\n-\t\treturn ret;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-void SimpleConverter::Stream::stop()\n-{\n-\tm2m_->capture()->streamOff();\n-\tm2m_->output()->streamOff();\n-\tm2m_->capture()->releaseBuffers();\n-\tm2m_->output()->releaseBuffers();\n-}\n-\n-int SimpleConverter::Stream::queueBuffers(FrameBuffer *input,\n-\t\t\t\t\t  FrameBuffer *output)\n-{\n-\tint ret = m2m_->output()->queueBuffer(input);\n-\tif (ret < 0)\n-\t\treturn ret;\n-\n-\tret = m2m_->capture()->queueBuffer(output);\n-\tif (ret < 0)\n-\t\treturn ret;\n-\n-\treturn 0;\n-}\n-\n-std::string SimpleConverter::Stream::logPrefix() const\n-{\n-\treturn \"stream\" + std::to_string(index_);\n-}\n-\n-void SimpleConverter::Stream::outputBufferReady(FrameBuffer *buffer)\n-{\n-\tauto it = converter_->queue_.find(buffer);\n-\tif (it == converter_->queue_.end())\n-\t\treturn;\n-\n-\tif (!--it->second) {\n-\t\tconverter_->inputBufferReady.emit(buffer);\n-\t\tconverter_->queue_.erase(it);\n-\t}\n-}\n-\n-void SimpleConverter::Stream::captureBufferReady(FrameBuffer *buffer)\n-{\n-\tconverter_->outputBufferReady.emit(buffer);\n-}\n-\n-/* -----------------------------------------------------------------------------\n- * SimpleConverter\n- */\n-\n-SimpleConverter::SimpleConverter(MediaDevice *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-\t\treturn;\n-\n-\tdeviceNode_ = (*it)->deviceNode();\n-\n-\tm2m_ = std::make_unique<V4L2M2MDevice>(deviceNode_);\n-\tint ret = m2m_->open();\n-\tif (ret < 0) {\n-\t\tm2m_.reset();\n-\t\treturn;\n-\t}\n-}\n-\n-std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)\n-{\n-\tif (!m2m_)\n-\t\treturn {};\n-\n-\t/*\n-\t * Set the format on the input side (V4L2 output) of the converter to\n-\t * enumerate the conversion capabilities on its output (V4L2 capture).\n-\t */\n-\tV4L2DeviceFormat v4l2Format;\n-\tv4l2Format.fourcc = m2m_->output()->toV4L2PixelFormat(input);\n-\tv4l2Format.size = { 1, 1 };\n-\n-\tint ret = m2m_->output()->setFormat(&v4l2Format);\n-\tif (ret < 0) {\n-\t\tLOG(SimplePipeline, 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\t\t<< \"Input format \" << input << \" not supported.\";\n-\t\treturn {};\n-\t}\n-\n-\tstd::vector<PixelFormat> pixelFormats;\n-\n-\tfor (const auto &format : m2m_->capture()->formats()) {\n-\t\tPixelFormat pixelFormat = format.first.toPixelFormat();\n-\t\tif (pixelFormat)\n-\t\t\tpixelFormats.push_back(pixelFormat);\n-\t}\n-\n-\treturn pixelFormats;\n-}\n-\n-SizeRange SimpleConverter::sizes(const Size &input)\n-{\n-\tif (!m2m_)\n-\t\treturn {};\n-\n-\t/*\n-\t * Set the size on the input side (V4L2 output) of the converter to\n-\t * enumerate the scaling capabilities on its output (V4L2 capture).\n-\t */\n-\tV4L2DeviceFormat format;\n-\tformat.fourcc = V4L2PixelFormat();\n-\tformat.size = input;\n-\n-\tint ret = m2m_->output()->setFormat(&format);\n-\tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n-\t\t\t<< \"Failed to set format: \" << strerror(-ret);\n-\t\treturn {};\n-\t}\n-\n-\tSizeRange sizes;\n-\n-\tformat.size = { 1, 1 };\n-\tret = m2m_->capture()->setFormat(&format);\n-\tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n-\t\t\t<< \"Failed to set format: \" << strerror(-ret);\n-\t\treturn {};\n-\t}\n-\n-\tsizes.min = format.size;\n-\n-\tformat.size = { UINT_MAX, UINT_MAX };\n-\tret = m2m_->capture()->setFormat(&format);\n-\tif (ret < 0) {\n-\t\tLOG(SimplePipeline, Error)\n-\t\t\t<< \"Failed to set format: \" << strerror(-ret);\n-\t\treturn {};\n-\t}\n-\n-\tsizes.max = format.size;\n-\n-\treturn sizes;\n-}\n-\n-std::tuple<unsigned int, unsigned int>\n-SimpleConverter::strideAndFrameSize(const PixelFormat &pixelFormat,\n-\t\t\t\t    const Size &size)\n-{\n-\tV4L2DeviceFormat format;\n-\tformat.fourcc = m2m_->capture()->toV4L2PixelFormat(pixelFormat);\n-\tformat.size = size;\n-\n-\tint ret = m2m_->capture()->tryFormat(&format);\n-\tif (ret < 0)\n-\t\treturn std::make_tuple(0, 0);\n-\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-\tint ret = 0;\n-\n-\tstreams_.clear();\n-\tstreams_.reserve(outputCfgs.size());\n-\n-\tfor (unsigned int i = 0; i < outputCfgs.size(); ++i) {\n-\t\tStream &stream = streams_.emplace_back(this, i);\n-\n-\t\tif (!stream.isValid()) {\n-\t\t\tLOG(SimplePipeline, Error)\n-\t\t\t\t<< \"Failed to create stream \" << i;\n-\t\t\tret = -EINVAL;\n-\t\t\tbreak;\n-\t\t}\n-\n-\t\tret = stream.configure(inputCfg, outputCfgs[i]);\n-\t\tif (ret < 0)\n-\t\t\tbreak;\n-\t}\n-\n-\tif (ret < 0) {\n-\t\tstreams_.clear();\n-\t\treturn ret;\n-\t}\n-\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-\tif (output >= streams_.size())\n-\t\treturn -EINVAL;\n-\n-\treturn streams_[output].exportBuffers(count, buffers);\n-}\n-\n-int SimpleConverter::start()\n-{\n-\tint ret;\n-\n-\tfor (Stream &stream : streams_) {\n-\t\tret = stream.start();\n-\t\tif (ret < 0) {\n-\t\t\tstop();\n-\t\t\treturn ret;\n-\t\t}\n-\t}\n-\n-\treturn 0;\n-}\n-\n-void SimpleConverter::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-\tunsigned int mask = 0;\n-\tint ret;\n-\n-\t/*\n-\t * Validate the outputs as a sanity check: at least one output is\n-\t * required, all outputs must reference a valid stream and no two\n-\t * outputs can reference the same stream.\n-\t */\n-\tif (outputs.empty())\n-\t\treturn -EINVAL;\n-\n-\tfor (auto [index, buffer] : outputs) {\n-\t\tif (!buffer)\n-\t\t\treturn -EINVAL;\n-\t\tif (index >= streams_.size())\n-\t\t\treturn -EINVAL;\n-\t\tif (mask & (1 << index))\n-\t\t\treturn -EINVAL;\n-\n-\t\tmask |= 1 << index;\n-\t}\n-\n-\t/* Queue the input and output buffers to all the streams. */\n-\tfor (auto [index, buffer] : outputs) {\n-\t\tret = streams_[index].queueBuffers(input, buffer);\n-\t\tif (ret < 0)\n-\t\t\treturn ret;\n-\t}\n-\n-\t/*\n-\t * Add the input buffer to the queue, with the number of streams as a\n-\t * reference count. Completion of the input buffer will be signalled by\n-\t * the stream that releases the last reference.\n-\t */\n-\tqueue_.emplace(std::piecewise_construct,\n-\t\t       std::forward_as_tuple(input),\n-\t\t       std::forward_as_tuple(outputs.size()));\n-\n-\treturn 0;\n-}\n-\n-} /* namespace libcamera */\ndiff --git a/src/libcamera/pipeline/simple/converter.h b/src/libcamera/pipeline/simple/converter.h\ndeleted file mode 100644\nindex f0ebe2e0..00000000\n--- a/src/libcamera/pipeline/simple/converter.h\n+++ /dev/null\n@@ -1,98 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2020, Laurent Pinchart\n- *\n- * converter.h - Format converter for simple pipeline handler\n- */\n-\n-#pragma once\n-\n-#include <functional>\n-#include <map>\n-#include <memory>\n-#include <string>\n-#include <tuple>\n-#include <vector>\n-\n-#include <libcamera/pixel_format.h>\n-\n-#include <libcamera/base/log.h>\n-#include <libcamera/base/signal.h>\n-\n-namespace libcamera {\n-\n-class FrameBuffer;\n-class MediaDevice;\n-class Size;\n-class SizeRange;\n-struct StreamConfiguration;\n-class V4L2M2MDevice;\n-\n-class SimpleConverter\n-{\n-public:\n-\tSimpleConverter(MediaDevice *media);\n-\n-\tbool isValid() const { return m2m_ != nullptr; }\n-\n-\tstd::vector<PixelFormat> formats(PixelFormat input);\n-\tSizeRange sizes(const Size &input);\n-\n-\tstd::tuple<unsigned int, unsigned int>\n-\tstrideAndFrameSize(const PixelFormat &pixelFormat, const Size &size);\n-\n-\tint configure(const StreamConfiguration &inputCfg,\n-\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfg);\n-\tint exportBuffers(unsigned int ouput, unsigned int count,\n-\t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n-\n-\tint start();\n-\tvoid stop();\n-\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-\n-\t\tbool isValid() const { return m2m_ != nullptr; }\n-\n-\t\tint configure(const StreamConfiguration &inputCfg,\n-\t\t\t      const StreamConfiguration &outputCfg);\n-\t\tint exportBuffers(unsigned int count,\n-\t\t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n-\n-\t\tint start();\n-\t\tvoid stop();\n-\n-\t\tint queueBuffers(FrameBuffer *input, FrameBuffer *output);\n-\n-\tprotected:\n-\t\tstd::string logPrefix() const override;\n-\n-\tprivate:\n-\t\tvoid captureBufferReady(FrameBuffer *buffer);\n-\t\tvoid outputBufferReady(FrameBuffer *buffer);\n-\n-\t\tSimpleConverter *converter_;\n-\t\tunsigned int index_;\n-\t\tstd::unique_ptr<V4L2M2MDevice> m2m_;\n-\n-\t\tunsigned int inputBufferCount_;\n-\t\tunsigned int outputBufferCount_;\n-\t};\n-\n-\tstd::string deviceNode_;\n-\tstd::unique_ptr<V4L2M2MDevice> m2m_;\n-\n-\tstd::vector<Stream> streams_;\n-\tstd::map<FrameBuffer *, unsigned int> queue_;\n-};\n-\n-} /* namespace libcamera */\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..2507d586 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_ = ConverterFactory::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","10/14"]}