From patchwork Sun Jun 28 23:19:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 8491 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 C1795C2E66 for ; Sun, 28 Jun 2020 23:19:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8F4E260B07; Mon, 29 Jun 2020 01:19:52 +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="ZG1fxYi/"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0C1DD60AF7 for ; Mon, 29 Jun 2020 01:19:44 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 887AF734; Mon, 29 Jun 2020 01:19:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1593386383; bh=NgGKREy6lYlJjjhepbY3Yi1cgHIIqnWbSsjsdhpoEGg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZG1fxYi/QyoSdR/jeKgVGgjGGqjHlgsuP1JISN4I7s8vBNx1/fJaS1C0+w8huCiDK rjcz8+miGU2kSrPOt9Bzso879ggLS5zhq1Hf2XPx0v7tP9arhdptnhzR4y8RzTPHJ+ MD6uHUv7gd+vc8qXBOvviGdXUIh2wbTJWB2/gr2w= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Jun 2020 02:19:32 +0300 Message-Id: <20200628231934.29025-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200628231934.29025-1-laurent.pinchart@ideasonboard.com> References: <20200628231934.29025-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 7/9] ipa: raspberrypi: Pass sensor config back from configure() 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" The Raspberry Pi IPA uses a custom frame action, RPI_IPA_ACTION_SET_SENSOR_CONFIG, to send initial sensor configuration to the pipeline handler when the IPA is configured. Replace this ad-hoc mechanism by passing the corresponding data back from the IPA to the pipeline handler through the configure() response. This allows synchronous handling of the response on the pipeline handler side. Signed-off-by: Laurent Pinchart --- include/libcamera/ipa/raspberrypi.h | 3 +- src/ipa/raspberrypi/raspberrypi.cpp | 44 ++++++++------ .../pipeline/raspberrypi/raspberrypi.cpp | 60 +++++++++++-------- 3 files changed, 61 insertions(+), 46 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index c335d0259549..77a7e6d40a2f 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -12,6 +12,8 @@ enum RPiConfigParameters { RPI_IPA_CONFIG_LSTABLE = (1 << 0), + RPI_IPA_CONFIG_STAGGERED_WRITE = (1 << 1), + RPI_IPA_CONFIG_SENSOR = (1 << 2), }; enum RPiOperations { @@ -20,7 +22,6 @@ enum RPiOperations { RPI_IPA_ACTION_STATS_METADATA_COMPLETE, RPI_IPA_ACTION_RUN_ISP, RPI_IPA_ACTION_RUN_ISP_AND_DROP_FRAME, - RPI_IPA_ACTION_SET_SENSOR_CONFIG, RPI_IPA_ACTION_EMBEDDED_COMPLETE, RPI_IPA_EVENT_SIGNAL_STAT_READY, RPI_IPA_EVENT_SIGNAL_ISP_PREPARE, diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index c9f7dea375a5..7da2ffdf84a1 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -93,7 +93,7 @@ private: void reportMetadata(); bool parseEmbeddedData(unsigned int bufferId, struct DeviceStatus &deviceStatus); void processStats(unsigned int bufferId); - void applyAGC(const struct AgcStatus *agcStatus); + void applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls); void applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls); void applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls); void applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls); @@ -195,6 +195,8 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, if (entityControls.empty()) return; + result->operation = 0; + unicam_ctrls_ = entityControls.at(0); isp_ctrls_ = entityControls.at(1); /* Setup a metadata ControlList to output metadata. */ @@ -217,18 +219,16 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, sensorMetadata = helper_->SensorEmbeddedDataPresent(); RPi::CamTransform orientation = helper_->GetOrientation(); - IPAOperationData op; - op.operation = RPI_IPA_ACTION_SET_SENSOR_CONFIG; - op.data.push_back(gainDelay); - op.data.push_back(exposureDelay); - op.data.push_back(sensorMetadata); + result->data.push_back(gainDelay); + result->data.push_back(exposureDelay); + result->data.push_back(sensorMetadata); ControlList ctrls(unicam_ctrls_); ctrls.set(V4L2_CID_HFLIP, (int32_t) !!(orientation & RPi::CamTransform_HFLIP)); ctrls.set(V4L2_CID_VFLIP, (int32_t) !!(orientation & RPi::CamTransform_VFLIP)); - op.controls.push_back(ctrls); + result->controls.push_back(ctrls); - queueFrameAction.emit(0, op); + result->operation |= RPI_IPA_CONFIG_STAGGERED_WRITE; } /* Re-assemble camera mode using the sensor info. */ @@ -273,8 +273,13 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, /* SwitchMode may supply updated exposure/gain values to use. */ metadata.Get("agc.status", agcStatus); - if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) - applyAGC(&agcStatus); + if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) { + ControlList ctrls(unicam_ctrls_); + applyAGC(&agcStatus, ctrls); + result->controls.push_back(ctrls); + + result->operation |= RPI_IPA_CONFIG_SENSOR; + } lastMode_ = mode_; @@ -781,8 +786,15 @@ void IPARPi::processStats(unsigned int bufferId) controller_.Process(statistics, &rpiMetadata_); struct AgcStatus agcStatus; - if (rpiMetadata_.Get("agc.status", agcStatus) == 0) - applyAGC(&agcStatus); + if (rpiMetadata_.Get("agc.status", agcStatus) == 0) { + ControlList ctrls(unicam_ctrls_); + applyAGC(&agcStatus, ctrls); + + IPAOperationData op; + op.operation = RPI_IPA_ACTION_V4L2_SET_STAGGERED; + op.controls.push_back(ctrls); + queueFrameAction.emit(0, op); + } } void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) @@ -808,11 +820,8 @@ void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) static_cast(awbStatus->gain_b * 1000)); } -void IPARPi::applyAGC(const struct AgcStatus *agcStatus) +void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls) { - IPAOperationData op; - op.operation = RPI_IPA_ACTION_V4L2_SET_STAGGERED; - int32_t gain_code = helper_->GainCode(agcStatus->analogue_gain); int32_t exposure_lines = helper_->ExposureLines(agcStatus->shutter_time); @@ -831,11 +840,8 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus) << agcStatus->analogue_gain << " (Gain Code: " << gain_code << ")"; - ControlList ctrls(unicam_ctrls_); ctrls.set(V4L2_CID_ANALOGUE_GAIN, gain_code); ctrls.set(V4L2_CID_EXPOSURE, exposure_lines); - op.controls.push_back(ctrls); - queueFrameAction.emit(0, op); } void IPARPi::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls) diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 903796790f44..60b01484b329 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -806,7 +806,7 @@ int PipelineHandlerRPi::start(Camera *camera) /* * Write the last set of gain and exposure values to the camera before * starting. First check that the staggered ctrl has been initialised - * by the IPA action. + * by configure(). */ ASSERT(data->staggeredCtrl_); data->staggeredCtrl_.reset(); @@ -1152,44 +1152,45 @@ int RPiCameraData::configureIPA() } /* Ready the IPA - it must know about the sensor resolution. */ + IPAOperationData result; + ipa_->configure(sensorInfo, streamConfig, entityControls, ipaConfig, - nullptr); + &result); - return 0; -} - -void RPiCameraData::queueFrameAction(unsigned int frame, const IPAOperationData &action) -{ - /* - * The following actions can be handled when the pipeline handler is in - * a stopped state. - */ - switch (action.operation) { - case RPI_IPA_ACTION_V4L2_SET_STAGGERED: { - ControlList controls = action.controls[0]; - if (!staggeredCtrl_.set(controls)) - LOG(RPI, Error) << "V4L2 staggered set failed"; - goto done; - } - - case RPI_IPA_ACTION_SET_SENSOR_CONFIG: { + if (result.operation & RPI_IPA_CONFIG_STAGGERED_WRITE) { /* * Setup our staggered control writer with the sensor default * gain and exposure delays. */ if (!staggeredCtrl_) { staggeredCtrl_.init(unicam_[Unicam::Image].dev(), - { { V4L2_CID_ANALOGUE_GAIN, action.data[0] }, - { V4L2_CID_EXPOSURE, action.data[1] } }); - sensorMetadata_ = action.data[2]; + { { V4L2_CID_ANALOGUE_GAIN, result.data[0] }, + { V4L2_CID_EXPOSURE, result.data[1] } }); + sensorMetadata_ = result.data[2]; } /* Set the sensor orientation here as well. */ - ControlList controls = action.controls[0]; - unicam_[Unicam::Image].dev()->setControls(&controls); - goto done; + unicam_[Unicam::Image].dev()->setControls(&result.controls[0]); } + if (result.operation & RPI_IPA_CONFIG_SENSOR) { + unsigned int idx = result.operation & RPI_IPA_CONFIG_STAGGERED_WRITE + ? 1 : 0; + const ControlList &ctrls = result.controls[idx]; + if (!staggeredCtrl_.set(ctrls)) + LOG(RPI, Error) << "V4L2 staggered set failed"; + } + + return 0; +} + +void RPiCameraData::queueFrameAction(unsigned int frame, const IPAOperationData &action) +{ + /* + * The following actions can be handled when the pipeline handler is in + * a stopped state. + */ + switch (action.operation) { case RPI_IPA_ACTION_V4L2_SET_ISP: { ControlList controls = action.controls[0]; isp_[Isp::Input].dev()->setControls(&controls); @@ -1205,6 +1206,13 @@ void RPiCameraData::queueFrameAction(unsigned int frame, const IPAOperationData * is in a stopped state. */ switch (action.operation) { + case RPI_IPA_ACTION_V4L2_SET_STAGGERED: { + const ControlList &controls = action.controls[0]; + if (!staggeredCtrl_.set(controls)) + LOG(RPI, Error) << "V4L2 staggered set failed"; + break; + } + case RPI_IPA_ACTION_STATS_METADATA_COMPLETE: { unsigned int bufferId = action.data[0]; FrameBuffer *buffer = isp_[Isp::Stats].getBuffers()->at(bufferId).get();