Message ID | 20220629103018.4025635-5-chenghaoyang@google.com |
---|---|
State | Superseded |
Delegated to: | Umang Jain |
Headers | show |
Series |
|
Related | show |
Hi Harvey, On 6/29/22 16:00, Harvey Yang via libcamera-devel wrote: > From: Harvey Yang <chenghaoyang@chromium.org> > > This patch adds the StillCapture stream and imgu1 param buffers. It might be worth to add that we will ignore statistics for still capture, as they aren't needed for 3A here, right? > The following patches will enable imgu1 to handle StillCapture stream > specifically, when the imgu0 is needed to handle video/preview streams. > > Signed-off-by: Harvey Yang <chenghaoyang@chromium.org> > --- > src/libcamera/pipeline/ipu3/frames.cpp | 23 +++++++++++++++++++++-- > src/libcamera/pipeline/ipu3/frames.h | 8 +++++++- > src/libcamera/pipeline/ipu3/ipu3.cpp | 20 +++++++++++++++++++- > 3 files changed, 47 insertions(+), 4 deletions(-) > > diff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp > index a4c3477c..f9b705a5 100644 > --- a/src/libcamera/pipeline/ipu3/frames.cpp > +++ b/src/libcamera/pipeline/ipu3/frames.cpp > @@ -23,7 +23,8 @@ IPU3Frames::IPU3Frames() > } > > void IPU3Frames::init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers, > - const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers) > + const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers, > + const std::vector<std::unique_ptr<FrameBuffer>> &captureParamBuffers) > { > for (const std::unique_ptr<FrameBuffer> &buffer : paramBuffers) > availableParamBuffers_.push(buffer.get()); > @@ -31,6 +32,9 @@ void IPU3Frames::init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuff > for (const std::unique_ptr<FrameBuffer> &buffer : statBuffers) > availableStatBuffers_.push(buffer.get()); > > + for (const std::unique_ptr<FrameBuffer> &buffer : captureParamBuffers) > + availableCaptureParamBuffers_.push(buffer.get()); > + > frameInfo_.clear(); > } > > @@ -38,6 +42,7 @@ void IPU3Frames::clear() > { > availableParamBuffers_ = {}; alternatively should we rename this to, availableVfParamBuffers_ to mark the distinction? > availableStatBuffers_ = {}; > + availableCaptureParamBuffers_ = {}; > } > > IPU3Frames::Info *IPU3Frames::create(Request *request) > @@ -54,14 +59,22 @@ IPU3Frames::Info *IPU3Frames::create(Request *request) > return nullptr; > } > > + if (availableCaptureParamBuffers_.empty()) { > + LOG(IPU3, Debug) << "Capture parameters buffer underrun"; > + return nullptr; > + } > + > FrameBuffer *paramBuffer = availableParamBuffers_.front(); Ties into the earlier comment, maybe vfParamBuffer ? ... and so on below.. > FrameBuffer *statBuffer = availableStatBuffers_.front(); > + FrameBuffer *captureParamBuffer = availableCaptureParamBuffers_.front(); > > paramBuffer->_d()->setRequest(request); > statBuffer->_d()->setRequest(request); > + captureParamBuffer->_d()->setRequest(request); > > availableParamBuffers_.pop(); > availableStatBuffers_.pop(); > + availableCaptureParamBuffers_.pop(); > > /* \todo Remove the dynamic allocation of Info */ > std::unique_ptr<Info> info = std::make_unique<Info>(); > @@ -71,7 +84,9 @@ IPU3Frames::Info *IPU3Frames::create(Request *request) > info->rawBuffer = nullptr; > info->paramBuffer = paramBuffer; > info->statBuffer = statBuffer; > + info->captureParamBuffer = captureParamBuffer; > info->paramDequeued = false; > + info->captureParamDequeued = false; > info->metadataProcessed = false; > > frameInfo_[id] = std::move(info); > @@ -84,6 +99,7 @@ void IPU3Frames::remove(IPU3Frames::Info *info) > /* Return params and stat buffer for reuse. */ > availableParamBuffers_.push(info->paramBuffer); > availableStatBuffers_.push(info->statBuffer); > + availableCaptureParamBuffers_.push(info->captureParamBuffer); > > /* Delete the extended frame information. */ > frameInfo_.erase(info->id); > @@ -102,6 +118,9 @@ bool IPU3Frames::tryComplete(IPU3Frames::Info *info) > if (!info->paramDequeued) > return false; > > + if (!info->captureParamDequeued) > + return false; > + > remove(info); > > bufferAvailable.emit(); > @@ -131,7 +150,7 @@ IPU3Frames::Info *IPU3Frames::find(FrameBuffer *buffer) > return info; > > if (info->rawBuffer == buffer || info->paramBuffer == buffer || > - info->statBuffer == buffer) > + info->statBuffer == buffer || info->captureParamBuffer == buffer) > return info; > } > > diff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h > index 6e3cb915..8fcb8a14 100644 > --- a/src/libcamera/pipeline/ipu3/frames.h > +++ b/src/libcamera/pipeline/ipu3/frames.h > @@ -36,16 +36,20 @@ public: > FrameBuffer *paramBuffer; > FrameBuffer *statBuffer; > > + FrameBuffer *captureParamBuffer; > + > ControlList effectiveSensorControls; > > bool paramDequeued; > + bool captureParamDequeued; > bool metadataProcessed; > }; > > IPU3Frames(); > > void init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers, > - const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers); > + const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers, > + const std::vector<std::unique_ptr<FrameBuffer>> &captureParamBuffers); > void clear(); > > Info *create(Request *request); > @@ -61,6 +65,8 @@ private: > std::queue<FrameBuffer *> availableParamBuffers_; > std::queue<FrameBuffer *> availableStatBuffers_; > > + std::queue<FrameBuffer *> availableCaptureParamBuffers_; > + > std::map<unsigned int, std::unique_ptr<Info>> frameInfo_; > }; > > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp > index e219f704..a201c5ca 100644 > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp > @@ -70,6 +70,7 @@ public: > Stream outStream_; > Stream vfStream_; > Stream rawStream_; > + Stream outCaptureStream_; If there is a outCaptureStream_ now, should we be dropping outStream_ and associated buffer allocations for outStream_ ? My guess is yes, let's see what happens in subsequent patches. For this one, Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > > Rectangle cropRegion_; > bool supportsFlips_; > @@ -696,6 +697,8 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream, > return imgu0_.viewfinder_->exportBuffers(count, buffers); > else if (stream == &data->rawStream_) > return data->cio2_.exportBuffers(count, buffers); > + else if (stream == &data->outCaptureStream_) > + return imgu1_.output_->exportBuffers(count, buffers); > > return -EINVAL; > } > @@ -718,11 +721,17 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) > data->outStream_.configuration().bufferCount, > data->vfStream_.configuration().bufferCount, > data->rawStream_.configuration().bufferCount, > + data->outCaptureStream_.configuration().bufferCount, > }); > > ret = imgu0_.allocateBuffers(bufferCount); > if (ret < 0) > return ret; > + ret = imgu1_.allocateBuffers(bufferCount); > + if (ret < 0) { > + imgu0_.freeBuffers(); > + return ret; > + } > > /* Map buffers to the IPA. */ > unsigned int ipaBufferId = 1; > @@ -737,9 +746,14 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) > ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); > } > > + for (const std::unique_ptr<FrameBuffer> &buffer : imgu1_.paramBuffers_) { > + buffer->setCookie(ipaBufferId++); > + ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); > + } > + > data->ipa_->mapBuffers(ipaBuffers_); > > - data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_); > + data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_, imgu1_.paramBuffers_); > data->frameInfos_.bufferAvailable.connect( > data, &IPU3CameraData::queuePendingRequests); > > @@ -760,6 +774,7 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) > ipaBuffers_.clear(); > > imgu0_.freeBuffers(); > + imgu1_.freeBuffers(); > > return 0; > } > @@ -1143,6 +1158,7 @@ int PipelineHandlerIPU3::registerCameras() > &data->outStream_, > &data->vfStream_, > &data->rawStream_, > + &data->outCaptureStream_, > }; > CIO2Device *cio2 = &data->cio2_; > > @@ -1318,6 +1334,8 @@ void IPU3CameraData::paramsBufferReady(unsigned int id) > imgu0_->param_->queueBuffer(info->paramBuffer); > imgu0_->stat_->queueBuffer(info->statBuffer); > imgu0_->input_->queueBuffer(info->rawBuffer); > + > + info->captureParamDequeued = true; > } > > void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)
Hi Umang, On Wed, Jul 27, 2022 at 4:41 PM Umang Jain <umang.jain@ideasonboard.com> wrote: > Hi Harvey, > > On 6/29/22 16:00, Harvey Yang via libcamera-devel wrote: > > From: Harvey Yang <chenghaoyang@chromium.org> > > > > This patch adds the StillCapture stream and imgu1 param buffers. > > > It might be worth to add that we will ignore statistics for still > capture, as they aren't needed for 3A here, right? > > Exactly, thanks! > > The following patches will enable imgu1 to handle StillCapture stream > > specifically, when the imgu0 is needed to handle video/preview streams. > > > > Signed-off-by: Harvey Yang <chenghaoyang@chromium.org> > > --- > > src/libcamera/pipeline/ipu3/frames.cpp | 23 +++++++++++++++++++++-- > > src/libcamera/pipeline/ipu3/frames.h | 8 +++++++- > > src/libcamera/pipeline/ipu3/ipu3.cpp | 20 +++++++++++++++++++- > > 3 files changed, 47 insertions(+), 4 deletions(-) > > > > diff --git a/src/libcamera/pipeline/ipu3/frames.cpp > b/src/libcamera/pipeline/ipu3/frames.cpp > > index a4c3477c..f9b705a5 100644 > > --- a/src/libcamera/pipeline/ipu3/frames.cpp > > +++ b/src/libcamera/pipeline/ipu3/frames.cpp > > @@ -23,7 +23,8 @@ IPU3Frames::IPU3Frames() > > } > > > > void IPU3Frames::init(const std::vector<std::unique_ptr<FrameBuffer>> > ¶mBuffers, > > - const std::vector<std::unique_ptr<FrameBuffer>> > &statBuffers) > > + const std::vector<std::unique_ptr<FrameBuffer>> > &statBuffers, > > + const std::vector<std::unique_ptr<FrameBuffer>> > &captureParamBuffers) > > { > > for (const std::unique_ptr<FrameBuffer> &buffer : paramBuffers) > > availableParamBuffers_.push(buffer.get()); > > @@ -31,6 +32,9 @@ void IPU3Frames::init(const > std::vector<std::unique_ptr<FrameBuffer>> ¶mBuff > > for (const std::unique_ptr<FrameBuffer> &buffer : statBuffers) > > availableStatBuffers_.push(buffer.get()); > > > > + for (const std::unique_ptr<FrameBuffer> &buffer : > captureParamBuffers) > > + availableCaptureParamBuffers_.push(buffer.get()); > > + > > frameInfo_.clear(); > > } > > > > @@ -38,6 +42,7 @@ void IPU3Frames::clear() > > { > > availableParamBuffers_ = {}; > > > alternatively should we rename this to, availableVfParamBuffers_ to mark > the distinction? > > I'm not sure if "availableVfParamBuffers_" describes it better though... It'll be used as ImgU0's param buffers, and ImgU0 is used for video streams. It might not always be used for preview, especially when a JPEG stream is not requested. IIUC "viewfinder" is mostly describing the "preview" stream, right? (Although Han-lin told me that the viewfinder node in ImgU might be more powerful, in terms of field of view, than the output node, which confuses me a lot) > > availableStatBuffers_ = {}; > > + availableCaptureParamBuffers_ = {}; > > } > > > > IPU3Frames::Info *IPU3Frames::create(Request *request) > > @@ -54,14 +59,22 @@ IPU3Frames::Info *IPU3Frames::create(Request > *request) > > return nullptr; > > } > > > > + if (availableCaptureParamBuffers_.empty()) { > > + LOG(IPU3, Debug) << "Capture parameters buffer underrun"; > > + return nullptr; > > + } > > + > > FrameBuffer *paramBuffer = availableParamBuffers_.front(); > > > Ties into the earlier comment, maybe vfParamBuffer ? ... and so on below.. > > ditto > > FrameBuffer *statBuffer = availableStatBuffers_.front(); > > + FrameBuffer *captureParamBuffer = > availableCaptureParamBuffers_.front(); > > > > paramBuffer->_d()->setRequest(request); > > statBuffer->_d()->setRequest(request); > > + captureParamBuffer->_d()->setRequest(request); > > > > availableParamBuffers_.pop(); > > availableStatBuffers_.pop(); > > + availableCaptureParamBuffers_.pop(); > > > > /* \todo Remove the dynamic allocation of Info */ > > std::unique_ptr<Info> info = std::make_unique<Info>(); > > @@ -71,7 +84,9 @@ IPU3Frames::Info *IPU3Frames::create(Request *request) > > info->rawBuffer = nullptr; > > info->paramBuffer = paramBuffer; > > info->statBuffer = statBuffer; > > + info->captureParamBuffer = captureParamBuffer; > > info->paramDequeued = false; > > + info->captureParamDequeued = false; > > info->metadataProcessed = false; > > > > frameInfo_[id] = std::move(info); > > @@ -84,6 +99,7 @@ void IPU3Frames::remove(IPU3Frames::Info *info) > > /* Return params and stat buffer for reuse. */ > > availableParamBuffers_.push(info->paramBuffer); > > availableStatBuffers_.push(info->statBuffer); > > + availableCaptureParamBuffers_.push(info->captureParamBuffer); > > > > /* Delete the extended frame information. */ > > frameInfo_.erase(info->id); > > @@ -102,6 +118,9 @@ bool IPU3Frames::tryComplete(IPU3Frames::Info *info) > > if (!info->paramDequeued) > > return false; > > > > + if (!info->captureParamDequeued) > > + return false; > > + > > remove(info); > > > > bufferAvailable.emit(); > > @@ -131,7 +150,7 @@ IPU3Frames::Info *IPU3Frames::find(FrameBuffer > *buffer) > > return info; > > > > if (info->rawBuffer == buffer || info->paramBuffer == > buffer || > > - info->statBuffer == buffer) > > + info->statBuffer == buffer || info->captureParamBuffer > == buffer) > > return info; > > } > > > > diff --git a/src/libcamera/pipeline/ipu3/frames.h > b/src/libcamera/pipeline/ipu3/frames.h > > index 6e3cb915..8fcb8a14 100644 > > --- a/src/libcamera/pipeline/ipu3/frames.h > > +++ b/src/libcamera/pipeline/ipu3/frames.h > > @@ -36,16 +36,20 @@ public: > > FrameBuffer *paramBuffer; > > FrameBuffer *statBuffer; > > > > + FrameBuffer *captureParamBuffer; > > + > > ControlList effectiveSensorControls; > > > > bool paramDequeued; > > + bool captureParamDequeued; > > bool metadataProcessed; > > }; > > > > IPU3Frames(); > > > > void init(const std::vector<std::unique_ptr<FrameBuffer>> > ¶mBuffers, > > - const std::vector<std::unique_ptr<FrameBuffer>> > &statBuffers); > > + const std::vector<std::unique_ptr<FrameBuffer>> > &statBuffers, > > + const std::vector<std::unique_ptr<FrameBuffer>> > &captureParamBuffers); > > void clear(); > > > > Info *create(Request *request); > > @@ -61,6 +65,8 @@ private: > > std::queue<FrameBuffer *> availableParamBuffers_; > > std::queue<FrameBuffer *> availableStatBuffers_; > > > > + std::queue<FrameBuffer *> availableCaptureParamBuffers_; > > + > > std::map<unsigned int, std::unique_ptr<Info>> frameInfo_; > > }; > > > > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp > b/src/libcamera/pipeline/ipu3/ipu3.cpp > > index e219f704..a201c5ca 100644 > > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp > > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp > > @@ -70,6 +70,7 @@ public: > > Stream outStream_; > > Stream vfStream_; > > Stream rawStream_; > > + Stream outCaptureStream_; > > > If there is a outCaptureStream_ now, should we be dropping outStream_ > and associated buffer allocations for outStream_ ? > > My guess is yes, let's see what happens in subsequent patches. > > For this one, > > So |outStream_| is still in use with |outCaptureStream_| available, as it's still the main output stream of ImgU0 (ipu3.cpp: line 380). Unless you're suggesting that when a JPEG stream is requested, there's at most one video stream requested (which is likely used as the Preview), and it should be supported by ImgU0's viewfinder node. However, The Android LIMIT-level guaranteed configuration already has a use-case that supports two YUV/video streams and a JPEG stream [1], not to mention the FULL-level. [1]: https://developer.android.com/reference/android/hardware/camera2/CameraDevice#regular-capture > Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > > > > > Rectangle cropRegion_; > > bool supportsFlips_; > > @@ -696,6 +697,8 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera > *camera, Stream *stream, > > return imgu0_.viewfinder_->exportBuffers(count, buffers); > > else if (stream == &data->rawStream_) > > return data->cio2_.exportBuffers(count, buffers); > > + else if (stream == &data->outCaptureStream_) > > + return imgu1_.output_->exportBuffers(count, buffers); > > > > return -EINVAL; > > } > > @@ -718,11 +721,17 @@ int PipelineHandlerIPU3::allocateBuffers(Camera > *camera) > > data->outStream_.configuration().bufferCount, > > data->vfStream_.configuration().bufferCount, > > data->rawStream_.configuration().bufferCount, > > + data->outCaptureStream_.configuration().bufferCount, > > }); > > > > ret = imgu0_.allocateBuffers(bufferCount); > > if (ret < 0) > > return ret; > > + ret = imgu1_.allocateBuffers(bufferCount); > > + if (ret < 0) { > > + imgu0_.freeBuffers(); > > + return ret; > > + } > > > > /* Map buffers to the IPA. */ > > unsigned int ipaBufferId = 1; > > @@ -737,9 +746,14 @@ int PipelineHandlerIPU3::allocateBuffers(Camera > *camera) > > ipaBuffers_.emplace_back(buffer->cookie(), > buffer->planes()); > > } > > > > + for (const std::unique_ptr<FrameBuffer> &buffer : > imgu1_.paramBuffers_) { > > + buffer->setCookie(ipaBufferId++); > > + ipaBuffers_.emplace_back(buffer->cookie(), > buffer->planes()); > > + } > > + > > data->ipa_->mapBuffers(ipaBuffers_); > > > > - data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_); > > + data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_, > imgu1_.paramBuffers_); > > data->frameInfos_.bufferAvailable.connect( > > data, &IPU3CameraData::queuePendingRequests); > > > > @@ -760,6 +774,7 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) > > ipaBuffers_.clear(); > > > > imgu0_.freeBuffers(); > > + imgu1_.freeBuffers(); > > > > return 0; > > } > > @@ -1143,6 +1158,7 @@ int PipelineHandlerIPU3::registerCameras() > > &data->outStream_, > > &data->vfStream_, > > &data->rawStream_, > > + &data->outCaptureStream_, > > }; > > CIO2Device *cio2 = &data->cio2_; > > > > @@ -1318,6 +1334,8 @@ void IPU3CameraData::paramsBufferReady(unsigned > int id) > > imgu0_->param_->queueBuffer(info->paramBuffer); > > imgu0_->stat_->queueBuffer(info->statBuffer); > > imgu0_->input_->queueBuffer(info->rawBuffer); > > + > > + info->captureParamDequeued = true; > > } > > > > void IPU3CameraData::metadataReady(unsigned int id, const ControlList > &metadata) >
diff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp index a4c3477c..f9b705a5 100644 --- a/src/libcamera/pipeline/ipu3/frames.cpp +++ b/src/libcamera/pipeline/ipu3/frames.cpp @@ -23,7 +23,8 @@ IPU3Frames::IPU3Frames() } void IPU3Frames::init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers, - const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers) + const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers, + const std::vector<std::unique_ptr<FrameBuffer>> &captureParamBuffers) { for (const std::unique_ptr<FrameBuffer> &buffer : paramBuffers) availableParamBuffers_.push(buffer.get()); @@ -31,6 +32,9 @@ void IPU3Frames::init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuff for (const std::unique_ptr<FrameBuffer> &buffer : statBuffers) availableStatBuffers_.push(buffer.get()); + for (const std::unique_ptr<FrameBuffer> &buffer : captureParamBuffers) + availableCaptureParamBuffers_.push(buffer.get()); + frameInfo_.clear(); } @@ -38,6 +42,7 @@ void IPU3Frames::clear() { availableParamBuffers_ = {}; availableStatBuffers_ = {}; + availableCaptureParamBuffers_ = {}; } IPU3Frames::Info *IPU3Frames::create(Request *request) @@ -54,14 +59,22 @@ IPU3Frames::Info *IPU3Frames::create(Request *request) return nullptr; } + if (availableCaptureParamBuffers_.empty()) { + LOG(IPU3, Debug) << "Capture parameters buffer underrun"; + return nullptr; + } + FrameBuffer *paramBuffer = availableParamBuffers_.front(); FrameBuffer *statBuffer = availableStatBuffers_.front(); + FrameBuffer *captureParamBuffer = availableCaptureParamBuffers_.front(); paramBuffer->_d()->setRequest(request); statBuffer->_d()->setRequest(request); + captureParamBuffer->_d()->setRequest(request); availableParamBuffers_.pop(); availableStatBuffers_.pop(); + availableCaptureParamBuffers_.pop(); /* \todo Remove the dynamic allocation of Info */ std::unique_ptr<Info> info = std::make_unique<Info>(); @@ -71,7 +84,9 @@ IPU3Frames::Info *IPU3Frames::create(Request *request) info->rawBuffer = nullptr; info->paramBuffer = paramBuffer; info->statBuffer = statBuffer; + info->captureParamBuffer = captureParamBuffer; info->paramDequeued = false; + info->captureParamDequeued = false; info->metadataProcessed = false; frameInfo_[id] = std::move(info); @@ -84,6 +99,7 @@ void IPU3Frames::remove(IPU3Frames::Info *info) /* Return params and stat buffer for reuse. */ availableParamBuffers_.push(info->paramBuffer); availableStatBuffers_.push(info->statBuffer); + availableCaptureParamBuffers_.push(info->captureParamBuffer); /* Delete the extended frame information. */ frameInfo_.erase(info->id); @@ -102,6 +118,9 @@ bool IPU3Frames::tryComplete(IPU3Frames::Info *info) if (!info->paramDequeued) return false; + if (!info->captureParamDequeued) + return false; + remove(info); bufferAvailable.emit(); @@ -131,7 +150,7 @@ IPU3Frames::Info *IPU3Frames::find(FrameBuffer *buffer) return info; if (info->rawBuffer == buffer || info->paramBuffer == buffer || - info->statBuffer == buffer) + info->statBuffer == buffer || info->captureParamBuffer == buffer) return info; } diff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h index 6e3cb915..8fcb8a14 100644 --- a/src/libcamera/pipeline/ipu3/frames.h +++ b/src/libcamera/pipeline/ipu3/frames.h @@ -36,16 +36,20 @@ public: FrameBuffer *paramBuffer; FrameBuffer *statBuffer; + FrameBuffer *captureParamBuffer; + ControlList effectiveSensorControls; bool paramDequeued; + bool captureParamDequeued; bool metadataProcessed; }; IPU3Frames(); void init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers, - const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers); + const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers, + const std::vector<std::unique_ptr<FrameBuffer>> &captureParamBuffers); void clear(); Info *create(Request *request); @@ -61,6 +65,8 @@ private: std::queue<FrameBuffer *> availableParamBuffers_; std::queue<FrameBuffer *> availableStatBuffers_; + std::queue<FrameBuffer *> availableCaptureParamBuffers_; + std::map<unsigned int, std::unique_ptr<Info>> frameInfo_; }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index e219f704..a201c5ca 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -70,6 +70,7 @@ public: Stream outStream_; Stream vfStream_; Stream rawStream_; + Stream outCaptureStream_; Rectangle cropRegion_; bool supportsFlips_; @@ -696,6 +697,8 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream, return imgu0_.viewfinder_->exportBuffers(count, buffers); else if (stream == &data->rawStream_) return data->cio2_.exportBuffers(count, buffers); + else if (stream == &data->outCaptureStream_) + return imgu1_.output_->exportBuffers(count, buffers); return -EINVAL; } @@ -718,11 +721,17 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) data->outStream_.configuration().bufferCount, data->vfStream_.configuration().bufferCount, data->rawStream_.configuration().bufferCount, + data->outCaptureStream_.configuration().bufferCount, }); ret = imgu0_.allocateBuffers(bufferCount); if (ret < 0) return ret; + ret = imgu1_.allocateBuffers(bufferCount); + if (ret < 0) { + imgu0_.freeBuffers(); + return ret; + } /* Map buffers to the IPA. */ unsigned int ipaBufferId = 1; @@ -737,9 +746,14 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); } + for (const std::unique_ptr<FrameBuffer> &buffer : imgu1_.paramBuffers_) { + buffer->setCookie(ipaBufferId++); + ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); + } + data->ipa_->mapBuffers(ipaBuffers_); - data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_); + data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_, imgu1_.paramBuffers_); data->frameInfos_.bufferAvailable.connect( data, &IPU3CameraData::queuePendingRequests); @@ -760,6 +774,7 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) ipaBuffers_.clear(); imgu0_.freeBuffers(); + imgu1_.freeBuffers(); return 0; } @@ -1143,6 +1158,7 @@ int PipelineHandlerIPU3::registerCameras() &data->outStream_, &data->vfStream_, &data->rawStream_, + &data->outCaptureStream_, }; CIO2Device *cio2 = &data->cio2_; @@ -1318,6 +1334,8 @@ void IPU3CameraData::paramsBufferReady(unsigned int id) imgu0_->param_->queueBuffer(info->paramBuffer); imgu0_->stat_->queueBuffer(info->statBuffer); imgu0_->input_->queueBuffer(info->rawBuffer); + + info->captureParamDequeued = true; } void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)