[libcamera-devel] [PATCH v4 9/9] ipu3: Fixes frame delay
Harvey Yang
chenghaoyang at chromium.org
Tue Aug 2 12:29:43 CEST 2022
Like the shipped ipu3 HAL [1], handle the frame delay with one extra input,
needed for the first frame and StillCapture's non-sequential frame
requests.
[1]:
https://source.corp.google.com/chromeos_public/src/platform/camera/hal/intel/ipu3/psl/ipu3/ImguUnit.cpp;l=773
Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
---
src/libcamera/pipeline/ipu3/ipu3.cpp | 73 +++++++++++++++++++++++-----
1 file changed, 62 insertions(+), 11 deletions(-)
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index f8101c6c..36ca47c2 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -90,6 +90,9 @@ public:
ControlInfoMap ipaControls_;
+ bool firstRequest_ = true;
+ int lastCaptureRequestSeq_ = -1;
+
private:
void metadataReady(unsigned int id, const ControlList &metadata);
void paramsBufferReady(unsigned int id);
@@ -884,6 +887,9 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis
CIO2Device *cio2 = &data->cio2_;
int ret;
+ data->firstRequest_ = true;
+ data->lastCaptureRequestSeq_ = -1;
+
imgu0_.input_->bufferReady.connect(data,
&IPU3CameraData::tryReturnBuffer);
imgu0_.output_->bufferReady.connect(data,
@@ -1422,6 +1428,11 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)
if (!info)
return;
+ int yuvCount = firstRequest_ ? 2 : 1;
+ int stillCount = firstRequest_ || (lastCaptureRequestSeq_ + 1) != static_cast<int>(info->request->sequence()) ? 2 : 1;
+
+ firstRequest_ = false;
+
bool hasYuv = false;
bool hasCapture = false;
/* Queue all buffers from the request aimed for the ImgU. */
@@ -1431,33 +1442,53 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)
if (stream == &outStream_) {
hasYuv = true;
- imgu0_->output_->queueBuffer(outbuffer);
+
+ for (int i = 0; i < yuvCount; ++i) {
+ bufferReturnCounters[outbuffer] += 1;
+ imgu0_->output_->queueBuffer(outbuffer);
+ }
} else if (stream == &vfStream_) {
hasYuv = true;
- imgu0_->viewfinder_->queueBuffer(outbuffer);
+
+ for (int i = 0; i < yuvCount; ++i) {
+ bufferReturnCounters[outbuffer] += 1;
+ imgu0_->viewfinder_->queueBuffer(outbuffer);
+ }
} else if (stream == &outCaptureStream_) {
hasCapture = true;
- imgu1_->output_->queueBuffer(outbuffer);
+ for (int i = 0; i < stillCount; ++i) {
+ bufferReturnCounters[outbuffer] += 1;
+ imgu1_->output_->queueBuffer(outbuffer);
+ }
}
}
if (hasYuv) {
- bufferReturnCounters[info->rawBuffer] += 1;
-
- imgu0_->param_->queueBuffer(info->paramBuffer);
- imgu0_->stat_->queueBuffer(info->statBuffer);
- imgu0_->input_->queueBuffer(info->rawBuffer);
+ for (int i = 0; i < yuvCount; ++i) {
+ bufferReturnCounters[info->paramBuffer] += 1;
+ bufferReturnCounters[info->statBuffer] += 1;
+ bufferReturnCounters[info->rawBuffer] += 1;
+
+ imgu0_->param_->queueBuffer(info->paramBuffer);
+ imgu0_->stat_->queueBuffer(info->statBuffer);
+ imgu0_->input_->queueBuffer(info->rawBuffer);
+ }
} else {
info->paramDequeued = true;
info->metadataProcessed = true;
}
if (hasCapture) {
- bufferReturnCounters[info->rawBuffer] += 1;
+ lastCaptureRequestSeq_ = info->request->sequence();
- imgu1_->param_->queueBuffer(info->captureParamBuffer);
- imgu1_->input_->queueBuffer(info->rawBuffer);
+ for (int i = 0; i < stillCount; ++i) {
+ bufferReturnCounters[info->captureParamBuffer] += 1;
+ bufferReturnCounters[info->rawBuffer] += 1;
+
+ imgu1_->param_->queueBuffer(info->captureParamBuffer);
+ imgu1_->input_->queueBuffer(info->rawBuffer);
+ }
} else {
info->captureParamDequeued = true;
}
@@ -1498,6 +1529,11 @@ void IPU3CameraData::tryReturnBuffer(FrameBuffer *buffer)
*/
void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)
{
+ if (--bufferReturnCounters[buffer] > 0)
+ return;
+
+ bufferReturnCounters.erase(buffer);
+
IPU3Frames::Info *info = frameInfos_.find(buffer);
if (!info)
return;
@@ -1564,6 +1600,11 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)
{
+ if (--bufferReturnCounters[buffer] > 0)
+ return;
+
+ bufferReturnCounters.erase(buffer);
+
IPU3Frames::Info *info = frameInfos_.find(buffer);
if (!info)
return;
@@ -1584,6 +1625,11 @@ void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)
void IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer)
{
+ if (--bufferReturnCounters[buffer] > 0)
+ return;
+
+ bufferReturnCounters.erase(buffer);
+
IPU3Frames::Info *info = frameInfos_.find(buffer);
if (!info)
return;
@@ -1604,6 +1650,11 @@ void IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer)
void IPU3CameraData::statBufferReady(FrameBuffer *buffer)
{
+ if (--bufferReturnCounters[buffer] > 0)
+ return;
+
+ bufferReturnCounters.erase(buffer);
+
IPU3Frames::Info *info = frameInfos_.find(buffer);
if (!info)
return;
--
2.37.1.455.g008518b4e5-goog
More information about the libcamera-devel
mailing list