From patchwork Wed Jul 7 14:41:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12855 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 55789BD794 for ; Wed, 7 Jul 2021 14:42:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EA11868503; Wed, 7 Jul 2021 16:42:22 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 311FD6028E for ; Wed, 7 Jul 2021 16:42:21 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id D7F681F434AD; Wed, 7 Jul 2021 15:42:19 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:41:53 -0300 Message-Id: <20210707144202.1327061-2-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 01/10] libcamera: property: Add MinNumRequests property X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The MinNumRequests property reports the bare minimum number of requests needed in the camera pipeline for capture to be possible. It is equal to the number of buffers required by the driver. At this quantity, there's no guarantee that frames won't be dropped or that manual per-frame controls will apply correctly. The quantity needed for those may be added as separate properties in the future. Signed-off-by: Nícolas F. R. A. Prado --- src/libcamera/pipeline/ipu3/ipu3.cpp | 6 ++++++ src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 6 ++++++ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 ++ src/libcamera/pipeline/simple/simple.cpp | 2 ++ src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 ++ src/libcamera/pipeline/vimc/vimc.cpp | 3 +++ src/libcamera/property_ids.yaml | 9 +++++++++ 7 files changed, 30 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 76c3bb3d8aa9..017018c845fa 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1111,6 +1111,12 @@ int PipelineHandlerIPU3::registerCameras() /* Initialize the camera properties. */ data->properties_ = cio2->sensor()->properties(); + /* + * \todo Make sure this is correct even after the stream is + * configured to CIO2 + */ + data->properties_.set(properties::MinNumRequests, 1); + ret = initControls(data.get()); if (ret) continue; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 082eb1ee1c23..f99a21de6918 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1045,6 +1045,12 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator) /* Initialize the camera properties. */ data->properties_ = data->sensor_->properties(); + /* + * \todo Make sure this is correct after the stream is configured for + * any of the roles + */ + data->properties_.set(properties::MinNumRequests, 1); + /* * Set a default value for the ScalerCropMaximum property to show * that we support its use, however, initialise it to zero because diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 00df4f0b3e6b..b5cbf2394b1c 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -944,6 +945,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) /* Initialize the camera properties. */ data->properties_ = data->sensor_->properties(); + data->properties_.set(properties::MinNumRequests, 3); /* * \todo Read dealy values from the sensor itself or from a diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index b29fff9820e5..c4adea61519f 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -436,6 +437,7 @@ int SimpleCameraData::init() } properties_ = sensor_->properties(); + properties_.set(properties::MinNumRequests, 3); return 0; } diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 0f634b8da609..0258111ad6cf 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -525,6 +525,8 @@ int UVCCameraData::init(MediaDevice *media) properties_.set(properties::PixelArraySize, resolution); properties_.set(properties::PixelArrayActiveAreas, { Rectangle(resolution) }); + properties_.set(properties::MinNumRequests, 1); + /* Initialise the supported controls. */ ControlInfoMap::Map ctrls; diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 12f7517fd0ae..8c3f7ccb46bd 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -517,6 +518,8 @@ int VimcCameraData::init() /* Initialize the camera properties. */ properties_ = sensor_->properties(); + properties_.set(properties::MinNumRequests, 2); + return 0; } diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml index 12ecbce5eed4..4efa952ee393 100644 --- a/src/libcamera/property_ids.yaml +++ b/src/libcamera/property_ids.yaml @@ -678,6 +678,15 @@ controls: \todo Turn this property into a "maximum control value" for the ScalerCrop control once "dynamic" controls have been implemented. + - MinNumRequests: + type: int32_t + description: | + The bare minimum number of requests needed in the camera pipeline for + capture to be possible, as required by the driver. Note that this + quantity does not guarantee that frames won't be dropped or that manual + per-frame controls will be applied properly. + + # ---------------------------------------------------------------------------- # Draft properties section From patchwork Wed Jul 7 14:41:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12856 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5264BBD794 for ; Wed, 7 Jul 2021 14:42:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1D2A368500; Wed, 7 Jul 2021 16:42:24 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 27F386851A for ; Wed, 7 Jul 2021 16:42:23 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 7F35C1F434AE; Wed, 7 Jul 2021 15:42:21 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:41:54 -0300 Message-Id: <20210707144202.1327061-3-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 02/10] libcamera: framebuffer_allocator: Make allocate() require count X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Make FrameBufferAllocator::allocate() require a 'count' argument for the number of buffers to be allocated. Signed-off-by: Nícolas F. R. A. Prado --- Changes in v5: - Made sure that qcam allocates at least 2 buffers include/libcamera/camera.h | 2 +- include/libcamera/framebuffer_allocator.h | 2 +- include/libcamera/internal/pipeline_handler.h | 2 +- src/android/camera_stream.cpp | 5 ++++- src/cam/capture.cpp | 9 +++------ src/gstreamer/gstlibcameraallocator.cpp | 4 +++- src/lc-compliance/simple_capture.cpp | 7 +++++-- src/libcamera/camera.cpp | 4 ++-- src/libcamera/framebuffer_allocator.cpp | 5 +++-- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 ++-- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 4 ++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 ++-- src/libcamera/pipeline/simple/simple.cpp | 4 ++-- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 7 ++++--- src/libcamera/pipeline/vimc/vimc.cpp | 7 ++++--- src/libcamera/pipeline_handler.cpp | 1 + src/qcam/main_window.cpp | 11 ++++++++++- src/v4l2/v4l2_camera.cpp | 2 +- test/camera/capture.cpp | 4 +++- test/camera/statemachine.cpp | 4 +++- test/mapped-buffer.cpp | 4 +++- 21 files changed, 60 insertions(+), 36 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index b081907e0cb1..9f1767e4c406 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -116,7 +116,7 @@ private: void requestComplete(Request *request); friend class FrameBufferAllocator; - int exportFrameBuffers(Stream *stream, + int exportFrameBuffers(Stream *stream, unsigned int count, std::vector> *buffers); }; diff --git a/include/libcamera/framebuffer_allocator.h b/include/libcamera/framebuffer_allocator.h index cbc9ce101889..2d5a6e98e10c 100644 --- a/include/libcamera/framebuffer_allocator.h +++ b/include/libcamera/framebuffer_allocator.h @@ -25,7 +25,7 @@ public: FrameBufferAllocator(std::shared_ptr camera); ~FrameBufferAllocator(); - int allocate(Stream *stream); + int allocate(Stream *stream, unsigned int count); int free(Stream *stream); bool allocated() const { return !buffers_.empty(); } diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 9e2d65d6f2c5..0b4b2e4947c0 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -76,7 +76,7 @@ public: const StreamRoles &roles) = 0; virtual int configure(Camera *camera, CameraConfiguration *config) = 0; - virtual int exportFrameBuffers(Camera *camera, Stream *stream, + virtual int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count, std::vector> *buffers) = 0; virtual int start(Camera *camera, const ControlList *controls) = 0; diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index bf4a7b41a70a..6e1e17b2e748 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -13,6 +13,7 @@ #include "jpeg/post_processor_jpeg.h" #include +#include using namespace libcamera; @@ -81,8 +82,10 @@ int CameraStream::configure() return ret; } + unsigned int bufferCount = cameraDevice_->camera()->properties().get(properties::MinNumRequests); + if (allocator_) { - int ret = allocator_->allocate(stream()); + int ret = allocator_->allocate(stream(), bufferCount); if (ret < 0) return ret; diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp index 3c3e3a53adf7..584097fae38c 100644 --- a/src/cam/capture.cpp +++ b/src/cam/capture.cpp @@ -11,6 +11,7 @@ #include #include +#include #include "capture.h" #include "main.h" @@ -81,17 +82,13 @@ int Capture::capture(FrameBufferAllocator *allocator) { int ret; - /* Identify the stream with the least number of buffers. */ - unsigned int nbuffers = UINT_MAX; + unsigned int nbuffers = camera_->properties().get(properties::MinNumRequests); for (StreamConfiguration &cfg : *config_) { - ret = allocator->allocate(cfg.stream()); + ret = allocator->allocate(cfg.stream(), nbuffers); if (ret < 0) { std::cerr << "Can't allocate buffers" << std::endl; return -ENOMEM; } - - unsigned int allocated = allocator->buffers(cfg.stream()).size(); - nbuffers = std::min(nbuffers, allocated); } /* diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp index 7bd8ba2db71d..37fe809bc575 100644 --- a/src/gstreamer/gstlibcameraallocator.cpp +++ b/src/gstreamer/gstlibcameraallocator.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include "gstlibcamera-utils.h" @@ -188,13 +189,14 @@ gst_libcamera_allocator_new(std::shared_ptr camera, { auto *self = GST_LIBCAMERA_ALLOCATOR(g_object_new(GST_TYPE_LIBCAMERA_ALLOCATOR, nullptr)); + unsigned int bufferCount = camera->properties().get(properties::MinNumRequests); self->fb_allocator = new FrameBufferAllocator(camera); for (StreamConfiguration &streamCfg : *config_) { Stream *stream = streamCfg.stream(); gint ret; - ret = self->fb_allocator->allocate(stream); + ret = self->fb_allocator->allocate(stream, bufferCount); if (ret == 0) return nullptr; diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index 25097f28a603..35dfccd664eb 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -7,6 +7,8 @@ #include +#include + #include "simple_capture.h" using namespace libcamera; @@ -44,11 +46,12 @@ void SimpleCapture::configure(StreamRole role) void SimpleCapture::start() { + unsigned int bufferCount = camera_->properties().get(properties::MinNumRequests); Stream *stream = config_->at(0).stream(); - int count = allocator_->allocate(stream); + int count = allocator_->allocate(stream, bufferCount); ASSERT_GE(count, 0) << "Failed to allocate buffers"; - EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected"; + EXPECT_EQ(count, static_cast(bufferCount)) << "Allocated less buffers than expected"; camera_->requestCompleted.connect(this, &SimpleCapture::requestComplete); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 29f2d91d05d3..7a2885465ca5 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -663,7 +663,7 @@ void Camera::disconnect() disconnected.emit(this); } -int Camera::exportFrameBuffers(Stream *stream, +int Camera::exportFrameBuffers(Stream *stream, unsigned int count, std::vector> *buffers) { Private *const d = LIBCAMERA_D_PTR(); @@ -680,7 +680,7 @@ int Camera::exportFrameBuffers(Stream *stream, return d->pipe_->invokeMethod(&PipelineHandler::exportFrameBuffers, ConnectionTypeBlocking, this, stream, - buffers); + count, buffers); } /** diff --git a/src/libcamera/framebuffer_allocator.cpp b/src/libcamera/framebuffer_allocator.cpp index 86a57923286c..42c5679e6610 100644 --- a/src/libcamera/framebuffer_allocator.cpp +++ b/src/libcamera/framebuffer_allocator.cpp @@ -71,6 +71,7 @@ FrameBufferAllocator::~FrameBufferAllocator() /** * \brief Allocate buffers for a configured stream * \param[in] stream The stream to allocate buffers for + * \param[in] count The number of buffers to allocate * * Allocate buffers suitable for capturing frames from the \a stream. The Camera * shall have been previously configured with Camera::configure() and shall be @@ -86,14 +87,14 @@ FrameBufferAllocator::~FrameBufferAllocator() * not part of the active camera configuration * \retval -EBUSY Buffers are already allocated for the \a stream */ -int FrameBufferAllocator::allocate(Stream *stream) +int FrameBufferAllocator::allocate(Stream *stream, unsigned int count) { if (buffers_.count(stream)) { LOG(Allocator, Error) << "Buffers already allocated for stream"; return -EBUSY; } - int ret = camera_->exportFrameBuffers(stream, &buffers_[stream]); + int ret = camera_->exportFrameBuffers(stream, count, &buffers_[stream]); if (ret == -EINVAL) LOG(Allocator, Error) << "Stream is not part of " << camera_->id() diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 017018c845fa..f3b456ba3afa 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -134,7 +134,7 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; - int exportFrameBuffers(Camera *camera, Stream *stream, + int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count, std::vector> *buffers) override; int start(Camera *camera, const ControlList *controls) override; @@ -654,10 +654,10 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) } int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, std::vector> *buffers) { IPU3CameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; if (stream == &data->outStream_) return data->imgu_->output_->exportBuffers(count, buffers); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index f99a21de6918..33d826433668 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -250,7 +250,7 @@ public: CameraConfiguration *generateConfiguration(Camera *camera, const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; - int exportFrameBuffers(Camera *camera, Stream *stream, + int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count, std::vector> *buffers) override; int start(Camera *camera, const ControlList *controls) override; @@ -794,10 +794,10 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) } int PipelineHandlerRPi::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream, + unsigned int count, std::vector> *buffers) { RPi::Stream *s = static_cast(stream); - unsigned int count = stream->configuration().bufferCount; int ret = s->dev()->exportBuffers(count, buffers); s->setExportedBuffers(buffers); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index b5cbf2394b1c..768969f4194a 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -141,7 +141,7 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; - int exportFrameBuffers(Camera *camera, Stream *stream, + int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count, std::vector> *buffers) override; int start(Camera *camera, const ControlList *controls) override; @@ -671,10 +671,10 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) } int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream, + unsigned int count, std::vector> *buffers) { RkISP1CameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; if (stream == &data->mainPathStream_) return mainPath_.exportBuffers(count, buffers); diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index c4adea61519f..37e880db0782 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -228,7 +228,7 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; - int exportFrameBuffers(Camera *camera, Stream *stream, + int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count, std::vector> *buffers) override; int start(Camera *camera, const ControlList *controls) override; @@ -776,10 +776,10 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) } int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, + unsigned int count, std::vector> *buffers) { SimpleCameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; /* * Export buffers on the converter or capture video node, depending on diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 0258111ad6cf..a1fa295a6456 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -69,7 +69,7 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; - int exportFrameBuffers(Camera *camera, Stream *stream, + int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count, std::vector> *buffers) override; int start(Camera *camera, const ControlList *controls) override; @@ -223,11 +223,12 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config) return 0; } -int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream, +int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, + [[maybe_unused]] Stream *stream, + unsigned int count, std::vector> *buffers) { UVCCameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; return data->video_->exportBuffers(count, buffers); } diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 8c3f7ccb46bd..d163e6b9767d 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -84,7 +84,7 @@ public: const StreamRoles &roles) override; int configure(Camera *camera, CameraConfiguration *config) override; - int exportFrameBuffers(Camera *camera, Stream *stream, + int exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count, std::vector> *buffers) override; int start(Camera *camera, const ControlList *controls) override; @@ -299,11 +299,12 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) return 0; } -int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream, +int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, + [[maybe_unused]] Stream *stream, + unsigned int count, std::vector> *buffers) { VimcCameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; return data->video_->exportBuffers(count, buffers); } diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 0ed172dcd750..93f62fc5bb4e 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -323,6 +323,7 @@ const ControlList &PipelineHandler::properties(const Camera *camera) const * \brief Allocate and export buffers for \a stream * \param[in] camera The camera * \param[in] stream The stream to allocate buffers for + * \param[in] count The number of buffers to allocate * \param[out] buffers Array of buffers successfully allocated * * This method allocates buffers for the \a stream from the devices associated diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 39d034de6bb2..e8b348470466 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include "dng_writer.h" @@ -463,7 +464,15 @@ int MainWindow::startCapture() for (StreamConfiguration &config : *config_) { Stream *stream = config.stream(); - ret = allocator_->allocate(stream); + unsigned int bufferCount = camera_->properties().get(properties::MinNumRequests); + + /* + * Need at least two buffers, one for capture and another for + * display + */ + bufferCount = std::max(bufferCount, 2U); + + ret = allocator_->allocate(stream, bufferCount); if (ret < 0) { qWarning() << "Failed to allocate capture buffers"; goto error; diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 157ab94e0544..d01eacfa2b84 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -161,7 +161,7 @@ int V4L2Camera::allocBuffers(unsigned int count) { Stream *stream = config_->at(0).stream(); - int ret = bufferAllocator_->allocate(stream); + int ret = bufferAllocator_->allocate(stream, count); if (ret < 0) return ret; diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index 238d98dbba16..fdb168dd5efa 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -96,7 +97,8 @@ protected: Stream *stream = cfg.stream(); - int ret = allocator_->allocate(stream); + unsigned int bufferCount = camera_->properties().get(properties::MinNumRequests); + int ret = allocator_->allocate(stream, bufferCount); if (ret < 0) return TestFail; diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index 26fb5ca17139..6f9a6b6f758c 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "camera_test.h" #include "test.h" @@ -119,7 +120,8 @@ protected: /* Use internally allocated buffers. */ allocator_ = new FrameBufferAllocator(camera_); Stream *stream = *camera_->streams().begin(); - if (allocator_->allocate(stream) < 0) + unsigned int bufferCount = camera_->properties().get(properties::MinNumRequests); + if (allocator_->allocate(stream, bufferCount) < 0) return TestFail; if (camera_->start()) diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp index 5de8201e45f6..c6b9e5882045 100644 --- a/test/mapped-buffer.cpp +++ b/test/mapped-buffer.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "libcamera/internal/buffer.h" @@ -54,7 +55,8 @@ protected: stream_ = cfg.stream(); - int ret = allocator_->allocate(stream_); + unsigned int bufferCount = camera_->properties().get(properties::MinNumRequests); + int ret = allocator_->allocate(stream_, bufferCount); if (ret < 0) return TestFail; From patchwork Wed Jul 7 14:41:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12857 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C1BDCBD794 for ; Wed, 7 Jul 2021 14:42:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 904CB6851F; Wed, 7 Jul 2021 16:42:26 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C98926028E for ; Wed, 7 Jul 2021 16:42:24 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 58EBA1F434B8; Wed, 7 Jul 2021 15:42:23 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:41:55 -0300 Message-Id: <20210707144202.1327061-4-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 03/10] lc-compliance: Move buffer allocation to separate function X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Move buffer allocation to its own function and with a count argument so tests can specify how many buffers to allocate. Also add an overloaded function with no arguments and that allocates MinNumRequests buffers for easier use by current tests. Signed-off-by: Nícolas F. R. A. Prado --- Added in v5 src/lc-compliance/capture_test.cpp | 8 +++++++- src/lc-compliance/simple_capture.cpp | 15 +++++++++++---- src/lc-compliance/simple_capture.h | 2 ++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/lc-compliance/capture_test.cpp b/src/lc-compliance/capture_test.cpp index 52578207c11f..6439cbd88f8e 100644 --- a/src/lc-compliance/capture_test.cpp +++ b/src/lc-compliance/capture_test.cpp @@ -80,6 +80,8 @@ TEST_P(SingleStream, Capture) capture.configure(role); + capture.allocateBuffers(); + capture.capture(numRequests); } @@ -99,8 +101,10 @@ TEST_P(SingleStream, CaptureStartStop) capture.configure(role); - for (unsigned int starts = 0; starts < numRepeats; starts++) + for (unsigned int starts = 0; starts < numRepeats; starts++) { + capture.allocateBuffers(); capture.capture(numRequests); + } } /* @@ -118,6 +122,8 @@ TEST_P(SingleStream, UnbalancedStop) capture.configure(role); + capture.allocateBuffers(); + capture.capture(numRequests); } diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index 35dfccd664eb..b20e2cefc000 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -44,15 +44,22 @@ void SimpleCapture::configure(StreamRole role) } } -void SimpleCapture::start() +void SimpleCapture::allocateBuffers() +{ + allocateBuffers(camera_->properties().get(properties::MinNumRequests)); +} + +void SimpleCapture::allocateBuffers(unsigned int count) { - unsigned int bufferCount = camera_->properties().get(properties::MinNumRequests); Stream *stream = config_->at(0).stream(); - int count = allocator_->allocate(stream, bufferCount); + int allocatedCount = allocator_->allocate(stream, count); ASSERT_GE(count, 0) << "Failed to allocate buffers"; - EXPECT_EQ(count, static_cast(bufferCount)) << "Allocated less buffers than expected"; + EXPECT_EQ(allocatedCount, static_cast(count)) << "Allocated less buffers than expected"; +} +void SimpleCapture::start() +{ camera_->requestCompleted.connect(this, &SimpleCapture::requestComplete); ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; diff --git a/src/lc-compliance/simple_capture.h b/src/lc-compliance/simple_capture.h index 100ffd6637ad..1a1e874a528c 100644 --- a/src/lc-compliance/simple_capture.h +++ b/src/lc-compliance/simple_capture.h @@ -17,6 +17,8 @@ class SimpleCapture { public: void configure(libcamera::StreamRole role); + void allocateBuffers(); + void allocateBuffers(unsigned int count); protected: SimpleCapture(std::shared_ptr camera); From patchwork Wed Jul 7 14:41:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12858 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E9BF3BD794 for ; Wed, 7 Jul 2021 14:42:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B7AE368521; Wed, 7 Jul 2021 16:42:28 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AF9FB68521 for ; Wed, 7 Jul 2021 16:42:26 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 32F381F434BD; Wed, 7 Jul 2021 15:42:25 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:41:56 -0300 Message-Id: <20210707144202.1327061-5-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 04/10] lc-compliance: Factor common capture code into SimpleCapture X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Factor common code from SimpleCapture* subclasses into the SimpleCapture parent class in order to avoid duplicated code. Signed-off-by: Nícolas F. R. A. Prado --- src/lc-compliance/simple_capture.cpp | 98 ++++++++++++++++------------ src/lc-compliance/simple_capture.h | 16 +++-- 2 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index b20e2cefc000..c28a6107ee87 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -78,6 +78,42 @@ void SimpleCapture::stop() allocator_->free(stream); } +bool SimpleCapture::captureCompleted() +{ + captureCount_++; + if (captureCount_ >= captureLimit_) { + loop_->exit(0); + return true; + } + return false; +} + +void SimpleCapture::queueRequests(Stream *stream, + std::vector> &requests, + const std::vector> &buffers) +{ + for (const std::unique_ptr &buffer : buffers) { + std::unique_ptr request = camera_->createRequest(); + ASSERT_TRUE(request) << "Can't create request"; + + ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; + + ASSERT_EQ(camera_->queueRequest(request.get()), 0) << "Failed to queue request"; + + requests.push_back(std::move(request)); + } +} + +int SimpleCapture::runCaptureSession() +{ + loop_ = new EventLoop(); + int status = loop_->exec(); + stop(); + delete loop_; + + return status; +} + /* SimpleCaptureBalanced */ SimpleCaptureBalanced::SimpleCaptureBalanced(std::shared_ptr camera) @@ -85,6 +121,22 @@ SimpleCaptureBalanced::SimpleCaptureBalanced(std::shared_ptr camera) { } +void SimpleCaptureBalanced::queueRequests(Stream *stream, + std::vector> &requests, + const std::vector> &buffers) +{ + for (const std::unique_ptr &buffer : buffers) { + std::unique_ptr request = camera_->createRequest(); + ASSERT_TRUE(request) << "Can't create request"; + + ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; + + ASSERT_EQ(queueRequest(request.get()), 0) << "Failed to queue request"; + + requests.push_back(std::move(request)); + } +} + void SimpleCaptureBalanced::capture(unsigned int numRequests) { start(); @@ -104,24 +156,10 @@ void SimpleCaptureBalanced::capture(unsigned int numRequests) captureCount_ = 0; captureLimit_ = numRequests; - /* Queue the recommended number of reqeuests. */ std::vector> requests; - for (const std::unique_ptr &buffer : buffers) { - std::unique_ptr request = camera_->createRequest(); - ASSERT_TRUE(request) << "Can't create request"; + queueRequests(stream, requests, buffers); - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; - - ASSERT_EQ(queueRequest(request.get()), 0) << "Failed to queue request"; - - requests.push_back(std::move(request)); - } - - /* Run capture session. */ - loop_ = new EventLoop(); - loop_->exec(); - stop(); - delete loop_; + runCaptureSession(); ASSERT_EQ(captureCount_, captureLimit_); } @@ -137,11 +175,8 @@ int SimpleCaptureBalanced::queueRequest(Request *request) void SimpleCaptureBalanced::requestComplete(Request *request) { - captureCount_++; - if (captureCount_ >= captureLimit_) { - loop_->exit(0); + if (captureCompleted()) return; - } request->reuse(Request::ReuseBuffers); if (queueRequest(request)) @@ -165,35 +200,18 @@ void SimpleCaptureUnbalanced::capture(unsigned int numRequests) captureCount_ = 0; captureLimit_ = numRequests; - /* Queue the recommended number of reqeuests. */ std::vector> requests; - for (const std::unique_ptr &buffer : buffers) { - std::unique_ptr request = camera_->createRequest(); - ASSERT_TRUE(request) << "Can't create request"; - - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; - - ASSERT_EQ(camera_->queueRequest(request.get()), 0) << "Failed to queue request"; + queueRequests(stream, requests, buffers); - requests.push_back(std::move(request)); - } - - /* Run capture session. */ - loop_ = new EventLoop(); - int status = loop_->exec(); - stop(); - delete loop_; + int status = runCaptureSession(); ASSERT_EQ(status, 0); } void SimpleCaptureUnbalanced::requestComplete(Request *request) { - captureCount_++; - if (captureCount_ >= captureLimit_) { - loop_->exit(0); + if (captureCompleted()) return; - } request->reuse(Request::ReuseBuffers); if (camera_->queueRequest(request)) diff --git a/src/lc-compliance/simple_capture.h b/src/lc-compliance/simple_capture.h index 1a1e874a528c..4356a849aa1b 100644 --- a/src/lc-compliance/simple_capture.h +++ b/src/lc-compliance/simple_capture.h @@ -26,11 +26,19 @@ protected: void start(); void stop(); + void queueRequests(libcamera::Stream *stream, + std::vector> &requests, + const std::vector> &buffers); + bool captureCompleted(); + int runCaptureSession(); virtual void requestComplete(libcamera::Request *request) = 0; EventLoop *loop_; + unsigned int captureCount_; + unsigned int captureLimit_; + std::shared_ptr camera_; std::unique_ptr allocator_; std::unique_ptr config_; @@ -46,10 +54,11 @@ public: private: int queueRequest(libcamera::Request *request); void requestComplete(libcamera::Request *request) override; + void queueRequests(libcamera::Stream *stream, + std::vector> &requests, + const std::vector> &buffers); unsigned int queueCount_; - unsigned int captureCount_; - unsigned int captureLimit_; }; class SimpleCaptureUnbalanced : public SimpleCapture @@ -61,9 +70,6 @@ public: private: void requestComplete(libcamera::Request *request) override; - - unsigned int captureCount_; - unsigned int captureLimit_; }; #endif /* __LC_COMPLIANCE_SIMPLE_CAPTURE_H__ */ From patchwork Wed Jul 7 14:41:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12859 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 35039BD794 for ; Wed, 7 Jul 2021 14:42:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D90FC68503; Wed, 7 Jul 2021 16:42:29 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 624B660284 for ; Wed, 7 Jul 2021 16:42:28 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id E72321F434CC; Wed, 7 Jul 2021 15:42:26 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:41:57 -0300 Message-Id: <20210707144202.1327061-6-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 05/10] lc-compliance: Move camera setup to CameraHolder class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Different base classes can be used for different setups on tests, but all of them will need to setup the camera for the test. To reuse that code, move it to a separate CameraHolder class that is inherited by test classes. Signed-off-by: Nícolas F. R. A. Prado --- Added in v5 src/lc-compliance/capture_test.cpp | 41 +++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/lc-compliance/capture_test.cpp b/src/lc-compliance/capture_test.cpp index 6439cbd88f8e..949407d3191e 100644 --- a/src/lc-compliance/capture_test.cpp +++ b/src/lc-compliance/capture_test.cpp @@ -18,23 +18,16 @@ using namespace libcamera; const std::vector NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; const std::vector ROLES = { Raw, StillCapture, VideoRecording, Viewfinder }; -class SingleStream : public testing::TestWithParam> +class CameraHolder { -public: - static std::string nameParameters(const testing::TestParamInfo &info); - protected: - void SetUp() override; - void TearDown() override; + void acquireCamera(); + void releaseCamera(); std::shared_ptr camera_; }; -/* - * We use gtest's SetUp() and TearDown() instead of constructor and destructor - * in order to be able to assert on them. - */ -void SingleStream::SetUp() +void CameraHolder::acquireCamera() { Environment *env = Environment::get(); @@ -43,7 +36,7 @@ void SingleStream::SetUp() ASSERT_EQ(camera_->acquire(), 0); } -void SingleStream::TearDown() +void CameraHolder::releaseCamera() { if (!camera_) return; @@ -52,6 +45,30 @@ void SingleStream::TearDown() camera_.reset(); } +class SingleStream : public testing::TestWithParam>, public CameraHolder +{ +public: + static std::string nameParameters(const testing::TestParamInfo &info); + +protected: + void SetUp() override; + void TearDown() override; +}; + +/* + * We use gtest's SetUp() and TearDown() instead of constructor and destructor + * in order to be able to assert on them. + */ +void SingleStream::SetUp() +{ + acquireCamera(); +} + +void SingleStream::TearDown() +{ + releaseCamera(); +} + std::string SingleStream::nameParameters(const testing::TestParamInfo &info) { std::map rolesMap = { { Raw, "Raw" }, From patchwork Wed Jul 7 14:41:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12860 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7E5A4BD794 for ; Wed, 7 Jul 2021 14:42:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4B08368509; Wed, 7 Jul 2021 16:42:33 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7A4EF60284 for ; Wed, 7 Jul 2021 16:42:31 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id A8DA01F434CD; Wed, 7 Jul 2021 15:42:28 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:41:58 -0300 Message-Id: <20210707144202.1327061-7-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 06/10] lc-compliance: Move role to string conversion to its own function X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The functions that generate the test name based on the parameters need to convert a StreamRole to a string. Move this to a separate function to avoid redundancy. Signed-off-by: Nícolas F. R. A. Prado --- Added in v5 src/lc-compliance/capture_test.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/lc-compliance/capture_test.cpp b/src/lc-compliance/capture_test.cpp index 949407d3191e..b4807486ee07 100644 --- a/src/lc-compliance/capture_test.cpp +++ b/src/lc-compliance/capture_test.cpp @@ -18,6 +18,16 @@ using namespace libcamera; const std::vector NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; const std::vector ROLES = { Raw, StillCapture, VideoRecording, Viewfinder }; +static const std::string &roleToString(const StreamRole &role) +{ + static std::map rolesMap = { { Raw, "Raw" }, + { StillCapture, "StillCapture" }, + { VideoRecording, "VideoRecording" }, + { Viewfinder, "Viewfinder" } }; + + return rolesMap[role]; +} + class CameraHolder { protected: @@ -71,15 +81,8 @@ void SingleStream::TearDown() std::string SingleStream::nameParameters(const testing::TestParamInfo &info) { - std::map rolesMap = { { Raw, "Raw" }, - { StillCapture, "StillCapture" }, - { VideoRecording, "VideoRecording" }, - { Viewfinder, "Viewfinder" } }; - - std::string roleName = rolesMap[std::get<0>(info.param)]; - std::string numRequestsName = std::to_string(std::get<1>(info.param)); - - return roleName + "_" + numRequestsName; + return roleToString(std::get<0>(info.param)) + "_" + + std::to_string(std::get<1>(info.param)); } /* From patchwork Wed Jul 7 14:41:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12861 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id AC0A2BD794 for ; Wed, 7 Jul 2021 14:42:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 78FC66851A; Wed, 7 Jul 2021 16:42:35 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AFE8960284 for ; Wed, 7 Jul 2021 16:42:33 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 04F661F434D4; Wed, 7 Jul 2021 15:42:31 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:41:59 -0300 Message-Id: <20210707144202.1327061-8-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 07/10] lc-compliance: Add test to queue more requests than hardware depth X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" A pipeline handler should be able to handle an arbitrary number of simultaneous requests by submitting what it can to the video device and queuing the rest internally until resources are available. This isn't currently done by some pipeline handlers however [1]. Add a new test to lc-compliance that submits a lot of requests at once to check if the pipeline handler is behaving well in this situation. [1] https://bugs.libcamera.org/show_bug.cgi?id=24 Signed-off-by: Nícolas F. R. A. Prado --- Changes in v5: - Updated to use googletest, and CameraHolder and roleToString from previous patches src/lc-compliance/capture_test.cpp | 45 ++++++++++++++++++++++++++++ src/lc-compliance/simple_capture.cpp | 30 +++++++++++++++++++ src/lc-compliance/simple_capture.h | 11 +++++++ 3 files changed, 86 insertions(+) diff --git a/src/lc-compliance/capture_test.cpp b/src/lc-compliance/capture_test.cpp index b4807486ee07..bb04e9ac100e 100644 --- a/src/lc-compliance/capture_test.cpp +++ b/src/lc-compliance/capture_test.cpp @@ -18,6 +18,8 @@ using namespace libcamera; const std::vector NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; const std::vector ROLES = { Raw, StillCapture, VideoRecording, Viewfinder }; +static const unsigned int MAX_SIMULTANEOUS_REQUESTS = 8; + static const std::string &roleToString(const StreamRole &role) { static std::map rolesMap = { { Raw, "Raw" }, @@ -79,12 +81,37 @@ void SingleStream::TearDown() releaseCamera(); } +class RoleParametrizedTest : public testing::TestWithParam, public CameraHolder +{ +public: + static std::string nameParameters(const testing::TestParamInfo &info); + +protected: + void SetUp() override; + void TearDown() override; +}; + +void RoleParametrizedTest::SetUp() +{ + acquireCamera(); +} + +void RoleParametrizedTest::TearDown() +{ + releaseCamera(); +} + std::string SingleStream::nameParameters(const testing::TestParamInfo &info) { return roleToString(std::get<0>(info.param)) + "_" + std::to_string(std::get<1>(info.param)); } +std::string RoleParametrizedTest::nameParameters(const testing::TestParamInfo &info) +{ + return roleToString(info.param); +} + /* * Test single capture cycles * @@ -147,8 +174,26 @@ TEST_P(SingleStream, UnbalancedStop) capture.capture(numRequests); } +TEST_P(RoleParametrizedTest, Overflow) +{ + auto role = GetParam(); + + SimpleCaptureOverflow capture(camera_); + + capture.configure(role); + + capture.allocateBuffers(MAX_SIMULTANEOUS_REQUESTS); + + capture.capture(); +} + INSTANTIATE_TEST_SUITE_P(CaptureTests, SingleStream, testing::Combine(testing::ValuesIn(ROLES), testing::ValuesIn(NUMREQUESTS)), SingleStream::nameParameters); + +INSTANTIATE_TEST_SUITE_P(CaptureTests, + RoleParametrizedTest, + testing::ValuesIn(ROLES), + RoleParametrizedTest::nameParameters); diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index c28a6107ee87..5aecc1ab0afc 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -217,3 +217,33 @@ void SimpleCaptureUnbalanced::requestComplete(Request *request) if (camera_->queueRequest(request)) loop_->exit(-EINVAL); } + +/* SimpleCaptureOverflow */ + +SimpleCaptureOverflow::SimpleCaptureOverflow(std::shared_ptr camera) + : SimpleCapture(camera) +{ +} + +void SimpleCaptureOverflow::capture() +{ + start(); + + Stream *stream = config_->at(0).stream(); + const std::vector> &buffers = allocator_->buffers(stream); + + captureCount_ = 0; + captureLimit_ = buffers.size(); + + std::vector> requests; + queueRequests(stream, requests, buffers); + + runCaptureSession(); + + ASSERT_EQ(captureCount_, captureLimit_); +} + +void SimpleCaptureOverflow::requestComplete([[maybe_unused]] Request *request) +{ + captureCompleted(); +} diff --git a/src/lc-compliance/simple_capture.h b/src/lc-compliance/simple_capture.h index 4356a849aa1b..a1bb594ddb01 100644 --- a/src/lc-compliance/simple_capture.h +++ b/src/lc-compliance/simple_capture.h @@ -72,4 +72,15 @@ private: void requestComplete(libcamera::Request *request) override; }; +class SimpleCaptureOverflow : public SimpleCapture +{ +public: + SimpleCaptureOverflow(std::shared_ptr camera); + + void capture(); + +private: + void requestComplete(libcamera::Request *request) override; +}; + #endif /* __LC_COMPLIANCE_SIMPLE_CAPTURE_H__ */ From patchwork Wed Jul 7 14:42:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12862 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id D379CBD794 for ; Wed, 7 Jul 2021 14:42:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A1AD668519; Wed, 7 Jul 2021 16:42:37 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5624860284 for ; Wed, 7 Jul 2021 16:42:35 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id DF5801F434E1; Wed, 7 Jul 2021 15:42:33 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:42:00 -0300 Message-Id: <20210707144202.1327061-9-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 08/10] lc-compliance: Check that requests complete successfully X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When a request fails to queue it is completed but with its status set to RequestCancelled. Add a check in the requestComplete callback to make sure that the request was completed successfully. Signed-off-by: Nícolas F. R. A. Prado --- Added in v5 src/lc-compliance/simple_capture.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index 5aecc1ab0afc..7bdc8abc4c0b 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -175,6 +175,7 @@ int SimpleCaptureBalanced::queueRequest(Request *request) void SimpleCaptureBalanced::requestComplete(Request *request) { + EXPECT_EQ(request->status(), Request::Status::RequestComplete) << "Request didn't complete successfully"; if (captureCompleted()) return; @@ -210,6 +211,7 @@ void SimpleCaptureUnbalanced::capture(unsigned int numRequests) void SimpleCaptureUnbalanced::requestComplete(Request *request) { + EXPECT_EQ(request->status(), Request::Status::RequestComplete) << "Request didn't complete successfully"; if (captureCompleted()) return; @@ -245,5 +247,6 @@ void SimpleCaptureOverflow::capture() void SimpleCaptureOverflow::requestComplete([[maybe_unused]] Request *request) { + EXPECT_EQ(request->status(), Request::Status::RequestComplete) << "Request didn't complete successfully"; captureCompleted(); } From patchwork Wed Jul 7 14:42:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12863 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 56EA4BD794 for ; Wed, 7 Jul 2021 14:42:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 23D9A68503; Wed, 7 Jul 2021 16:42:39 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D5C9A68523 for ; Wed, 7 Jul 2021 16:42:37 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id B93681F434E4; Wed, 7 Jul 2021 15:42:35 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:42:01 -0300 Message-Id: <20210707144202.1327061-10-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 09/10] libcamera: pipeline: Don't rely on bufferCount X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Pipelines have relied on bufferCount to decide on the number of buffers to allocate internally through allocateBuffers() and on the number of V4L2 buffer slots to reserve through importBuffers(). Instead, the number of internal buffers should be the minimum required by the algorithms to avoid wasting memory, and the number of V4L2 buffer slots should overallocate to avoid thrashing dmabuf mappings. For now, just set them to constants and stop relying on bufferCount, to allow for its removal. Signed-off-by: Nícolas F. R. A. Prado --- src/libcamera/pipeline/ipu3/imgu.cpp | 12 ++++++------ src/libcamera/pipeline/ipu3/imgu.h | 5 ++++- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 +-------- .../pipeline/raspberrypi/raspberrypi.cpp | 15 +++++---------- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 9 ++------- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 3 +++ src/libcamera/pipeline/simple/converter.cpp | 4 ++-- src/libcamera/pipeline/simple/converter.h | 3 +++ src/libcamera/pipeline/simple/simple.cpp | 6 ++---- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 5 +++-- src/libcamera/pipeline/vimc/vimc.cpp | 5 +++-- 12 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index e955bc3456ba..ac044638f9b0 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -593,22 +593,22 @@ int ImgUDevice::configureVideoDevice(V4L2VideoDevice *dev, unsigned int pad, /** * \brief Allocate buffers for all the ImgU video devices */ -int ImgUDevice::allocateBuffers(unsigned int bufferCount) +int ImgUDevice::allocateBuffers() { /* Share buffers between CIO2 output and ImgU input. */ - int ret = input_->importBuffers(bufferCount); + int ret = input_->importBuffers(BUFFER_SLOT_COUNT); if (ret) { LOG(IPU3, Error) << "Failed to import ImgU input buffers"; return ret; } - ret = param_->allocateBuffers(bufferCount, ¶mBuffers_); + ret = param_->allocateBuffers(INTERNAL_BUFFER_COUNT, ¶mBuffers_); if (ret < 0) { LOG(IPU3, Error) << "Failed to allocate ImgU param buffers"; goto error; } - ret = stat_->allocateBuffers(bufferCount, &statBuffers_); + ret = stat_->allocateBuffers(INTERNAL_BUFFER_COUNT, &statBuffers_); if (ret < 0) { LOG(IPU3, Error) << "Failed to allocate ImgU stat buffers"; goto error; @@ -619,13 +619,13 @@ int ImgUDevice::allocateBuffers(unsigned int bufferCount) * corresponding stream is active or inactive, as the driver needs * buffers to be requested on the V4L2 devices in order to operate. */ - ret = output_->importBuffers(bufferCount); + ret = output_->importBuffers(BUFFER_SLOT_COUNT); if (ret < 0) { LOG(IPU3, Error) << "Failed to import ImgU output buffers"; goto error; } - ret = viewfinder_->importBuffers(bufferCount); + ret = viewfinder_->importBuffers(BUFFER_SLOT_COUNT); if (ret < 0) { LOG(IPU3, Error) << "Failed to import ImgU viewfinder buffers"; goto error; diff --git a/src/libcamera/pipeline/ipu3/imgu.h b/src/libcamera/pipeline/ipu3/imgu.h index 9d4915116087..4163a8dc0875 100644 --- a/src/libcamera/pipeline/ipu3/imgu.h +++ b/src/libcamera/pipeline/ipu3/imgu.h @@ -61,7 +61,7 @@ public: outputFormat); } - int allocateBuffers(unsigned int bufferCount); + int allocateBuffers(); void freeBuffers(); int start(); @@ -86,6 +86,9 @@ private: static constexpr unsigned int PAD_VF = 3; static constexpr unsigned int PAD_STAT = 4; + static constexpr unsigned int INTERNAL_BUFFER_COUNT = 4; + static constexpr unsigned int BUFFER_SLOT_COUNT = 5; + int linkSetup(const std::string &source, unsigned int sourcePad, const std::string &sink, unsigned int sinkPad, bool enable); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f3b456ba3afa..e80b0aaea8dc 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -681,16 +681,9 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) { IPU3CameraData *data = cameraData(camera); ImgUDevice *imgu = data->imgu_; - unsigned int bufferCount; int ret; - bufferCount = std::max({ - data->outStream_.configuration().bufferCount, - data->vfStream_.configuration().bufferCount, - data->rawStream_.configuration().bufferCount, - }); - - ret = imgu->allocateBuffers(bufferCount); + ret = imgu->allocateBuffers(); if (ret < 0) return ret; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 33d826433668..9ad837f23338 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1154,20 +1154,15 @@ int PipelineHandlerRPi::prepareBuffers(Camera *camera) { RPiCameraData *data = cameraData(camera); int ret; + constexpr unsigned int bufferCount = 4; /* - * Decide how many internal buffers to allocate. For now, simply look - * at how many external buffers will be provided. We'll need to improve - * this logic. However, we really must have all streams allocate the same - * number of buffers to simplify error handling in queueRequestDevice(). + * Allocate internal buffers. We really must have all streams allocate + * the same number of buffers to simplify error handling in + * queueRequestDevice(). */ - unsigned int maxBuffers = 0; - for (const Stream *s : camera->streams()) - if (static_cast(s)->isExternal()) - maxBuffers = std::max(maxBuffers, s->configuration().bufferCount); - for (auto const stream : data->streams_) { - ret = stream->prepareBuffers(maxBuffers); + ret = stream->prepareBuffers(bufferCount); if (ret < 0) return ret; } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 768969f4194a..a36fc432cd0d 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -690,16 +690,11 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) unsigned int ipaBufferId = 1; int ret; - unsigned int maxCount = std::max({ - data->mainPathStream_.configuration().bufferCount, - data->selfPathStream_.configuration().bufferCount, - }); - - ret = param_->allocateBuffers(maxCount, ¶mBuffers_); + ret = param_->allocateBuffers(INTERNAL_BUFFER_COUNT, ¶mBuffers_); if (ret < 0) goto error; - ret = stat_->allocateBuffers(maxCount, &statBuffers_); + ret = stat_->allocateBuffers(INTERNAL_BUFFER_COUNT, &statBuffers_); if (ret < 0) goto error; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index 25f482eb8d8e..ec281fef316b 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -172,7 +172,7 @@ int RkISP1Path::start() return -EBUSY; /* \todo Make buffer count user configurable. */ - ret = video_->importBuffers(RKISP1_BUFFER_COUNT); + ret = video_->importBuffers(BUFFER_SLOT_COUNT); if (ret) return ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index 91757600ccdc..a0c4ef066a71 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -27,6 +27,9 @@ class V4L2Subdevice; struct StreamConfiguration; struct V4L2SubdeviceFormat; +static constexpr unsigned int INTERNAL_BUFFER_COUNT = 4; +static constexpr unsigned int BUFFER_SLOT_COUNT = 5; + class RkISP1Path { public: diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp index 3baf78f9364c..e797a1e8f2e8 100644 --- a/src/libcamera/pipeline/simple/converter.cpp +++ b/src/libcamera/pipeline/simple/converter.cpp @@ -103,11 +103,11 @@ int SimpleConverter::Stream::exportBuffers(unsigned int count, int SimpleConverter::Stream::start() { - int ret = m2m_->output()->importBuffers(inputBufferCount_); + int ret = m2m_->output()->importBuffers(BUFFER_SLOT_COUNT); if (ret < 0) return ret; - ret = m2m_->capture()->importBuffers(outputBufferCount_); + ret = m2m_->capture()->importBuffers(BUFFER_SLOT_COUNT); if (ret < 0) { stop(); return ret; diff --git a/src/libcamera/pipeline/simple/converter.h b/src/libcamera/pipeline/simple/converter.h index 276a2a291c21..dc252afd08e4 100644 --- a/src/libcamera/pipeline/simple/converter.h +++ b/src/libcamera/pipeline/simple/converter.h @@ -29,6 +29,9 @@ class SizeRange; struct StreamConfiguration; class V4L2M2MDevice; +constexpr unsigned int INTERNAL_BUFFER_COUNT = 5; +constexpr unsigned int BUFFER_SLOT_COUNT = 5; + class SimpleConverter { public: diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 37e880db0782..e9c914b32d63 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -803,12 +803,10 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL * When using the converter allocate a fixed number of internal * buffers. */ - ret = video->allocateBuffers(kNumInternalBuffers, + ret = video->allocateBuffers(INTERNAL_BUFFER_COUNT, &data->converterBuffers_); } else { - /* Otherwise, prepare for using buffers from the only stream. */ - Stream *stream = &data->streams_[0]; - ret = video->importBuffers(stream->configuration().bufferCount); + ret = video->importBuffers(BUFFER_SLOT_COUNT); } if (ret < 0) return ret; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index a1fa295a6456..f9fbcd721c4d 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -91,6 +91,8 @@ private: return static_cast( PipelineHandler::cameraData(camera)); } + + static constexpr unsigned int BUFFER_SLOT_COUNT = 5; }; UVCCameraConfiguration::UVCCameraConfiguration(UVCCameraData *data) @@ -236,9 +238,8 @@ int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, int PipelineHandlerUVC::start(Camera *camera, [[maybe_unused]] const ControlList *controls) { UVCCameraData *data = cameraData(camera); - unsigned int count = data->stream_.configuration().bufferCount; - int ret = data->video_->importBuffers(count); + int ret = data->video_->importBuffers(BUFFER_SLOT_COUNT); if (ret < 0) return ret; diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index d163e6b9767d..969f454e9951 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -102,6 +102,8 @@ private: return static_cast( PipelineHandler::cameraData(camera)); } + + static constexpr unsigned int BUFFER_SLOT_COUNT = 5; }; namespace { @@ -312,9 +314,8 @@ int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] const ControlList *controls) { VimcCameraData *data = cameraData(camera); - unsigned int count = data->stream_.configuration().bufferCount; - int ret = data->video_->importBuffers(count); + int ret = data->video_->importBuffers(BUFFER_SLOT_COUNT); if (ret < 0) return ret; From patchwork Wed Jul 7 14:42:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12864 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 80600BD794 for ; Wed, 7 Jul 2021 14:42:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 48FAD68509; Wed, 7 Jul 2021 16:42:41 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A59CC6851B for ; Wed, 7 Jul 2021 16:42:39 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:6553:ad0c:9d2a:24db]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 4CD5C1F434EA; Wed, 7 Jul 2021 15:42:38 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Wed, 7 Jul 2021 11:42:02 -0300 Message-Id: <20210707144202.1327061-11-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210707144202.1327061-1-nfraprado@collabora.com> References: <20210707144202.1327061-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 10/10] libcamera: stream: Remove bufferCount X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that the number of buffers allocated by the FrameBufferAllocator helper is passed through FrameBufferAllocator::allocate() and the pipelines no longer use bufferCount for internal buffer or V4L2 buffer slots allocation, we no longer need to have bufferCount in the StreamConfiguration, so remove it. Signed-off-by: Nícolas F. R. A. Prado --- include/libcamera/stream.h | 2 -- src/android/camera_stream.cpp | 2 +- src/libcamera/pipeline/ipu3/cio2.cpp | 1 - src/libcamera/pipeline/ipu3/ipu3.cpp | 7 ------- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 6 ------ src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 2 -- src/libcamera/pipeline/simple/converter.cpp | 3 --- src/libcamera/pipeline/simple/converter.h | 3 --- src/libcamera/pipeline/simple/simple.cpp | 5 +---- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 3 --- src/libcamera/pipeline/vimc/vimc.cpp | 3 --- src/libcamera/stream.cpp | 9 ++------- src/v4l2/v4l2_camera.cpp | 14 ++++++++++---- src/v4l2/v4l2_camera.h | 5 +++-- src/v4l2/v4l2_camera_proxy.cpp | 8 +++----- test/camera/buffer_import.cpp | 10 +++++++--- test/libtest/buffer_source.cpp | 4 ++-- test/libtest/buffer_source.h | 2 +- test/v4l2_videodevice/buffer_cache.cpp | 4 ++-- 19 files changed, 32 insertions(+), 61 deletions(-) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index bb47c390f8a1..f36aeffd9540 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -45,8 +45,6 @@ struct StreamConfiguration { unsigned int stride; unsigned int frameSize; - unsigned int bufferCount; - Stream *stream() const { return stream_; } void setStream(Stream *stream) { stream_ = stream; } const StreamFormats &formats() const { return formats_; } diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index 6e1e17b2e748..ffa6586d4546 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -94,7 +94,7 @@ int CameraStream::configure() buffers_.push_back(frameBuffer.get()); } - camera3Stream_->max_buffers = configuration().bufferCount; + camera3Stream_->max_buffers = bufferCount; return 0; } diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 1be2cbcd5cac..6e0f57d70534 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -213,7 +213,6 @@ StreamConfiguration CIO2Device::generateConfiguration(Size size) const cfg.size = sensorFormat.size; cfg.pixelFormat = mbusCodesToPixelFormat.at(sensorFormat.mbus_code); - cfg.bufferCount = CIO2_BUFFER_COUNT; return cfg; } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index e80b0aaea8dc..2245173b3ad5 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -295,7 +295,6 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() /* Initialize the RAW stream with the CIO2 configuration. */ cfg->size = cio2Configuration_.size; cfg->pixelFormat = cio2Configuration_.pixelFormat; - cfg->bufferCount = cio2Configuration_.bufferCount; cfg->stride = info.stride(cfg->size.width, 0, 64); cfg->frameSize = info.frameSize(cfg->size, 64); cfg->setStream(const_cast(&data_->rawStream_)); @@ -339,7 +338,6 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() IMGU_OUTPUT_HEIGHT_ALIGN); cfg->pixelFormat = formats::NV12; - cfg->bufferCount = IPU3_BUFFER_COUNT; cfg->stride = info.stride(cfg->size.width, 0, 1); cfg->frameSize = info.frameSize(cfg->size, 1); @@ -407,7 +405,6 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, Size sensorResolution = data->cio2_.sensor()->resolution(); for (const StreamRole role : roles) { std::map> streamFormats; - unsigned int bufferCount; PixelFormat pixelFormat; Size size; @@ -428,7 +425,6 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, size.height = utils::alignDown(size.height - 1, IMGU_OUTPUT_HEIGHT_MARGIN); pixelFormat = formats::NV12; - bufferCount = IPU3_BUFFER_COUNT; streamFormats[pixelFormat] = { { IMGU_OUTPUT_MIN_SIZE, size } }; break; @@ -438,7 +434,6 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, data->cio2_.generateConfiguration(sensorResolution); pixelFormat = cio2Config.pixelFormat; size = cio2Config.size; - bufferCount = cio2Config.bufferCount; for (const PixelFormat &format : data->cio2_.formats()) streamFormats[format] = data->cio2_.sizes(); @@ -457,7 +452,6 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN, IMGU_OUTPUT_HEIGHT_ALIGN); pixelFormat = formats::NV12; - bufferCount = IPU3_BUFFER_COUNT; streamFormats[pixelFormat] = { { IMGU_OUTPUT_MIN_SIZE, size } }; break; @@ -474,7 +468,6 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, StreamConfiguration cfg(formats); cfg.size = size; cfg.pixelFormat = pixelFormat; - cfg.bufferCount = bufferCount; config->addConfiguration(cfg); } diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 9ad837f23338..3da358c88592 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -472,7 +472,6 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, RPiCameraData *data = cameraData(camera); CameraConfiguration *config = new RPiCameraConfiguration(data); V4L2DeviceFormat sensorFormat; - unsigned int bufferCount; PixelFormat pixelFormat; V4L2VideoDevice::Formats fmts; Size size; @@ -490,7 +489,6 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, sensorFormat = findBestMode(fmts, size); pixelFormat = sensorFormat.fourcc.toPixelFormat(); ASSERT(pixelFormat.isValid()); - bufferCount = 2; rawCount++; break; @@ -499,7 +497,6 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, pixelFormat = formats::NV12; /* Return the largest sensor resolution. */ size = data->sensor_->resolution(); - bufferCount = 1; outCount++; break; @@ -515,7 +512,6 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, fmts = data->isp_[Isp::Output0].dev()->formats(); pixelFormat = formats::YUV420; size = { 1920, 1080 }; - bufferCount = 4; outCount++; break; @@ -523,7 +519,6 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, fmts = data->isp_[Isp::Output0].dev()->formats(); pixelFormat = formats::ARGB8888; size = { 800, 600 }; - bufferCount = 4; outCount++; break; @@ -553,7 +548,6 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, StreamConfiguration cfg(formats); cfg.size = size; cfg.pixelFormat = pixelFormat; - cfg.bufferCount = bufferCount; config->addConfiguration(cfg); } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index ec281fef316b..42cdb0ff7be6 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -61,7 +61,6 @@ StreamConfiguration RkISP1Path::generateConfiguration(const Size &resolution) StreamConfiguration cfg(formats); cfg.pixelFormat = formats::NV12; cfg.size = maxResolution; - cfg.bufferCount = RKISP1_BUFFER_COUNT; return cfg; } @@ -77,7 +76,6 @@ CameraConfiguration::Status RkISP1Path::validate(StreamConfiguration *cfg) cfg->size.boundTo(maxResolution_); cfg->size.expandTo(minResolution_); - cfg->bufferCount = RKISP1_BUFFER_COUNT; V4L2DeviceFormat format; format.fourcc = video_->toV4L2PixelFormat(cfg->pixelFormat); diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp index e797a1e8f2e8..c65cce541255 100644 --- a/src/libcamera/pipeline/simple/converter.cpp +++ b/src/libcamera/pipeline/simple/converter.cpp @@ -89,9 +89,6 @@ int SimpleConverter::Stream::configure(const StreamConfiguration &inputCfg, return -EINVAL; } - inputBufferCount_ = inputCfg.bufferCount; - outputBufferCount_ = outputCfg.bufferCount; - return 0; } diff --git a/src/libcamera/pipeline/simple/converter.h b/src/libcamera/pipeline/simple/converter.h index dc252afd08e4..1ee0538c5cd9 100644 --- a/src/libcamera/pipeline/simple/converter.h +++ b/src/libcamera/pipeline/simple/converter.h @@ -87,9 +87,6 @@ private: SimpleConverter *converter_; unsigned int index_; std::unique_ptr m2m_; - - unsigned int inputBufferCount_; - unsigned int outputBufferCount_; }; std::string deviceNode_; diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index e9c914b32d63..54d179e5fc90 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -628,7 +628,7 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() cfg.size != pipeConfig_->captureSize) needConversion_ = true; - /* Set the stride, frameSize and bufferCount. */ + /* Set the stride and frameSize. */ if (needConversion_) { std::tie(cfg.stride, cfg.frameSize) = converter->strideAndFrameSize(cfg.pixelFormat, cfg.size); @@ -646,8 +646,6 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() cfg.stride = format.planes[0].bpl; cfg.frameSize = format.planes[0].size; } - - cfg.bufferCount = 3; } return status; @@ -770,7 +768,6 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) inputCfg.pixelFormat = pipeConfig->captureFormat; inputCfg.size = pipeConfig->captureSize; inputCfg.stride = captureFormat.planes[0].bpl; - inputCfg.bufferCount = kNumInternalBuffers; return converter_->configure(inputCfg, outputCfgs); } diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index f9fbcd721c4d..182bea819715 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -150,8 +150,6 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() status = Adjusted; } - cfg.bufferCount = 4; - V4L2DeviceFormat format; format.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; @@ -193,7 +191,6 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, cfg.pixelFormat = formats.pixelformats().front(); cfg.size = formats.sizes(cfg.pixelFormat).back(); - cfg.bufferCount = 4; config->addConfiguration(cfg); diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 969f454e9951..97d814339bbb 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -167,8 +167,6 @@ CameraConfiguration::Status VimcCameraConfiguration::validate() status = Adjusted; } - cfg.bufferCount = 4; - V4L2DeviceFormat format; format.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; @@ -224,7 +222,6 @@ CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera, cfg.pixelFormat = formats::BGR888; cfg.size = { 1920, 1080 }; - cfg.bufferCount = 4; config->addConfiguration(cfg); diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp index b8626775d224..ca507b72b26a 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -280,7 +280,7 @@ SizeRange StreamFormats::range(const PixelFormat &pixelformat) const * handlers provide StreamFormats. */ StreamConfiguration::StreamConfiguration() - : pixelFormat(0), stride(0), frameSize(0), bufferCount(0), + : pixelFormat(0), stride(0), frameSize(0), stream_(nullptr) { } @@ -289,7 +289,7 @@ StreamConfiguration::StreamConfiguration() * \brief Construct a configuration with stream formats */ StreamConfiguration::StreamConfiguration(const StreamFormats &formats) - : pixelFormat(0), stride(0), frameSize(0), bufferCount(0), + : pixelFormat(0), stride(0), frameSize(0), stream_(nullptr), formats_(formats) { } @@ -324,11 +324,6 @@ StreamConfiguration::StreamConfiguration(const StreamFormats &formats) * validating the configuration with a call to CameraConfiguration::validate(). */ -/** - * \var StreamConfiguration::bufferCount - * \brief Requested number of buffers to allocate for the stream - */ - /** * \fn StreamConfiguration::stream() * \brief Retrieve the stream associated with the configuration diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index d01eacfa2b84..3c5bff4623bd 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -12,6 +12,8 @@ #include +#include + using namespace libcamera; LOG_DECLARE_CATEGORY(V4L2Compat) @@ -107,14 +109,12 @@ void V4L2Camera::requestComplete(Request *request) } int V4L2Camera::configure(StreamConfiguration *streamConfigOut, - const Size &size, const PixelFormat &pixelformat, - unsigned int bufferCount) + const Size &size, const PixelFormat &pixelformat) { StreamConfiguration &streamConfig = config_->at(0); streamConfig.size.width = size.width; streamConfig.size.height = size.height; streamConfig.pixelFormat = pixelformat; - streamConfig.bufferCount = bufferCount; /* \todo memoryType (interval vs external) */ CameraConfiguration::Status validation = config_->validate(); @@ -146,7 +146,6 @@ int V4L2Camera::validateConfiguration(const PixelFormat &pixelFormat, StreamConfiguration &cfg = config->at(0); cfg.size = size; cfg.pixelFormat = pixelFormat; - cfg.bufferCount = 1; CameraConfiguration::Status validation = config->validate(); if (validation == CameraConfiguration::Invalid) @@ -299,3 +298,10 @@ bool V4L2Camera::isRunning() { return isRunning_; } + +unsigned int V4L2Camera::minNumRequests(unsigned int count) +{ + unsigned int min = camera_->properties().get(properties::MinNumRequests); + + return std::max(count, min); +} diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index dbe0573bd3a4..fb0591eb4a64 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -45,8 +45,7 @@ public: std::vector completedBuffers(); int configure(StreamConfiguration *streamConfigOut, - const Size &size, const PixelFormat &pixelformat, - unsigned int bufferCount); + const Size &size, const PixelFormat &pixelformat); int validateConfiguration(const PixelFormat &pixelformat, const Size &size, StreamConfiguration *streamConfigOut); @@ -65,6 +64,8 @@ public: bool isRunning(); + unsigned int minNumRequests(unsigned int count); + private: void requestComplete(Request *request); diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 7682c4bddf90..26c8874033ec 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -349,8 +349,7 @@ int V4L2CameraProxy::vidioc_s_fmt(V4L2CameraFile *file, struct v4l2_format *arg) Size size(arg->fmt.pix.width, arg->fmt.pix.height); V4L2PixelFormat v4l2Format = V4L2PixelFormat(arg->fmt.pix.pixelformat); ret = vcam_->configure(&streamConfig_, size, - PixelFormatInfo::info(v4l2Format).format, - bufferCount_); + PixelFormatInfo::info(v4l2Format).format); if (ret < 0) return -EINVAL; @@ -491,14 +490,13 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf Size size(v4l2PixFormat_.width, v4l2PixFormat_.height); V4L2PixelFormat v4l2Format = V4L2PixelFormat(v4l2PixFormat_.pixelformat); int ret = vcam_->configure(&streamConfig_, size, - PixelFormatInfo::info(v4l2Format).format, - arg->count); + PixelFormatInfo::info(v4l2Format).format); if (ret < 0) return -EINVAL; setFmtFromConfig(streamConfig_); - arg->count = streamConfig_.bufferCount; + arg->count = vcam_->minNumRequests(arg->count); bufferCount_ = arg->count; ret = vcam_->allocBuffers(arg->count); diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp index c504ea09e64b..45e6ec91747b 100644 --- a/test/camera/buffer_import.cpp +++ b/test/camera/buffer_import.cpp @@ -16,6 +16,8 @@ #include #include +#include + #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/v4l2_videodevice.h" @@ -92,10 +94,12 @@ protected: return TestFail; } + unsigned int bufferCount = camera_->properties().get(properties::MinNumRequests); + Stream *stream = cfg.stream(); BufferSource source; - int ret = source.allocate(cfg); + int ret = source.allocate(cfg, bufferCount); if (ret != TestPass) return ret; @@ -139,10 +143,10 @@ protected: while (timer.isRunning()) dispatcher->processEvents(); - if (completeRequestsCount_ < cfg.bufferCount * 2) { + if (completeRequestsCount_ < bufferCount * 2) { std::cout << "Failed to capture enough frames (got " << completeRequestsCount_ << " expected at least " - << cfg.bufferCount * 2 << ")" << std::endl; + << bufferCount * 2 << ")" << std::endl; return TestFail; } diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp index 73563f2fc39d..c3d5286a2462 100644 --- a/test/libtest/buffer_source.cpp +++ b/test/libtest/buffer_source.cpp @@ -24,7 +24,7 @@ BufferSource::~BufferSource() media_->release(); } -int BufferSource::allocate(const StreamConfiguration &config) +int BufferSource::allocate(const StreamConfiguration &config, unsigned int count) { /* Locate and open the video device. */ std::string videoDeviceName = "vivid-000-vid-out"; @@ -77,7 +77,7 @@ int BufferSource::allocate(const StreamConfiguration &config) return TestFail; } - if (video->allocateBuffers(config.bufferCount, &buffers_) < 0) { + if (video->allocateBuffers(count, &buffers_) < 0) { std::cout << "Failed to allocate buffers" << std::endl; return TestFail; } diff --git a/test/libtest/buffer_source.h b/test/libtest/buffer_source.h index 14b4770e8d8a..6a18e269a575 100644 --- a/test/libtest/buffer_source.h +++ b/test/libtest/buffer_source.h @@ -20,7 +20,7 @@ public: BufferSource(); ~BufferSource(); - int allocate(const StreamConfiguration &config); + int allocate(const StreamConfiguration &config, unsigned int count); const std::vector> &buffers(); private: diff --git a/test/v4l2_videodevice/buffer_cache.cpp b/test/v4l2_videodevice/buffer_cache.cpp index b3f2bec11783..07fddfd2617c 100644 --- a/test/v4l2_videodevice/buffer_cache.cpp +++ b/test/v4l2_videodevice/buffer_cache.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include "buffer_source.h" @@ -145,10 +146,9 @@ public: StreamConfiguration cfg; cfg.pixelFormat = formats::YUYV; cfg.size = Size(600, 800); - cfg.bufferCount = numBuffers; BufferSource source; - int ret = source.allocate(cfg); + int ret = source.allocate(cfg, numBuffers); if (ret != TestPass) return ret;