[libcamera-devel,v2,3/7] libcamera: ipu3: returning partial results
diff mbox series

Message ID 20220812090838.1784703-4-hanlinchen@chromium.org
State New
Headers show
Series
  • Implement Android Partial Result Featrue
Related show

Commit Message

Hanlin Chen Aug. 12, 2022, 9:08 a.m. UTC
Return metadata at earlier stage.

Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>
---
 src/ipa/ipu3/ipu3.cpp                |  2 -
 src/libcamera/pipeline/ipu3/ipu3.cpp | 65 ++++++++++++++++++----------
 2 files changed, 42 insertions(+), 25 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 2f6bb672..5e921875 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -594,8 +594,6 @@  void IPAIPU3::processStatsBuffer(const uint32_t frame,
 
 	ctrls.set(controls::ColourTemperature, context_.activeState.awb.temperatureK);
 
-	ctrls.set(controls::ExposureTime, frameContext.sensor.exposure * lineDuration);
-
 	/*
 	 * \todo The Metadata provides a path to getting extended data
 	 * out to the application. Further data such as a simplifed Histogram
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 4fe52f74..f65db3c8 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -41,6 +41,8 @@  namespace libcamera {
 
 LOG_DEFINE_CATEGORY(IPU3)
 
+using namespace std::literals::chrono_literals;
+
 static const ControlInfoMap::Map IPU3Controls = {
 	{ &controls::draft::PipelineDepth, ControlInfo(2, 3) },
 };
@@ -86,6 +88,8 @@  public:
 
 	ControlInfoMap ipaControls_;
 
+	IPACameraSensorInfo sensorInfo_;
+
 private:
 	void metadataReady(unsigned int id, const ControlList &metadata);
 	void paramsBufferReady(unsigned int id);
@@ -993,7 +997,7 @@  int PipelineHandlerIPU3::initControls(IPU3CameraData *data)
 int PipelineHandlerIPU3::updateControls(IPU3CameraData *data)
 {
 	CameraSensor *sensor = data->cio2_.sensor();
-	IPACameraSensorInfo sensorInfo{};
+	IPACameraSensorInfo &sensorInfo = data->sensorInfo_;
 
 	int ret = sensor->sensorInfo(&sensorInfo);
 	if (ret)
@@ -1300,7 +1304,7 @@  void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)
 		return;
 
 	Request *request = info->request;
-	request->metadata().merge(metadata);
+	pipe()->completeMetadata(request, metadata);
 
 	info->metadataProcessed = true;
 	if (frameInfos_.tryComplete(info))
@@ -1324,16 +1328,8 @@  void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)
 		return;
 
 	Request *request = info->request;
-
 	pipe()->completeBuffer(request, buffer);
 
-	request->metadata().set(controls::draft::PipelineDepth, 3);
-	/* \todo Actually apply the scaler crop region to the ImgU. */
-	const auto &scalerCrop = request->controls().get(controls::ScalerCrop);
-	if (scalerCrop)
-		cropRegion_ = *scalerCrop;
-	request->metadata().set(controls::ScalerCrop, cropRegion_);
-
 	if (frameInfos_.tryComplete(info))
 		pipe()->completeRequest(request);
 }
@@ -1372,13 +1368,35 @@  void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
 	 * \todo The sensor timestamp should be better estimated by connecting
 	 * to the V4L2Device::frameStart signal.
 	 */
-	request->metadata().set(controls::SensorTimestamp,
-				buffer->metadata().timestamp);
 
-	info->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence);
+	ControlList &sensorCtrl = info->effectiveSensorControls;
+	sensorCtrl = delayedCtrls_->get(buffer->metadata().sequence);
 
-	if (request->findBuffer(&rawStream_))
+	ControlList metadata;
+	metadata.set(controls::draft::PipelineDepth, 3);
+	metadata.set(controls::SensorTimestamp, buffer->metadata().timestamp);
+
+	/* \todo Actually apply the scaler crop region to the ImgU. */
+	const auto &scalerCrop = request->controls().get(controls::ScalerCrop);
+	if (scalerCrop)
+		cropRegion_ = *scalerCrop;
+	metadata.set(controls::ScalerCrop, cropRegion_);
+
+	/*
+	 * \todo Move reporting the raw frame related metadata from the IPA
+	 * to here: AnalogueGain, FrameDuration, etc.
+	 */
+	utils::Duration lineDuration = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate;
+	if (sensorCtrl.contains(V4L2_CID_EXPOSURE)) {
+		int32_t exposureTime = sensorCtrl.get(V4L2_CID_EXPOSURE).get<int32_t>();
+		metadata.set(controls::ExposureTime, exposureTime * lineDuration.get<std::micro>());
+	}
+
+	pipe()->completeMetadata(request, metadata);
+
+	if (request->findBuffer(&rawStream_)) {
 		pipe()->completeBuffer(request, buffer);
+	}
 
 	ipa_->fillParamsBuffer(info->id, info->paramBuffer->cookie());
 }
@@ -1455,20 +1473,21 @@  void IPU3CameraData::frameStart(uint32_t sequence)
 	Request *request = processingRequests_.front();
 	processingRequests_.pop();
 
-	const auto &testPatternMode = request->controls().get(controls::draft::TestPatternMode);
-	if (!testPatternMode)
-		return;
+	int32_t testPatternMode = controls::draft::TestPatternModeOff;
+	const auto &testPatternControl = request->controls().get(controls::draft::TestPatternMode);
+	if (testPatternControl)
+		testPatternMode = *testPatternControl;
 
 	int ret = cio2_.sensor()->setTestPatternMode(
-		static_cast<controls::draft::TestPatternModeEnum>(*testPatternMode));
+		static_cast<controls::draft::TestPatternModeEnum>(testPatternMode));
 	if (ret) {
-		LOG(IPU3, Error) << "Failed to set test pattern mode: "
-				 << ret;
-		return;
+		LOG(IPU3, Error) << "Failed to set test pattern mode: " << ret;
+		testPatternMode = controls::draft::TestPatternModeOff;
 	}
 
-	request->metadata().set(controls::draft::TestPatternMode,
-				*testPatternMode);
+	ControlList metadata;
+	metadata.set(controls::draft::TestPatternMode, testPatternMode);
+	pipe()->completeMetadata(request, metadata);
 }
 
 REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3)