@@ -326,6 +326,7 @@ public:
};
std::vector<Stream> streams_;
+ Stream *rawStream_;
/*
* All entities in the pipeline, from the camera sensor to the video
@@ -453,7 +454,7 @@ private:
SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe,
unsigned int numStreams,
MediaEntity *sensor)
- : Camera::Private(pipe), streams_(numStreams)
+ : Camera::Private(pipe), streams_(numStreams), rawStream_(nullptr)
{
/*
* Find the shortest path from the camera sensor to a video capture
@@ -926,7 +927,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
*/
if (useConversion_) {
if (conversionQueue_.empty()) {
- video_->queueBuffer(buffer);
+ if (!rawStream_)
+ video_->queueBuffer(buffer);
return;
}
@@ -979,7 +981,14 @@ void SimpleCameraData::tryCompleteRequest(Request *request)
void SimpleCameraData::conversionInputDone(FrameBuffer *buffer)
{
/* Queue the input buffer back for capture. */
- video_->queueBuffer(buffer);
+ if (!rawStream_) {
+ video_->queueBuffer(buffer);
+ } else {
+ /* Complete the input buffer. */
+ Request *request = buffer->request();
+ if (pipe()->completeBuffer(request, buffer))
+ tryCompleteRequest(request);
+ }
}
void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
@@ -1219,7 +1228,7 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
* require any conversion, similar to raw capture use cases). This is
* left as a future improvement.
*/
- needConversion_ = config_.size() > 1;
+ needConversion_ = config_.size() > 1 + rawCount;
for (unsigned int i = 0; i < config_.size(); ++i) {
StreamConfiguration &cfg = config_[i];
@@ -1448,11 +1457,15 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
for (unsigned int i = 0; i < config->size(); ++i) {
StreamConfiguration &cfg = config->at(i);
+ bool rawStream = isFormatRaw(cfg.pixelFormat);
cfg.setStream(&data->streams_[i]);
- if (data->useConversion_ && !isFormatRaw(cfg.pixelFormat))
+ if (data->useConversion_ && !rawStream)
outputCfgs.push_back(cfg);
+
+ if (rawStream)
+ data->rawStream_ = &data->streams_[i];
}
if (outputCfgs.empty())
@@ -1483,7 +1496,7 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream,
* Export buffers on the converter or capture video node, depending on
* whether the converter is used or not.
*/
- if (data->useConversion_)
+ if (data->useConversion_ && (stream != data->rawStream_))
return data->converter_
? data->converter_->exportBuffers(stream, count, buffers)
: data->swIsp_->exportBuffers(stream, count, buffers);
@@ -1505,8 +1518,7 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
<< pad->entity()->name() << " in use";
return -EBUSY;
}
-
- if (data->useConversion_) {
+ if (data->useConversion_ && !data->rawStream_) {
/*
* When using the converter allocate a fixed number of internal
* buffers.
@@ -1514,8 +1526,16 @@ 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. */
- Stream *stream = &data->streams_[0];
+ /*
+ * Otherwise, prepare for using buffers from either the raw
+ * stream((if requested) or the only stream configured.
+ */
+ Stream *stream;
+ if (data->rawStream_)
+ stream = data->rawStream_;
+ else
+ stream = &data->streams_[0];
+
ret = video->importBuffers(stream->configuration().bufferCount);
}
if (ret < 0) {
@@ -1556,8 +1576,10 @@ 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->rawStream_) {
+ for (std::unique_ptr<FrameBuffer> &buffer : data->conversionBuffers_)
+ video->queueBuffer(buffer.get());
+ }
}
return 0;
@@ -1608,7 +1630,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_ && (stream != data->rawStream_)) {
buffers.emplace(stream, buffer);
metadataRequired = !!data->swIsp_;
} else {
Enable capturing of raw streams (standalone or in combination with a processed stream). Track the raw stream (if requested) in SimpleCameraData and adapt the buffer handling management accordingly. Signed-off-by: Umang Jain <uajain@igalia.com> --- src/libcamera/pipeline/simple/simple.cpp | 48 +++++++++++++++++------- 1 file changed, 35 insertions(+), 13 deletions(-)