[RFC,v2,10/13] libcamera: simple: Make raw streams working
diff mbox series

Message ID 20250124215806.158024-11-mzamazal@redhat.com
State New
Headers show
Series
  • Enable raw streams with software ISP
Related show

Commit Message

Milan Zamazal Jan. 24, 2025, 9:58 p.m. UTC
When a raw stream is requested, whether alone or together with a
processed stream, its buffers must be handled outside the software ISP
machinery.  They serve as input buffers, even when a processed stream is
produced.

At most one raw stream and at most one processed stream are supported
and can be combined.  An example of producing both raw and processed
files using `cam' application:

  cam -c1 -C100 -s role=raw,width=1920,height=1080,pixelformat=SRGGB8 -s role=viewfinder,width=1920,height=1080,pixelformat=RGB888 -Ffile#

This is the final step to make raw streams working.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 src/libcamera/pipeline/simple/simple.cpp | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index edf08666..23456cbf 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -824,7 +824,8 @@  void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
 		 * buffer for capture (unless the stream is being stopped), and
 		 * complete the request with all the user-facing buffers.
 		 */
-		if (buffer->metadata().status != FrameMetadata::FrameCancelled)
+		if (buffer->metadata().status != FrameMetadata::FrameCancelled &&
+		    !rawRequested_)
 			video_->queueBuffer(buffer);
 
 		if (conversionQueue_.empty())
@@ -870,13 +871,14 @@  void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
 	 */
 	if (useConversion_) {
 		if (conversionQueue_.empty()) {
-			video_->queueBuffer(buffer);
+			if (!rawRequested_)
+				video_->queueBuffer(buffer);
 			return;
 		}
 
 		if (converter_)
 			converter_->queueBuffers(buffer, conversionQueue_.front().outputs);
-		else
+		else if (swispRequested_)
 			/*
 			 * request->sequence() cannot be retrieved from `buffer' inside
 			 * queueBuffers because unique_ptr's make buffer->request() invalid
@@ -886,6 +888,8 @@  void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
 					     conversionQueue_.front().outputs);
 
 		conversionQueue_.pop();
+		if (rawRequested_)
+			pipe->completeBuffer(request, buffer);
 		return;
 	}
 
@@ -905,7 +909,8 @@  void SimpleCameraData::clearIncompleteRequests()
 void SimpleCameraData::conversionInputDone(FrameBuffer *buffer)
 {
 	/* Queue the input buffer back for capture. */
-	video_->queueBuffer(buffer);
+	if (!rawRequested_)
+		video_->queueBuffer(buffer);
 }
 
 void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
@@ -1450,7 +1455,7 @@  int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
 		return -EBUSY;
 	}
 
-	if (data->useConversion_) {
+	if (data->useConversion_ && !data->rawRequested_) {
 		/*
 		 * When using the converter allocate a fixed number of internal
 		 * buffers.
@@ -1458,7 +1463,7 @@  int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
 		ret = video->allocateBuffers(kNumInternalBuffers,
 					     &data->conversionBuffers_);
 	} else {
-		/* Otherwise, prepare for using buffers from the only stream. */
+		/* Otherwise, prepare for using buffers from the only or raw stream. */
 		Stream *stream = &data->streams_[0];
 		ret = video->importBuffers(stream->configuration().bufferCount);
 	}
@@ -1489,8 +1494,9 @@  int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
 		}
 
 		/* Queue all internal buffers for capture. */
-		for (std::unique_ptr<FrameBuffer> &buffer : data->conversionBuffers_)
-			video->queueBuffer(buffer.get());
+		if (!data->rawRequested_)
+			for (std::unique_ptr<FrameBuffer> &buffer : data->conversionBuffers_)
+				video->queueBuffer(buffer.get());
 	}
 
 	return 0;
@@ -1532,7 +1538,7 @@  int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request)
 		 * queue, it will be handed to the converter in the capture
 		 * completion handler.
 		 */
-		if (data->useConversion_) {
+		if (data->useConversion_ && !isRawFormat(stream->configuration().pixelFormat)) {
 			buffers.emplace(stream, buffer);
 		} else {
 			ret = data->video_->queueBuffer(buffer);