mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-16 17:05:08 +03:00
libcamera: pipeline: simple: converter: Decouple input and output completion
The SimpleConverter API signals completion of input and output buffer pairs. This unnecessarily delays requeueing the input buffer to the video capture queue until the output buffer completes, and also delays signalling request completion until the input buffer completes. While this shouldn't cause large delays in practice, it will also not scale when multi-stream support will be added to the converter class. To address the current issue and prepare for the future, decouple signalling of input and output buffers completion. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Phi-Bang Nguyen <pnguyen@baylibre.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
parent
fb8c63d69c
commit
be50270b7d
3 changed files with 26 additions and 35 deletions
|
@ -45,8 +45,8 @@ SimpleConverter::SimpleConverter(MediaDevice *media)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m2m_->output()->bufferReady.connect(this, &SimpleConverter::outputBufferReady);
|
m2m_->output()->bufferReady.connect(this, &SimpleConverter::m2mInputBufferReady);
|
||||||
m2m_->capture()->bufferReady.connect(this, &SimpleConverter::captureBufferReady);
|
m2m_->capture()->bufferReady.connect(this, &SimpleConverter::m2mOutputBufferReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)
|
std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)
|
||||||
|
@ -247,26 +247,14 @@ int SimpleConverter::queueBuffers(FrameBuffer *input, FrameBuffer *output)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleConverter::captureBufferReady(FrameBuffer *buffer)
|
void SimpleConverter::m2mInputBufferReady(FrameBuffer *buffer)
|
||||||
{
|
{
|
||||||
if (!outputDoneQueue_.empty()) {
|
inputBufferReady.emit(buffer);
|
||||||
FrameBuffer *other = outputDoneQueue_.front();
|
|
||||||
outputDoneQueue_.pop();
|
|
||||||
bufferReady.emit(other, buffer);
|
|
||||||
} else {
|
|
||||||
captureDoneQueue_.push(buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleConverter::outputBufferReady(FrameBuffer *buffer)
|
void SimpleConverter::m2mOutputBufferReady(FrameBuffer *buffer)
|
||||||
{
|
{
|
||||||
if (!captureDoneQueue_.empty()) {
|
outputBufferReady.emit(buffer);
|
||||||
FrameBuffer *other = captureDoneQueue_.front();
|
|
||||||
captureDoneQueue_.pop();
|
|
||||||
bufferReady.emit(buffer, other);
|
|
||||||
} else {
|
|
||||||
outputDoneQueue_.push(buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#define __LIBCAMERA_PIPELINE_SIMPLE_CONVERTER_H__
|
#define __LIBCAMERA_PIPELINE_SIMPLE_CONVERTER_H__
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -48,17 +47,15 @@ public:
|
||||||
|
|
||||||
int queueBuffers(FrameBuffer *input, FrameBuffer *output);
|
int queueBuffers(FrameBuffer *input, FrameBuffer *output);
|
||||||
|
|
||||||
Signal<FrameBuffer *, FrameBuffer *> bufferReady;
|
Signal<FrameBuffer *> inputBufferReady;
|
||||||
|
Signal<FrameBuffer *> outputBufferReady;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void captureBufferReady(FrameBuffer *buffer);
|
void m2mInputBufferReady(FrameBuffer *buffer);
|
||||||
void outputBufferReady(FrameBuffer *buffer);
|
void m2mOutputBufferReady(FrameBuffer *buffer);
|
||||||
|
|
||||||
std::unique_ptr<V4L2M2MDevice> m2m_;
|
std::unique_ptr<V4L2M2MDevice> m2m_;
|
||||||
|
|
||||||
std::queue<FrameBuffer *> captureDoneQueue_;
|
|
||||||
std::queue<FrameBuffer *> outputDoneQueue_;
|
|
||||||
|
|
||||||
unsigned int inputBufferCount_;
|
unsigned int inputBufferCount_;
|
||||||
unsigned int outputBufferCount_;
|
unsigned int outputBufferCount_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -144,7 +144,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void bufferReady(FrameBuffer *buffer);
|
void bufferReady(FrameBuffer *buffer);
|
||||||
void converterDone(FrameBuffer *input, FrameBuffer *output);
|
void converterInputDone(FrameBuffer *buffer);
|
||||||
|
void converterOutputDone(FrameBuffer *buffer);
|
||||||
|
|
||||||
MediaDevice *media_;
|
MediaDevice *media_;
|
||||||
std::map<const MediaEntity *, std::unique_ptr<V4L2VideoDevice>> videos_;
|
std::map<const MediaEntity *, std::unique_ptr<V4L2VideoDevice>> videos_;
|
||||||
|
@ -768,7 +769,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
|
||||||
<< "Failed to create converter, disabling format conversion";
|
<< "Failed to create converter, disabling format conversion";
|
||||||
converter_.reset();
|
converter_.reset();
|
||||||
} else {
|
} else {
|
||||||
converter_->bufferReady.connect(this, &SimplePipelineHandler::converterDone);
|
converter_->inputBufferReady.connect(this, &SimplePipelineHandler::converterInputDone);
|
||||||
|
converter_->outputBufferReady.connect(this, &SimplePipelineHandler::converterOutputDone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,19 +927,23 @@ void SimplePipelineHandler::bufferReady(FrameBuffer *buffer)
|
||||||
completeRequest(request);
|
completeRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimplePipelineHandler::converterDone(FrameBuffer *input,
|
void SimplePipelineHandler::converterInputDone(FrameBuffer *buffer)
|
||||||
FrameBuffer *output)
|
|
||||||
{
|
{
|
||||||
ASSERT(activeCamera_);
|
ASSERT(activeCamera_);
|
||||||
SimpleCameraData *data = cameraData(activeCamera_);
|
SimpleCameraData *data = cameraData(activeCamera_);
|
||||||
|
|
||||||
/* Complete the request. */
|
|
||||||
Request *request = output->request();
|
|
||||||
completeBuffer(request, output);
|
|
||||||
completeRequest(request);
|
|
||||||
|
|
||||||
/* Queue the input buffer back for capture. */
|
/* Queue the input buffer back for capture. */
|
||||||
data->video_->queueBuffer(input);
|
data->video_->queueBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimplePipelineHandler::converterOutputDone(FrameBuffer *buffer)
|
||||||
|
{
|
||||||
|
ASSERT(activeCamera_);
|
||||||
|
|
||||||
|
/* Complete the request. */
|
||||||
|
Request *request = buffer->request();
|
||||||
|
completeBuffer(request, buffer);
|
||||||
|
completeRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_PIPELINE_HANDLER(SimplePipelineHandler)
|
REGISTER_PIPELINE_HANDLER(SimplePipelineHandler)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue