Message ID | 20211126050810.1871781-4-hiroh@chromium.org |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi Hiro On Fri, Nov 26, 2021 at 02:08:10PM +0900, Hirokazu Honda wrote: > This introduces a way to set controls immediately for a capture > in ipu3 pipeline handler. It enables to apply a test pattern mode > per frame. > > Signed-off-by: Hirokazu Honda <hiroh@chromium.org> > Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Sorry, too soon As commented on the previous version, Requests stored processingRequests_ at the time stop() is called should be completed before the ones in pendingRequests_ > Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> > --- > src/libcamera/pipeline/ipu3/ipu3.cpp | 55 +++++++++++++++++++++++++++- > 1 file changed, 53 insertions(+), 2 deletions(-) > > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp > index 25490dcf..31f5f9dd 100644 > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp > @@ -59,6 +59,7 @@ public: > void statBufferReady(FrameBuffer *buffer); > void queuePendingRequests(); > void cancelPendingRequests(); > + void frameStart(uint32_t sequence); > > CIO2Device cio2_; > ImgUDevice *imgu_; > @@ -76,7 +77,10 @@ public: > > std::unique_ptr<ipa::ipu3::IPAProxyIPU3> ipa_; > > + /* Requests before queueing cio2 device. */ > std::queue<Request *> pendingRequests_; > + /* Requests queued in cio2 device and before passing imgu device. */ > + std::queue<Request *> processingRequests_; > > ControlInfoMap ipaControls_; > > @@ -823,6 +827,8 @@ void IPU3CameraData::cancelPendingRequests() > pipe()->completeRequest(request); > pendingRequests_.pop(); > } > + > + processingRequests_ = {}; > } > > void IPU3CameraData::queuePendingRequests() > @@ -853,6 +859,8 @@ void IPU3CameraData::queuePendingRequests() > > info->rawBuffer = rawBuffer; > > + processingRequests_.push(request); > + > ipa::ipu3::IPU3Event ev; > ev.op = ipa::ipu3::EventProcessControls; > ev.frame = info->id; > @@ -1121,8 +1129,8 @@ int PipelineHandlerIPU3::registerCameras() > data->delayedCtrls_ = > std::make_unique<DelayedControls>(cio2->sensor()->device(), > params); > - data->cio2_.frameStart().connect(data->delayedCtrls_.get(), > - &DelayedControls::applyControls); > + data->cio2_.frameStart().connect(data.get(), > + &IPU3CameraData::frameStart); > > /* Convert the sensor rotation to a transformation */ > int32_t rotation = 0; > @@ -1414,6 +1422,49 @@ void IPU3CameraData::statBufferReady(FrameBuffer *buffer) > ipa_->processEvent(ev); > } > > +void IPU3CameraData::frameStart(uint32_t sequence) > +{ > + /* > + * Handle the start of frame exposure signal. > + * > + * Inspect the list of pending requests waiting for a RAW frame to be > + * produced and apply controls for the 'next' one. > + * > + * Some controls need to be applied immediately, such as the > + * TestPatternMode one. Other controls are handled through the delayed > + * controls class. > + */ I would have made of this a block before the function declaration > + > + delayedCtrls_->applyControls(sequence); > + > + if (!processingRequests_.empty()) { Return early to reduce indentation if (processingRequests_.empty()) return; > + /* Handle controls which are to be set ready for the next frame to start. */ /* Handle controls which have to be applied to the next frame. */ > + Request *request = processingRequests_.front(); > + processingRequests_.pop(); > + > + /* Assumes applying the test pattern mode affects immediately. */ s/affect/takes effect > + if (!request->controls().contains(controls::draft::TestPatternMode)) > + return; Blank line > + const int32_t testPatternMode = request->controls().get( > + controls::draft::TestPatternMode); > + > + LOG(IPU3, Debug) << "Apply test pattern mode: " > + << testPatternMode; I would actually move this to CameraSensor but ok > + > + int ret = cio2_.sensor()->setTestPatternMode( > + static_cast<controls::draft::TestPatternModeEnum>( > + testPatternMode)); > + if (ret) { > + LOG(IPU3, Error) << "Failed to set test pattern mode: " > + << ret; > + return; > + } > + > + request->metadata().set(controls::draft::TestPatternMode, > + testPatternMode); Nicer! Thanks j > + } > +} > + > REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3) > > } /* namespace libcamera */ > -- > 2.34.0.rc2.393.gf8c9666880-goog >
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 25490dcf..31f5f9dd 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -59,6 +59,7 @@ public: void statBufferReady(FrameBuffer *buffer); void queuePendingRequests(); void cancelPendingRequests(); + void frameStart(uint32_t sequence); CIO2Device cio2_; ImgUDevice *imgu_; @@ -76,7 +77,10 @@ public: std::unique_ptr<ipa::ipu3::IPAProxyIPU3> ipa_; + /* Requests before queueing cio2 device. */ std::queue<Request *> pendingRequests_; + /* Requests queued in cio2 device and before passing imgu device. */ + std::queue<Request *> processingRequests_; ControlInfoMap ipaControls_; @@ -823,6 +827,8 @@ void IPU3CameraData::cancelPendingRequests() pipe()->completeRequest(request); pendingRequests_.pop(); } + + processingRequests_ = {}; } void IPU3CameraData::queuePendingRequests() @@ -853,6 +859,8 @@ void IPU3CameraData::queuePendingRequests() info->rawBuffer = rawBuffer; + processingRequests_.push(request); + ipa::ipu3::IPU3Event ev; ev.op = ipa::ipu3::EventProcessControls; ev.frame = info->id; @@ -1121,8 +1129,8 @@ int PipelineHandlerIPU3::registerCameras() data->delayedCtrls_ = std::make_unique<DelayedControls>(cio2->sensor()->device(), params); - data->cio2_.frameStart().connect(data->delayedCtrls_.get(), - &DelayedControls::applyControls); + data->cio2_.frameStart().connect(data.get(), + &IPU3CameraData::frameStart); /* Convert the sensor rotation to a transformation */ int32_t rotation = 0; @@ -1414,6 +1422,49 @@ void IPU3CameraData::statBufferReady(FrameBuffer *buffer) ipa_->processEvent(ev); } +void IPU3CameraData::frameStart(uint32_t sequence) +{ + /* + * Handle the start of frame exposure signal. + * + * Inspect the list of pending requests waiting for a RAW frame to be + * produced and apply controls for the 'next' one. + * + * Some controls need to be applied immediately, such as the + * TestPatternMode one. Other controls are handled through the delayed + * controls class. + */ + + delayedCtrls_->applyControls(sequence); + + if (!processingRequests_.empty()) { + /* Handle controls which are to be set ready for the next frame to start. */ + Request *request = processingRequests_.front(); + processingRequests_.pop(); + + /* Assumes applying the test pattern mode affects immediately. */ + if (!request->controls().contains(controls::draft::TestPatternMode)) + return; + const int32_t testPatternMode = request->controls().get( + controls::draft::TestPatternMode); + + LOG(IPU3, Debug) << "Apply test pattern mode: " + << testPatternMode; + + int ret = cio2_.sensor()->setTestPatternMode( + static_cast<controls::draft::TestPatternModeEnum>( + testPatternMode)); + if (ret) { + LOG(IPU3, Error) << "Failed to set test pattern mode: " + << ret; + return; + } + + request->metadata().set(controls::draft::TestPatternMode, + testPatternMode); + } +} + REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3) } /* namespace libcamera */