From patchwork Thu Sep 8 18:48:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xavier Roumegue X-Patchwork-Id: 17352 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 0EBE6C327E for ; Thu, 8 Sep 2022 18:49:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BC3DF6203B; Thu, 8 Sep 2022 20:49:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1662662968; bh=bXFTFLYPc8xs5W+ZTXlG2P+wmN/hywT2knH1TyhTrqU=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=ZmehGSnJZyAPbV/BzrmWqpa/XXpf9hy8x2CcteyCVUrCRBfmQQnNZB2u5xW7Gz7SV pJYfPb8ilgFj4GKfNor4yJVonSKpUYevO3LEEhy6n8YAtdIgBNss48KEJjc87hCfkc MOw3pvxySXbHgGsx0t2XO0F9RZPCEgtd4+kIHWMgArAgroYunw/56DwXX1xurdDMmv kz7R2QebH/GwNMZGW/0Vo9Jk+LipzkhNRw75CqCyWESu4SUVdXSKBv8nSpb/p1QyU6 ty0LejIdcw4WZz5gQraliAymlcGMbL7PAGUOP/xsZFGSEPra5P3bm6QixJaFGo4bLo 6v7O33/njK8rA== Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60070.outbound.protection.outlook.com [40.107.6.70]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 68695620AF for ; Thu, 8 Sep 2022 20:49:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b="XjK67miQ"; dkim-atps=neutral ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NQQCbsgmUGUYApkPU8QjEzy9/NcmMwd/gmeNk4lrioHZ7fjHTFhqArZ4xwZRJR2tpM8/qiu1Vnr9/SvFTVtHltmIJvK1fjkzCsvv2yNEOkt+3g1z5puDF8xmmU/i7wZi8f3vxUZWXs+Bkt2Rr4AKauaug7sLKrhG0gkCpDanCQNvTfvhx7y9TcxlgHTjPSR20HZVP6KePXvzJHVw0XGB9RBuvvxnbFyZzSBDKnAkV+vf6nuhX4Jy9Y0W6Pv4a6AAG8XlTyvYc1ZpdebkAR67o6BHF+FMi3tQ3taIXwlRCINKt4MITVUwvflEmeBl1k442MPie2bkTwUrnFWbqRsxJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=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; bh=yQKjXSBzqXyIduGILBjaZsOGxtx3tljw1EuJ+wiPwdM=; b=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 smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com; dkim=pass header.d=oss.nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com; s=selector2-NXP1-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yQKjXSBzqXyIduGILBjaZsOGxtx3tljw1EuJ+wiPwdM=; b=XjK67miQ9m94mJpXvalcrzTaTId7yN7IHrbZbouFM4AS5CEd8zbOo5DKl3HQctepzT36vP8aWCzTyMNIR7+aabpx1hN9oI3W5YRtnTlcNvGZxI25ZfJWCJKppl1nk3l4wLxMyN5T43VaC4R832mI/MzbSTSM5QkEY8gd5mlqQj0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oss.nxp.com; Received: from PAXPR04MB8703.eurprd04.prod.outlook.com (2603:10a6:102:21e::22) by AS8PR04MB8852.eurprd04.prod.outlook.com (2603:10a6:20b:42f::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5612.19; Thu, 8 Sep 2022 18:49:21 +0000 Received: from PAXPR04MB8703.eurprd04.prod.outlook.com ([fe80::485:adba:7081:715a]) by PAXPR04MB8703.eurprd04.prod.outlook.com ([fe80::485:adba:7081:715a%3]) with mapi id 15.20.5612.019; Thu, 8 Sep 2022 18:49:21 +0000 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> X-ClientProxiedBy: PR3P250CA0001.EURP250.PROD.OUTLOOK.COM (2603:10a6:102:57::6) To PAXPR04MB8703.eurprd04.prod.outlook.com (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:; IPV:NLI; SFV:NSPM; H:PAXPR04MB8703.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(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); DIR: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 (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: converter: Use generic converter interface X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Xavier Roumegue via libcamera-devel From: Xavier Roumegue Reply-To: Xavier Roumegue Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Xavier Roumegue --- src/libcamera/pipeline/simple/converter.cpp | 405 -------------------- src/libcamera/pipeline/simple/converter.h | 98 ----- src/libcamera/pipeline/simple/meson.build | 1 - src/libcamera/pipeline/simple/simple.cpp | 6 +- 4 files changed, 3 insertions(+), 507 deletions(-) delete mode 100644 src/libcamera/pipeline/simple/converter.cpp delete mode 100644 src/libcamera/pipeline/simple/converter.h diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp deleted file mode 100644 index acaaa64c..00000000 --- a/src/libcamera/pipeline/simple/converter.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Laurent Pinchart - * - * converter.cpp - Format converter for simple pipeline handler - */ - -#include "converter.h" - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "libcamera/internal/media_device.h" -#include "libcamera/internal/v4l2_videodevice.h" - -namespace libcamera { - -LOG_DECLARE_CATEGORY(SimplePipeline) - -/* ----------------------------------------------------------------------------- - * SimpleConverter::Stream - */ - -SimpleConverter::Stream::Stream(SimpleConverter *converter, unsigned int index) - : converter_(converter), index_(index) -{ - m2m_ = std::make_unique(converter->deviceNode_); - - m2m_->output()->bufferReady.connect(this, &Stream::outputBufferReady); - m2m_->capture()->bufferReady.connect(this, &Stream::captureBufferReady); - - int ret = m2m_->open(); - if (ret < 0) - m2m_.reset(); -} - -int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg, - const StreamConfiguration &outputCfg) -{ - V4L2PixelFormat videoFormat = - m2m_->output()->toV4L2PixelFormat(inputCfg.pixelFormat); - - V4L2DeviceFormat format; - format.fourcc = videoFormat; - format.size = inputCfg.size; - format.planesCount = 1; - format.planes[0].bpl = inputCfg.stride; - - int ret = m2m_->output()->setFormat(&format); - if (ret < 0) { - LOG(SimplePipeline, Error) - << "Failed to set input format: " << strerror(-ret); - return ret; - } - - if (format.fourcc != videoFormat || format.size != inputCfg.size || - format.planes[0].bpl != inputCfg.stride) { - LOG(SimplePipeline, Error) - << "Input format not supported (requested " - << inputCfg.size << "-" << videoFormat - << ", got " << format << ")"; - return -EINVAL; - } - - /* Set the pixel format and size on the output. */ - videoFormat = m2m_->capture()->toV4L2PixelFormat(outputCfg.pixelFormat); - format = {}; - format.fourcc = videoFormat; - format.size = outputCfg.size; - - ret = m2m_->capture()->setFormat(&format); - if (ret < 0) { - LOG(SimplePipeline, Error) - << "Failed to set output format: " << strerror(-ret); - return ret; - } - - if (format.fourcc != videoFormat || format.size != outputCfg.size) { - LOG(SimplePipeline, Error) - << "Output format not supported"; - return -EINVAL; - } - - inputBufferCount_ = inputCfg.bufferCount; - outputBufferCount_ = outputCfg.bufferCount; - - return 0; -} - -int SimpleConverter::Stream::exportBuffers(unsigned int count, - std::vector> *buffers) -{ - return m2m_->capture()->exportBuffers(count, buffers); -} - -int SimpleConverter::Stream::start() -{ - int ret = m2m_->output()->importBuffers(inputBufferCount_); - if (ret < 0) - return ret; - - ret = m2m_->capture()->importBuffers(outputBufferCount_); - if (ret < 0) { - stop(); - return ret; - } - - ret = m2m_->output()->streamOn(); - if (ret < 0) { - stop(); - return ret; - } - - ret = m2m_->capture()->streamOn(); - if (ret < 0) { - stop(); - return ret; - } - - return 0; -} - -void SimpleConverter::Stream::stop() -{ - m2m_->capture()->streamOff(); - m2m_->output()->streamOff(); - m2m_->capture()->releaseBuffers(); - m2m_->output()->releaseBuffers(); -} - -int SimpleConverter::Stream::queueBuffers(FrameBuffer *input, - FrameBuffer *output) -{ - int ret = m2m_->output()->queueBuffer(input); - if (ret < 0) - return ret; - - ret = m2m_->capture()->queueBuffer(output); - if (ret < 0) - return ret; - - return 0; -} - -std::string SimpleConverter::Stream::logPrefix() const -{ - return "stream" + std::to_string(index_); -} - -void SimpleConverter::Stream::outputBufferReady(FrameBuffer *buffer) -{ - auto it = converter_->queue_.find(buffer); - if (it == converter_->queue_.end()) - return; - - if (!--it->second) { - converter_->inputBufferReady.emit(buffer); - converter_->queue_.erase(it); - } -} - -void SimpleConverter::Stream::captureBufferReady(FrameBuffer *buffer) -{ - converter_->outputBufferReady.emit(buffer); -} - -/* ----------------------------------------------------------------------------- - * SimpleConverter - */ - -SimpleConverter::SimpleConverter(MediaDevice *media) -{ - /* - * Locate the video node. There's no need to validate the pipeline - * further, the caller guarantees that this is a V4L2 mem2mem device. - */ - const std::vector &entities = media->entities(); - auto it = std::find_if(entities.begin(), entities.end(), - [](MediaEntity *entity) { - return entity->function() == MEDIA_ENT_F_IO_V4L; - }); - if (it == entities.end()) - return; - - deviceNode_ = (*it)->deviceNode(); - - m2m_ = std::make_unique(deviceNode_); - int ret = m2m_->open(); - if (ret < 0) { - m2m_.reset(); - return; - } -} - -std::vector SimpleConverter::formats(PixelFormat input) -{ - if (!m2m_) - return {}; - - /* - * Set the format on the input side (V4L2 output) of the converter to - * enumerate the conversion capabilities on its output (V4L2 capture). - */ - V4L2DeviceFormat v4l2Format; - v4l2Format.fourcc = m2m_->output()->toV4L2PixelFormat(input); - v4l2Format.size = { 1, 1 }; - - int ret = m2m_->output()->setFormat(&v4l2Format); - if (ret < 0) { - LOG(SimplePipeline, Error) - << "Failed to set format: " << strerror(-ret); - return {}; - } - - if (v4l2Format.fourcc != m2m_->output()->toV4L2PixelFormat(input)) { - LOG(SimplePipeline, Debug) - << "Input format " << input << " not supported."; - return {}; - } - - std::vector pixelFormats; - - for (const auto &format : m2m_->capture()->formats()) { - PixelFormat pixelFormat = format.first.toPixelFormat(); - if (pixelFormat) - pixelFormats.push_back(pixelFormat); - } - - return pixelFormats; -} - -SizeRange SimpleConverter::sizes(const Size &input) -{ - if (!m2m_) - return {}; - - /* - * Set the size on the input side (V4L2 output) of the converter to - * enumerate the scaling capabilities on its output (V4L2 capture). - */ - V4L2DeviceFormat format; - format.fourcc = V4L2PixelFormat(); - format.size = input; - - int ret = m2m_->output()->setFormat(&format); - if (ret < 0) { - LOG(SimplePipeline, Error) - << "Failed to set format: " << strerror(-ret); - return {}; - } - - SizeRange sizes; - - format.size = { 1, 1 }; - ret = m2m_->capture()->setFormat(&format); - if (ret < 0) { - LOG(SimplePipeline, Error) - << "Failed to set format: " << strerror(-ret); - return {}; - } - - sizes.min = format.size; - - format.size = { UINT_MAX, UINT_MAX }; - ret = m2m_->capture()->setFormat(&format); - if (ret < 0) { - LOG(SimplePipeline, Error) - << "Failed to set format: " << strerror(-ret); - return {}; - } - - sizes.max = format.size; - - return sizes; -} - -std::tuple -SimpleConverter::strideAndFrameSize(const PixelFormat &pixelFormat, - const Size &size) -{ - V4L2DeviceFormat format; - format.fourcc = m2m_->capture()->toV4L2PixelFormat(pixelFormat); - format.size = size; - - int ret = m2m_->capture()->tryFormat(&format); - if (ret < 0) - return std::make_tuple(0, 0); - - return std::make_tuple(format.planes[0].bpl, format.planes[0].size); -} - -int SimpleConverter::configure(const StreamConfiguration &inputCfg, - const std::vector> &outputCfgs) -{ - int ret = 0; - - streams_.clear(); - streams_.reserve(outputCfgs.size()); - - for (unsigned int i = 0; i < outputCfgs.size(); ++i) { - Stream &stream = streams_.emplace_back(this, i); - - if (!stream.isValid()) { - LOG(SimplePipeline, Error) - << "Failed to create stream " << i; - ret = -EINVAL; - break; - } - - ret = stream.configure(inputCfg, outputCfgs[i]); - if (ret < 0) - break; - } - - if (ret < 0) { - streams_.clear(); - return ret; - } - - return 0; -} - -int SimpleConverter::exportBuffers(unsigned int output, unsigned int count, - std::vector> *buffers) -{ - if (output >= streams_.size()) - return -EINVAL; - - return streams_[output].exportBuffers(count, buffers); -} - -int SimpleConverter::start() -{ - int ret; - - for (Stream &stream : streams_) { - ret = stream.start(); - if (ret < 0) { - stop(); - return ret; - } - } - - return 0; -} - -void SimpleConverter::stop() -{ - for (Stream &stream : utils::reverse(streams_)) - stream.stop(); -} - -int SimpleConverter::queueBuffers(FrameBuffer *input, - const std::map &outputs) -{ - unsigned int mask = 0; - int ret; - - /* - * Validate the outputs as a sanity check: at least one output is - * required, all outputs must reference a valid stream and no two - * outputs can reference the same stream. - */ - if (outputs.empty()) - return -EINVAL; - - for (auto [index, buffer] : outputs) { - if (!buffer) - return -EINVAL; - if (index >= streams_.size()) - return -EINVAL; - if (mask & (1 << index)) - return -EINVAL; - - mask |= 1 << index; - } - - /* Queue the input and output buffers to all the streams. */ - for (auto [index, buffer] : outputs) { - ret = streams_[index].queueBuffers(input, buffer); - if (ret < 0) - return ret; - } - - /* - * Add the input buffer to the queue, with the number of streams as a - * reference count. Completion of the input buffer will be signalled by - * the stream that releases the last reference. - */ - queue_.emplace(std::piecewise_construct, - std::forward_as_tuple(input), - std::forward_as_tuple(outputs.size())); - - return 0; -} - -} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/simple/converter.h b/src/libcamera/pipeline/simple/converter.h deleted file mode 100644 index f0ebe2e0..00000000 --- a/src/libcamera/pipeline/simple/converter.h +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Laurent Pinchart - * - * converter.h - Format converter for simple pipeline handler - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -namespace libcamera { - -class FrameBuffer; -class MediaDevice; -class Size; -class SizeRange; -struct StreamConfiguration; -class V4L2M2MDevice; - -class SimpleConverter -{ -public: - SimpleConverter(MediaDevice *media); - - bool isValid() const { return m2m_ != nullptr; } - - std::vector formats(PixelFormat input); - SizeRange sizes(const Size &input); - - std::tuple - strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size); - - int configure(const StreamConfiguration &inputCfg, - const std::vector> &outputCfg); - int exportBuffers(unsigned int ouput, unsigned int count, - std::vector> *buffers); - - int start(); - void stop(); - - int queueBuffers(FrameBuffer *input, - const std::map &outputs); - - Signal inputBufferReady; - Signal outputBufferReady; - -private: - class Stream : protected Loggable - { - public: - Stream(SimpleConverter *converter, unsigned int index); - - bool isValid() const { return m2m_ != nullptr; } - - int configure(const StreamConfiguration &inputCfg, - const StreamConfiguration &outputCfg); - int exportBuffers(unsigned int count, - std::vector> *buffers); - - int start(); - void stop(); - - int queueBuffers(FrameBuffer *input, FrameBuffer *output); - - protected: - std::string logPrefix() const override; - - private: - void captureBufferReady(FrameBuffer *buffer); - void outputBufferReady(FrameBuffer *buffer); - - SimpleConverter *converter_; - unsigned int index_; - std::unique_ptr m2m_; - - unsigned int inputBufferCount_; - unsigned int outputBufferCount_; - }; - - std::string deviceNode_; - std::unique_ptr m2m_; - - std::vector streams_; - std::map queue_; -}; - -} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/simple/meson.build b/src/libcamera/pipeline/simple/meson.build index 9c99b32f..42b0896d 100644 --- a/src/libcamera/pipeline/simple/meson.build +++ b/src/libcamera/pipeline/simple/meson.build @@ -1,6 +1,5 @@ # SPDX-License-Identifier: CC0-1.0 libcamera_sources += files([ - 'converter.cpp', 'simple.cpp', ]) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 37b3e7ac..2507d586 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -30,13 +30,13 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_sensor.h" +#include "libcamera/internal/converter.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" -#include "converter.h" namespace libcamera { @@ -266,7 +266,7 @@ public: std::vector configs_; std::map> formats_; - std::unique_ptr converter_; + std::unique_ptr converter_; std::vector> converterBuffers_; bool useConverter_; std::queue> converterQueue_; @@ -492,7 +492,7 @@ int SimpleCameraData::init() /* Open the converter, if any. */ MediaDevice *converter = pipe->converter(); if (converter) { - converter_ = std::make_unique(converter); + converter_ = ConverterFactory::create(converter); if (!converter_->isValid()) { LOG(SimplePipeline, Warning) << "Failed to create converter, disabling format conversion";