[libcamera-devel] [PATCH 08/20] libcamera: pipeline: simple: converter: Decouple input and output completion
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sun Feb 21 14:06:39 CET 2021
Hi Kieran,
On Fri, Feb 19, 2021 at 05:33:23PM +0000, Kieran Bingham wrote:
> On 31/01/2021 22:46, Laurent Pinchart wrote:
> > 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 at ideasonboard.com>
> > ---
> > src/libcamera/pipeline/simple/converter.cpp | 24 +++++--------------
> > src/libcamera/pipeline/simple/converter.h | 11 ++++-----
> > src/libcamera/pipeline/simple/simple.cpp | 26 +++++++++++++--------
> > 3 files changed, 26 insertions(+), 35 deletions(-)
> >
> > diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp
> > index f782fbc63b09..8324baedc198 100644
> > --- a/src/libcamera/pipeline/simple/converter.cpp
> > +++ b/src/libcamera/pipeline/simple/converter.cpp
> > @@ -45,8 +45,8 @@ SimpleConverter::SimpleConverter(MediaDevice *media)
> > return;
> > }
> >
> > - m2m_->output()->bufferReady.connect(this, &SimpleConverter::outputBufferReady);
> > - m2m_->capture()->bufferReady.connect(this, &SimpleConverter::captureBufferReady);
> > + m2m_->output()->bufferReady.connect(this, &SimpleConverter::m2mInputBufferReady);
> > + m2m_->capture()->bufferReady.connect(this, &SimpleConverter::m2mOutputBufferReady);
> > }
> >
> > std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)
> > @@ -247,26 +247,14 @@ int SimpleConverter::queueBuffers(FrameBuffer *input, FrameBuffer *output)
> > return 0;
> > }
> >
> > -void SimpleConverter::captureBufferReady(FrameBuffer *buffer)
> > +void SimpleConverter::m2mInputBufferReady(FrameBuffer *buffer)
> > {
> > - if (!outputDoneQueue_.empty()) {
> > - FrameBuffer *other = outputDoneQueue_.front();
> > - outputDoneQueue_.pop();
> > - bufferReady.emit(other, buffer);
> > - } else {
> > - captureDoneQueue_.push(buffer);
> > - }
> > + inputBufferReady.emit(buffer);
> > }
> >
> > -void SimpleConverter::outputBufferReady(FrameBuffer *buffer)
> > +void SimpleConverter::m2mOutputBufferReady(FrameBuffer *buffer)
> > {
> > - if (!captureDoneQueue_.empty()) {
> > - FrameBuffer *other = captureDoneQueue_.front();
> > - captureDoneQueue_.pop();
> > - bufferReady.emit(buffer, other);
> > - } else {
> > - outputDoneQueue_.push(buffer);
> > - }
> > + outputBufferReady.emit(buffer);
> > }
> >
> > } /* namespace libcamera */
> > diff --git a/src/libcamera/pipeline/simple/converter.h b/src/libcamera/pipeline/simple/converter.h
> > index 780bfa8f7832..739b24df0200 100644
> > --- a/src/libcamera/pipeline/simple/converter.h
> > +++ b/src/libcamera/pipeline/simple/converter.h
> > @@ -9,7 +9,6 @@
> > #define __LIBCAMERA_PIPELINE_SIMPLE_CONVERTER_H__
> >
> > #include <memory>
> > -#include <queue>
> > #include <tuple>
> > #include <vector>
> >
> > @@ -47,17 +46,15 @@ public:
> >
> > int queueBuffers(FrameBuffer *input, FrameBuffer *output);
> >
> > - Signal<FrameBuffer *, FrameBuffer *> bufferReady;
> > + Signal<FrameBuffer *> inputBufferReady;
> > + Signal<FrameBuffer *> outputBufferReady;
> >
> > private:
> > - void captureBufferReady(FrameBuffer *buffer);
> > - void outputBufferReady(FrameBuffer *buffer);
> > + void m2mInputBufferReady(FrameBuffer *buffer);
> > + void m2mOutputBufferReady(FrameBuffer *buffer);
> >
> > std::unique_ptr<V4L2M2MDevice> m2m_;
> >
> > - std::queue<FrameBuffer *> captureDoneQueue_;
> > - std::queue<FrameBuffer *> outputDoneQueue_;
> > -
> > unsigned int inputBufferCount_;
> > unsigned int outputBufferCount_;
> > };
> > diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
> > index 20a4ebca94fd..7f9c57234256 100644
> > --- a/src/libcamera/pipeline/simple/simple.cpp
> > +++ b/src/libcamera/pipeline/simple/simple.cpp
> > @@ -144,7 +144,8 @@ private:
> > }
> >
> > void bufferReady(FrameBuffer *buffer);
> > - void converterDone(FrameBuffer *input, FrameBuffer *output);
> > + void converterInputDone(FrameBuffer *buffer);
> > + void converterOutputDone(FrameBuffer *buffer);
> >
> > MediaDevice *media_;
> > 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";
> > converter_.reset();
> > } 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);
> > }
> >
> > -void SimplePipelineHandler::converterDone(FrameBuffer *input,
> > - FrameBuffer *output)
> > +void SimplePipelineHandler::converterInputDone(FrameBuffer *buffer)
> > {
> > ASSERT(activeCamera_);
> > SimpleCameraData *data = cameraData(activeCamera_);
> >
> > - /* Complete the request. */
> > - Request *request = output->request();
> > - completeBuffer(request, output);
> > - completeRequest(request);
> > -
> > /* 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);
> > }
>
> I assume we still expect to maintain a one-in-one-out principle on the
> convertor though (no interlacing/de-interacing type buffers though here).
Correct. Until someone needs this feature of couse :-)
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> >
> > REGISTER_PIPELINE_HANDLER(SimplePipelineHandler)
> >
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list