From patchwork Tue Sep 22 13:35:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 9732 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 E1372BF01C for ; Tue, 22 Sep 2020 13:39:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AA1A862FFB; Tue, 22 Sep 2020 15:39:11 +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="izhXpck8"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 95A6A62FD6 for ; Tue, 22 Sep 2020 15:39:10 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 657C62D7; Tue, 22 Sep 2020 15:39:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1600781945; bh=T8nZ7VZ99y4onSlTZCMhmM+WolGbAkpEIB2QFKBr6cg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=izhXpck8/ySfOgMFy6oOahIOxbsmIViCVqiUPJxvzadShcU99Ca9mTpBwzue6COM1 bUOV+c777rfT4y1GE5rsmJaUWro5RjIWMZukEo8K3VoD4dqSCT7VEdzm5vblr7g1D5 2gkeB52L7CuVyklj5Purre5ZvO2g5/n/k28BJl28= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Tue, 22 Sep 2020 22:35:27 +0900 Message-Id: <20200922133537.258098-29-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200922133537.258098-1-paul.elder@ideasonboard.com> References: <20200922133537.258098-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 28/38] libcamera: pipeline, ipa: raspberrypi: Use new data definition 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" Now that we can generate custom functions and data structures with mojo, switch the raspberrypi pipeline handler and IPA to use the custom data structures as defined in the mojom data definition file. Signed-off-by: Paul Elder --- Changes in v2: - rebased on "libcamera: pipeline: ipa: raspberrypi: Rework drop frame signalling" - use newly customized RPi IPA interface --- include/libcamera/ipa/raspberrypi.h | 37 ++-- src/ipa/raspberrypi/raspberrypi.cpp | 152 +++++++--------- .../pipeline/raspberrypi/raspberrypi.cpp | 171 +++++++++--------- 3 files changed, 170 insertions(+), 190 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 4e38d009..3357bf61 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -24,22 +24,27 @@ enum RPiBufferMask { namespace libcamera { /* List of controls handled by the Raspberry Pi IPA */ -static const ControlInfoMap RPiControls = { - { &controls::AeEnable, ControlInfo(false, true) }, - { &controls::ExposureTime, ControlInfo(0, 999999) }, - { &controls::AnalogueGain, ControlInfo(1.0f, 32.0f) }, - { &controls::AeMeteringMode, ControlInfo(0, static_cast(controls::MeteringModeMax)) }, - { &controls::AeConstraintMode, ControlInfo(0, static_cast(controls::ConstraintModeMax)) }, - { &controls::AeExposureMode, ControlInfo(0, static_cast(controls::ExposureModeMax)) }, - { &controls::ExposureValue, ControlInfo(0.0f, 16.0f) }, - { &controls::AwbEnable, ControlInfo(false, true) }, - { &controls::ColourGains, ControlInfo(0.0f, 32.0f) }, - { &controls::AwbMode, ControlInfo(0, static_cast(controls::AwbModeMax)) }, - { &controls::Brightness, ControlInfo(-1.0f, 1.0f) }, - { &controls::Contrast, ControlInfo(0.0f, 32.0f) }, - { &controls::Saturation, ControlInfo(0.0f, 32.0f) }, - { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) }, - { &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) }, +static ControlInfoMap RPiControls; + +inline void initializeRPiControls() +{ + RPiControls = { + { &controls::AeEnable, ControlInfo(false, true) }, + { &controls::ExposureTime, ControlInfo(0, 999999) }, + { &controls::AnalogueGain, ControlInfo(1.0f, 32.0f) }, + { &controls::AeMeteringMode, ControlInfo(0, static_cast(controls::MeteringModeMax)) }, + { &controls::AeConstraintMode, ControlInfo(0, static_cast(controls::ConstraintModeMax)) }, + { &controls::AeExposureMode, ControlInfo(0, static_cast(controls::ExposureModeMax)) }, + { &controls::ExposureValue, ControlInfo(0.0f, 16.0f) }, + { &controls::AwbEnable, ControlInfo(false, true) }, + { &controls::ColourGains, ControlInfo(0.0f, 32.0f) }, + { &controls::AwbMode, ControlInfo(0, static_cast(controls::AwbModeMax)) }, + { &controls::Brightness, ControlInfo(-1.0f, 1.0f) }, + { &controls::Contrast, ControlInfo(0.0f, 32.0f) }, + { &controls::Saturation, ControlInfo(0.0f, 32.0f) }, + { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) }, + { &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) }, + }; }; } /* namespace libcamera */ diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 0555cc4e..805ced33 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -60,7 +61,7 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPARPI) -class IPARPi : public IPAInterface +class IPARPi : public IPARPiInterface { public: IPARPi() @@ -68,6 +69,7 @@ public: frame_count_(0), check_count_(0), mistrust_count_(0), lsTable_(nullptr) { + initializeRPiControls(); } ~IPARPi() @@ -82,12 +84,14 @@ public: void configure(const CameraSensorInfo &sensorInfo, const std::map &streamConfig, - const std::map &entityControls, - const IPAOperationData &data, - IPAOperationData *response) override; + const std::map &entityControls, + const RPiConfigInput &data, + RPiConfigOutput *response) override; void mapBuffers(const std::vector &buffers) override; void unmapBuffers(const std::vector &ids) override; - void processEvent(const IPAOperationData &event) override; + void signalStatReady(const uint32_t bufferId) override; + void signalQueueRequest(const ControlList &controls) override; + void signalIspPrepare(const RPiIspPreparePayload &data) override; private: void setMode(const CameraSensorInfo &sensorInfo); @@ -141,6 +145,11 @@ private: unsigned int mistrust_count_; /* LS table allocation passed in from the pipeline handler. */ FileDescriptor lsTableHandle_; + /* + * LS table allocation passed in from the pipeline handler, + * in the context of the pipeline handler. + */ + int32_t lsTableHandlePH_; void *lsTable_; }; @@ -190,15 +199,13 @@ void IPARPi::setMode(const CameraSensorInfo &sensorInfo) void IPARPi::configure(const CameraSensorInfo &sensorInfo, [[maybe_unused]] const std::map &streamConfig, - const std::map &entityControls, - const IPAOperationData &ipaConfig, - IPAOperationData *result) + const std::map &entityControls, + const RPiConfigInput &ipaConfig, + RPiConfigOutput *result) { if (entityControls.empty()) return; - result->operation = 0; - unicam_ctrls_ = entityControls.at(0); isp_ctrls_ = entityControls.at(1); /* Setup a metadata ControlList to output metadata. */ @@ -220,11 +227,10 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, helper_->GetDelays(exposureDelay, gainDelay); sensorMetadata = helper_->SensorEmbeddedDataPresent(); - result->data.push_back(gainDelay); - result->data.push_back(exposureDelay); - result->data.push_back(sensorMetadata); - - result->operation |= RPI_IPA_CONFIG_STAGGERED_WRITE; + result->op_ |= RPI_IPA_CONFIG_STAGGERED_WRITE; + result->staggeredWriteResult_.gainDelay_ = gainDelay; + result->staggeredWriteResult_.exposureDelay_ = exposureDelay; + result->staggeredWriteResult_.sensorMetadata_ = sensorMetadata; } /* Re-assemble camera mode using the sensor info. */ @@ -240,18 +246,15 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, */ frame_count_ = 0; check_count_ = 0; - unsigned int drop_frame = 0; + result->op_ |= RPI_IPA_CONFIG_DROP_FRAMES; if (controllerInit_) { - drop_frame = helper_->HideFramesModeSwitch(); + result->dropFrameCount_ = helper_->HideFramesModeSwitch(); mistrust_count_ = helper_->MistrustFramesModeSwitch(); } else { - drop_frame = helper_->HideFramesStartup(); + result->dropFrameCount_ = helper_->HideFramesStartup(); mistrust_count_ = helper_->MistrustFramesStartup(); } - result->data.push_back(drop_frame); - result->operation |= RPI_IPA_CONFIG_DROP_FRAMES; - struct AgcStatus agcStatus; /* These zero values mean not program anything (unless overwritten). */ agcStatus.shutter_time = 0.0; @@ -276,15 +279,15 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, 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; + result->op_ |= RPI_IPA_CONFIG_SENSOR; + result->controls_ = ctrls; } lastMode_ = mode_; /* Store the lens shading table pointer and handle if available. */ - if (ipaConfig.operation & RPI_IPA_CONFIG_LS_TABLE) { + if (ipaConfig.op_ & RPI_IPA_CONFIG_LS_TABLE) { /* Remove any previous table, if there was one. */ if (lsTable_) { munmap(lsTable_, MAX_LS_GRID_SIZE); @@ -292,7 +295,8 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, } /* Map the LS table buffer into user space. */ - lsTableHandle_ = FileDescriptor(ipaConfig.data[0]); + lsTableHandle_ = FileDescriptor(ipaConfig.lsTableHandle_); + lsTableHandlePH_ = ipaConfig.lsTableHandleStatic_; if (lsTableHandle_.isValid()) { lsTable_ = mmap(nullptr, MAX_LS_GRID_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, lsTableHandle_.fd(), 0); @@ -337,56 +341,38 @@ void IPARPi::unmapBuffers(const std::vector &ids) } } -void IPARPi::processEvent(const IPAOperationData &event) +void IPARPi::signalStatReady(const uint32_t bufferId) { - switch (event.operation) { - case RPI_IPA_EVENT_SIGNAL_STAT_READY: { - unsigned int bufferId = event.data[0]; - - if (++check_count_ != frame_count_) /* assert here? */ - LOG(IPARPI, Error) << "WARNING: Prepare/Process mismatch!!!"; - if (frame_count_ > mistrust_count_) - processStats(bufferId); - - reportMetadata(); - - IPAOperationData op; - op.operation = RPI_IPA_ACTION_STATS_METADATA_COMPLETE; - op.data = { bufferId & RPiBufferMask::ID }; - op.controls = { libcameraMetadata_ }; - queueFrameAction.emit(0, op); - break; - } + if (++check_count_ != frame_count_) /* assert here? */ + LOG(IPARPI, Error) << "WARNING: Prepare/Process mismatch!!!"; + if (frame_count_ > mistrust_count_) + processStats(bufferId); - case RPI_IPA_EVENT_SIGNAL_ISP_PREPARE: { - unsigned int embeddedbufferId = event.data[0]; - unsigned int bayerbufferId = event.data[1]; + reportMetadata(); - /* - * At start-up, or after a mode-switch, we may want to - * avoid running the control algos for a few frames in case - * they are "unreliable". - */ - prepareISP(embeddedbufferId); - frame_count_++; - - /* Ready to push the input buffer into the ISP. */ - IPAOperationData op; - op.operation = RPI_IPA_ACTION_RUN_ISP; - op.data = { bayerbufferId & RPiBufferMask::ID }; - queueFrameAction.emit(0, op); - break; - } + statsMetadataComplete.emit(bufferId & RPiBufferMask::ID, libcameraMetadata_); +} - case RPI_IPA_EVENT_QUEUE_REQUEST: { - queueRequest(event.controls[0]); - break; - } +void IPARPi::signalQueueRequest(const ControlList &controls) +{ + queueRequest(controls); +} - default: - LOG(IPARPI, Error) << "Unknown event " << event.operation; - break; - } +void IPARPi::signalIspPrepare(const RPiIspPreparePayload &data) +{ + unsigned int embeddedbufferId = data.embeddedbufferId_; + unsigned int bayerbufferId = data.bayerbufferId_; + + /* + * At start-up, or after a mode-switch, we may want to + * avoid running the control algos for a few frames in case + * they are "unreliable". + */ + prepareISP(embeddedbufferId); + frame_count_++; + + /* Ready to push the input buffer into the ISP. */ + runIsp.emit(bayerbufferId & RPiBufferMask::ID); } void IPARPi::reportMetadata() @@ -489,6 +475,8 @@ void IPARPi::queueRequest(const ControlList &controls) /* Clear the return metadata buffer. */ libcameraMetadata_.clear(); + LOG(IPARPI, Info) << "Request ctrl length: " << controls.size(); + for (auto const &ctrl : controls) { LOG(IPARPI, Info) << "Request ctrl: " << controls::controls.at(ctrl.first)->name() @@ -698,10 +686,7 @@ void IPARPi::queueRequest(const ControlList &controls) void IPARPi::returnEmbeddedBuffer(unsigned int bufferId) { - IPAOperationData op; - op.operation = RPI_IPA_ACTION_EMBEDDED_COMPLETE; - op.data = { bufferId & RPiBufferMask::ID }; - queueFrameAction.emit(0, op); + embeddedComplete.emit(bufferId & RPiBufferMask::ID); } void IPARPi::prepareISP(unsigned int bufferId) @@ -762,12 +747,8 @@ void IPARPi::prepareISP(unsigned int bufferId) if (dpcStatus) applyDPC(dpcStatus, ctrls); - if (!ctrls.empty()) { - IPAOperationData op; - op.operation = RPI_IPA_ACTION_V4L2_SET_ISP; - op.controls.push_back(ctrls); - queueFrameAction.emit(0, op); - } + if (!ctrls.empty()) + setIsp.emit(ctrls); } } @@ -823,10 +804,7 @@ void IPARPi::processStats(unsigned int bufferId) 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); + setStaggered.emit(ctrls); } } @@ -1056,7 +1034,7 @@ void IPARPi::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) .grid_width = w, .grid_stride = w, .grid_height = h, - .dmabuf = lsTableHandle_.fd(), + .dmabuf = lsTableHandlePH_, .ref_transform = 0, .corner_sampled = 1, .gain_format = GAIN_FORMAT_U4P10 @@ -1136,9 +1114,9 @@ const struct IPAModuleInfo ipaModuleInfo = { "raspberrypi", }; -struct ipa_context *ipaCreate() +IPAInterface *ipaCreate() { - return new IPAInterfaceWrapper(std::make_unique()); + return new IPARPi(); } }; /* extern "C" */ diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 50f07182..49e28e0c 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -16,7 +16,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -142,7 +144,11 @@ public: int loadIPA(); int configureIPA(); - void queueFrameAction(unsigned int frame, const IPAOperationData &action); + void statsMetadataComplete(uint32_t bufferId, const ControlList &controls); + void runIsp(uint32_t bufferId); + void embeddedComplete(uint32_t bufferId); + void setIsp(const ControlList &controls); + void setStaggered(const ControlList &controls); /* bufferComplete signal handlers. */ void unicamBufferDequeue(FrameBuffer *buffer); @@ -154,6 +160,8 @@ public: void handleExternalBuffer(FrameBuffer *buffer, RPi::RPiStream *stream); void handleState(); + std::unique_ptr ipa_; + CameraSensor *sensor_; /* Array of Unicam and ISP device streams and associated buffers/streams. */ RPi::RPiDevice unicam_; @@ -356,6 +364,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() PipelineHandlerRPi::PipelineHandlerRPi(CameraManager *manager) : PipelineHandler(manager), unicam_(nullptr), isp_(nullptr) { + initializeRPiControls(); } CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, @@ -974,11 +983,17 @@ void RPiCameraData::frameStarted(uint32_t sequence) int RPiCameraData::loadIPA() { - ipa_ = IPAManager::createIPA(pipe_, 1, 1); + std::unique_ptr ptr = IPAManager::createIPA(pipe_, 1, 1); + ipa_ = std::unique_ptr{static_cast(std::move(ptr).release())}; + if (!ipa_) return -ENOENT; - ipa_->queueFrameAction.connect(this, &RPiCameraData::queueFrameAction); + ipa_->statsMetadataComplete.connect(this, &RPiCameraData::statsMetadataComplete); + ipa_->runIsp.connect(this, &RPiCameraData::runIsp); + ipa_->embeddedComplete.connect(this, &RPiCameraData::embeddedComplete); + ipa_->setIsp.connect(this, &RPiCameraData::setIsp); + ipa_->setStaggered.connect(this, &RPiCameraData::setStaggered); IPASettings settings{ .configurationFile = ipa_->configurationFile(sensor_->model() + ".json") @@ -990,8 +1005,8 @@ int RPiCameraData::loadIPA() int RPiCameraData::configureIPA() { std::map streamConfig; - std::map entityControls; - IPAOperationData ipaConfig = {}; + std::map entityControls; + RPiConfigInput ipaConfig; /* Get the device format to pass to the IPA. */ V4L2DeviceFormat sensorFormat; @@ -1017,8 +1032,9 @@ int RPiCameraData::configureIPA() return -ENOMEM; /* Allow the IPA to mmap the LS table via the file descriptor. */ - ipaConfig.operation = RPI_IPA_CONFIG_LS_TABLE; - ipaConfig.data = { static_cast(lsTable_.fd()) }; + ipaConfig.op_ = RPI_IPA_CONFIG_LS_TABLE; + ipaConfig.lsTableHandle_ = lsTable_; + ipaConfig.lsTableHandleStatic_ = lsTable_.fd(); } CameraSensorInfo sensorInfo = {}; @@ -1029,105 +1045,92 @@ int RPiCameraData::configureIPA() } /* Ready the IPA - it must know about the sensor resolution. */ - IPAOperationData result; + RPiConfigOutput result; ipa_->configure(sensorInfo, streamConfig, entityControls, ipaConfig, &result); - unsigned int resultIdx = 0; - if (result.operation & RPI_IPA_CONFIG_STAGGERED_WRITE) { + if (result.op_ & 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, result.data[resultIdx++] }, - { V4L2_CID_EXPOSURE, result.data[resultIdx++] } }); - sensorMetadata_ = result.data[resultIdx++]; + { { V4L2_CID_ANALOGUE_GAIN, + result.staggeredWriteResult_.gainDelay_ }, + { V4L2_CID_EXPOSURE, + result.staggeredWriteResult_.exposureDelay_ } }); + sensorMetadata_ = result.staggeredWriteResult_.sensorMetadata_; + } + + if (result.op_ & RPI_IPA_CONFIG_SENSOR) { + const ControlList &ctrls = result.controls_; + if (!staggeredCtrl_.set(ctrls)) + LOG(RPI, Error) << "V4L2 staggered set failed"; } - } - if (result.operation & RPI_IPA_CONFIG_SENSOR) { - const ControlList &ctrls = result.controls[0]; - if (!staggeredCtrl_.set(ctrls)) - LOG(RPI, Error) << "V4L2 staggered set failed"; } - if (result.operation & RPI_IPA_CONFIG_DROP_FRAMES) { + if (result.op_ & RPI_IPA_CONFIG_DROP_FRAMES) { /* Configure the number of dropped frames required on startup. */ - dropFrameCount_ = result.data[resultIdx++]; + dropFrameCount_ = result.dropFrameCount_; } return 0; } -void RPiCameraData::queueFrameAction([[maybe_unused]] unsigned int frame, - const IPAOperationData &action) +void RPiCameraData::statsMetadataComplete(uint32_t bufferId, const ControlList &controls) { - /* - * 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: { - const ControlList &controls = action.controls[0]; - if (!staggeredCtrl_.set(controls)) - LOG(RPI, Error) << "V4L2 staggered set failed"; - goto done; - } + if (state_ == State::Stopped) + handleState(); - case RPI_IPA_ACTION_V4L2_SET_ISP: { - ControlList controls = action.controls[0]; - isp_[Isp::Input].dev()->setControls(&controls); - goto done; - } - } + FrameBuffer *buffer = isp_[Isp::Stats].getBuffers().at(bufferId); + + handleStreamBuffer(buffer, &isp_[Isp::Stats]); + /* Fill the Request metadata buffer with what the IPA has provided */ + requestQueue_.front()->metadata() = std::move(controls); + state_ = State::IpaComplete; + handleState(); +} +void RPiCameraData::runIsp(uint32_t bufferId) +{ if (state_ == State::Stopped) - goto done; + handleState(); - /* - * The following actions must not be handled when the pipeline handler - * is in a stopped state. - */ - switch (action.operation) { - case RPI_IPA_ACTION_STATS_METADATA_COMPLETE: { - unsigned int bufferId = action.data[0]; - FrameBuffer *buffer = isp_[Isp::Stats].getBuffers().at(bufferId); - - handleStreamBuffer(buffer, &isp_[Isp::Stats]); - /* Fill the Request metadata buffer with what the IPA has provided */ - requestQueue_.front()->metadata() = std::move(action.controls[0]); - state_ = State::IpaComplete; - break; - } + FrameBuffer *buffer = unicam_[Unicam::Image].getBuffers().at(bufferId); - case RPI_IPA_ACTION_EMBEDDED_COMPLETE: { - unsigned int bufferId = action.data[0]; - FrameBuffer *buffer = unicam_[Unicam::Embedded].getBuffers().at(bufferId); - handleStreamBuffer(buffer, &unicam_[Unicam::Embedded]); - break; - } + LOG(RPI, Debug) << "Input re-queue to ISP, buffer id " << bufferId + << ", timestamp: " << buffer->metadata().timestamp; - case RPI_IPA_ACTION_RUN_ISP: { - unsigned int bufferId = action.data[0]; - FrameBuffer *buffer = unicam_[Unicam::Image].getBuffers().at(bufferId); + isp_[Isp::Input].queueBuffer(buffer); + ispOutputCount_ = 0; + handleState(); +} - LOG(RPI, Debug) << "Input re-queue to ISP, buffer id " << bufferId - << ", timestamp: " << buffer->metadata().timestamp; +void RPiCameraData::embeddedComplete(uint32_t bufferId) +{ + if (state_ == State::Stopped) + handleState(); - isp_[Isp::Input].queueBuffer(buffer); - ispOutputCount_ = 0; - break; - } + FrameBuffer *buffer = unicam_[Unicam::Embedded].getBuffers().at(bufferId); + handleStreamBuffer(buffer, &unicam_[Unicam::Embedded]); + handleState(); +} - default: - LOG(RPI, Error) << "Unknown action " << action.operation; - break; - } +void RPiCameraData::setIsp(const ControlList &controls) +{ + ControlList ctrls = controls; + isp_[Isp::Input].dev()->setControls(&ctrls); + handleState(); +} -done: +void RPiCameraData::setStaggered(const ControlList &controls) +{ + if (!staggeredCtrl_.set(controls)) + LOG(RPI, Error) << "V4L2 staggered set failed"; handleState(); } @@ -1227,10 +1230,7 @@ void RPiCameraData::ispOutputDequeue(FrameBuffer *buffer) * application until after the IPA signals so. */ if (stream == &isp_[Isp::Stats]) { - IPAOperationData op; - op.operation = RPI_IPA_EVENT_SIGNAL_STAT_READY; - op.data = { RPiBufferMask::STATS | static_cast(index) }; - ipa_->processEvent(op); + ipa_->signalStatReady(RPiBufferMask::STATS | static_cast(index)); } else { /* Any other ISP output can be handed back to the application now. */ handleStreamBuffer(buffer, stream); @@ -1403,7 +1403,6 @@ void RPiCameraData::checkRequestCompleted() void RPiCameraData::tryRunPipeline() { FrameBuffer *bayerBuffer, *embeddedBuffer; - IPAOperationData op; /* If any of our request or buffer queues are empty, we cannot proceed. */ if (state_ != State::Idle || requestQueue_.empty() || @@ -1454,9 +1453,7 @@ void RPiCameraData::tryRunPipeline() * queue the ISP output buffer listed in the request to start the HW * pipeline. */ - op.operation = RPI_IPA_EVENT_QUEUE_REQUEST; - op.controls = { request->controls() }; - ipa_->processEvent(op); + ipa_->signalQueueRequest(request->controls()); /* Ready to use the buffers, pop them off the queue. */ bayerQueue_.pop(); @@ -1472,10 +1469,10 @@ void RPiCameraData::tryRunPipeline() << " Bayer buffer id: " << bayerId << " Embedded buffer id: " << embeddedId; - op.operation = RPI_IPA_EVENT_SIGNAL_ISP_PREPARE; - op.data = { RPiBufferMask::EMBEDDED_DATA | embeddedId, - RPiBufferMask::BAYER_DATA | bayerId }; - ipa_->processEvent(op); + RPiIspPreparePayload ispPrepare; + ispPrepare.embeddedbufferId_ = RPiBufferMask::EMBEDDED_DATA | embeddedId; + ispPrepare.bayerbufferId_ = RPiBufferMask::BAYER_DATA | bayerId; + ipa_->signalIspPrepare(ispPrepare); } void RPiCameraData::tryFlushQueues()