[libcamera-devel] [PATCH 4/8] Add StillCapture stream and imgu1 param buffers
Harvey Yang
chenghaoyang at chromium.org
Thu May 12 12:32:54 CEST 2022
From: Harvey Yang <chenghaoyang at chromium.org>
This patch adds the StillCapture stream and imgu1 param buffers, and the
following patches will enable imgu1 to handle StillCapture stream
specifically, when the imgu0 needs to handle video/preview streams.
Signed-off-by: Harvey Yang <chenghaoyang at 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_ = {};
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 5dd13c41..b635976b 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;
}
@@ -1139,6 +1154,7 @@ int PipelineHandlerIPU3::registerCameras()
&data->outStream_,
&data->vfStream_,
&data->rawStream_,
+ &data->outCaptureStream_,
};
CIO2Device *cio2 = &data->cio2_;
@@ -1314,6 +1330,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)
--
2.36.0.512.ge40c2bad7a-goog
More information about the libcamera-devel
mailing list