From patchwork Thu Aug 5 22:24:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 13239 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 2EA3CC323D for ; Thu, 5 Aug 2021 22:25:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ABE8168892; Fri, 6 Aug 2021 00:25:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CP+Z1Cqj"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5E441687CF for ; Fri, 6 Aug 2021 00:24:58 +0200 (CEST) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0977EE1A for ; Fri, 6 Aug 2021 00:24:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628202298; bh=bxrBrcn4L9y9oMNwRh/dP4+Egnd/J4qfdrqUrnhjIy8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=CP+Z1Cqj135uemp0Ny04gQb6GT4IgImm0cjbnLaJ7dq4CglHWKmRATipek+PqavaK llNFaYIxFqFRTpdGJizozosBJkuTqO3BSib/aUK8Qy51YhFk8MkuRw55PtSbvVIFog nkc1R+U5CbFKwBfEtsEqKoLyjYBNEn5gHbV2Pq6w= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Aug 2021 01:24:34 +0300 Message-Id: <20210805222436.6263-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210805222436.6263-1-laurent.pinchart@ideasonboard.com> References: <20210805222436.6263-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/10] libcamera: pipeline: simple: Move converter to SimpleCameraData 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" To use multiple cameras at the same time, each camera instance will need its own converter. Store the converter in SimpleCameraData, and open it in init(). Signed-off-by: Laurent Pinchart --- src/libcamera/pipeline/simple/simple.cpp | 106 +++++++++++------------ 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index b32369cae701..961262b7803d 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -226,9 +226,14 @@ public: std::vector configs_; std::map formats_; + std::unique_ptr converter_; std::vector> converterBuffers_; bool useConverter_; std::queue> converterQueue_; + +private: + void converterInputDone(FrameBuffer *buffer); + void converterOutputDone(FrameBuffer *buffer); }; class SimpleCameraConfiguration : public CameraConfiguration @@ -277,7 +282,7 @@ public: V4L2VideoDevice *video(const MediaEntity *entity); V4L2Subdevice *subdev(const MediaEntity *entity); - SimpleConverter *converter() { return converter_.get(); } + MediaDevice *converter() { return converter_; } protected: int queueRequestDevice(Camera *camera, Request *request) override; @@ -303,13 +308,11 @@ private: void releasePipeline(SimpleCameraData *data); void bufferReady(FrameBuffer *buffer); - void converterInputDone(FrameBuffer *buffer); - void converterOutputDone(FrameBuffer *buffer); MediaDevice *media_; std::map entities_; - std::unique_ptr converter_; + MediaDevice *converter_; Camera *activeCamera_; }; @@ -417,9 +420,22 @@ SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe, int SimpleCameraData::init() { SimplePipelineHandler *pipe = static_cast(pipe_); - SimpleConverter *converter = pipe->converter(); int ret; + /* Open the converter, if any. */ + MediaDevice *converter = pipe->converter(); + if (converter) { + converter_ = std::make_unique(converter); + if (!converter_->isValid()) { + LOG(SimplePipeline, Warning) + << "Failed to create converter, disabling format conversion"; + converter_.reset(); + } else { + converter_->inputBufferReady.connect(this, &SimpleCameraData::converterInputDone); + converter_->outputBufferReady.connect(this, &SimpleCameraData::converterOutputDone); + } + } + video_ = pipe->video(entities_.back().entity); ASSERT(video_); @@ -471,12 +487,12 @@ int SimpleCameraData::init() config.captureFormat = pixelFormat; config.captureSize = format.size; - if (!converter) { + if (!converter_) { config.outputFormats = { pixelFormat }; config.outputSizes = config.captureSize; } else { - config.outputFormats = converter->formats(pixelFormat); - config.outputSizes = converter->sizes(format.size); + config.outputFormats = converter_->formats(pixelFormat); + config.outputSizes = converter_->sizes(format.size); } configs_.push_back(config); @@ -605,6 +621,20 @@ int SimpleCameraData::setupFormats(V4L2SubdeviceFormat *format, return 0; } +void SimpleCameraData::converterInputDone(FrameBuffer *buffer) +{ + /* Queue the input buffer back for capture. */ + video_->queueBuffer(buffer); +} + +void SimpleCameraData::converterOutputDone(FrameBuffer *buffer) +{ + /* Complete the buffer and the request. */ + Request *request = buffer->request(); + if (pipe_->completeBuffer(request, buffer)) + pipe_->completeRequest(request); +} + /* ----------------------------------------------------------------------------- * Camera Configuration */ @@ -650,11 +680,9 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() } } - /* Adjust the requested streams. */ - SimplePipelineHandler *pipe = static_cast(data_->pipe_); - SimpleConverter *converter = pipe->converter(); - /* + * Adjust the requested streams. + * * Enable usage of the converter when producing multiple streams, as * the video capture device can't capture to multiple buffers. * @@ -700,7 +728,8 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() /* Set the stride, frameSize and bufferCount. */ if (needConversion_) { std::tie(cfg.stride, cfg.frameSize) = - converter->strideAndFrameSize(cfg.pixelFormat, cfg.size); + data_->converter_->strideAndFrameSize(cfg.pixelFormat, + cfg.size); if (cfg.stride == 0) return Invalid; } else { @@ -727,7 +756,7 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() */ SimplePipelineHandler::SimplePipelineHandler(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager), converter_(nullptr) { } @@ -841,7 +870,7 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) inputCfg.stride = captureFormat.planes[0].bpl; inputCfg.bufferCount = kNumInternalBuffers; - return converter_->configure(inputCfg, outputCfgs); + return data->converter_->configure(inputCfg, outputCfgs); } int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, @@ -855,8 +884,8 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, * whether the converter is used or not. */ if (data->useConverter_) - return converter_->exportBuffers(data->streamIndex(stream), - count, buffers); + return data->converter_->exportBuffers(data->streamIndex(stream), + count, buffers); else return data->video_->exportBuffers(count, buffers); } @@ -899,7 +928,7 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL } if (data->useConverter_) { - ret = converter_->start(); + ret = data->converter_->start(); if (ret < 0) { stop(camera); return ret; @@ -921,7 +950,7 @@ void SimplePipelineHandler::stop(Camera *camera) V4L2VideoDevice *video = data->video_; if (data->useConverter_) - converter_->stop(); + data->converter_->stop(); video->streamOff(); video->releaseBuffers(); @@ -1028,7 +1057,6 @@ std::vector SimplePipelineHandler::locateSensors() bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) { const SimplePipelineInfo *info = nullptr; - MediaDevice *converter = nullptr; unsigned int numStreams = 1; for (const SimplePipelineInfo &inf : supportedDevices) { @@ -1045,8 +1073,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) for (const auto &[name, streams] : info->converters) { DeviceMatch converterMatch(name); - converter = acquireMediaDevice(enumerator, converterMatch); - if (converter) { + converter_ = acquireMediaDevice(enumerator, converterMatch); + if (converter_) { numStreams = streams; break; } @@ -1059,19 +1087,6 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) return false; } - /* Open the converter, if any. */ - if (converter) { - converter_ = std::make_unique(converter); - if (!converter_->isValid()) { - LOG(SimplePipeline, Warning) - << "Failed to create converter, disabling format conversion"; - converter_.reset(); - } else { - converter_->inputBufferReady.connect(this, &SimplePipelineHandler::converterInputDone); - converter_->outputBufferReady.connect(this, &SimplePipelineHandler::converterOutputDone); - } - } - /* * Create one camera data instance for each sensor and gather all * entities in all pipelines. @@ -1317,7 +1332,7 @@ void SimplePipelineHandler::bufferReady(FrameBuffer *buffer) return; } - converter_->queueBuffers(buffer, data->converterQueue_.front()); + data->converter_->queueBuffers(buffer, data->converterQueue_.front()); data->converterQueue_.pop(); return; } @@ -1327,25 +1342,6 @@ void SimplePipelineHandler::bufferReady(FrameBuffer *buffer) completeRequest(request); } -void SimplePipelineHandler::converterInputDone(FrameBuffer *buffer) -{ - ASSERT(activeCamera_); - SimpleCameraData *data = cameraData(activeCamera_); - - /* Queue the input buffer back for capture. */ - data->video_->queueBuffer(buffer); -} - -void SimplePipelineHandler::converterOutputDone(FrameBuffer *buffer) -{ - ASSERT(activeCamera_); - - /* Complete the buffer and the request. */ - Request *request = buffer->request(); - if (completeBuffer(request, buffer)) - completeRequest(request); -} - REGISTER_PIPELINE_HANDLER(SimplePipelineHandler) } /* namespace libcamera */