From patchwork Thu Jul 1 19:29:51 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: 12760 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 68DF2C3222 for ; Thu, 1 Jul 2021 19:30:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7ABFA684E7; Thu, 1 Jul 2021 21:30:10 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 86E8E60289 for ; Thu, 1 Jul 2021 21:30:08 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2434:bd70:78a1:919c:f01a]) (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 F387C1F445A3; Thu, 1 Jul 2021 20:30:06 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Thu, 1 Jul 2021 16:29:51 -0300 Message-Id: <20210701192951.662584-1-nfraprado@collabora.com> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] libcamera: pipeline: uvcvideo: Add internal request queue 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" Add an internal queue that stores requests until there are v4l2 buffer slots available. This avoids the need to cancel requests when there is a shortage of said buffers. Signed-off-by: NĂ­colas F. R. A. Prado --- This is very similar to what 5a9d19210fad ("libcamera: pipeline: ipu3: Try queuing pending requests if a buffer is available") and 89dae5844964 ("libcamera: pipeline: ipu3: Store requests in the case a buffer shortage") did for IPU3. I tested this with a new lc-compliance test from [1] which is a rebased version of the series in [2]. I'll resend this series after the googletest refactor series [3] is merged. But this patch for uvcvideo doesn't depend on that. [1] https://gitlab.collabora.com/nfraprado/libcamera/-/tree/lcc-lots-requests-v5 [2] https://lists.libcamera.org/pipermail/libcamera-devel/2021-May/020150.html [3] https://lists.libcamera.org/pipermail/libcamera-devel/2021-June/021891.html src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 64 +++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 0f634b8da609..a51131dce8e0 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,11 @@ public: ControlInfoMap::Map *ctrls); void bufferReady(FrameBuffer *buffer); + void queuePendingRequests(); + void cancelPendingRequests(); + + std::queue pendingRequests_; + std::unique_ptr video_; Stream stream_; }; @@ -79,12 +85,13 @@ public: bool match(DeviceEnumerator *enumerator) override; + int processControls(UVCCameraData *data, Request *request); + private: std::string generateId(const UVCCameraData *data); int processControl(ControlList *controls, unsigned int id, const ControlValue &value); - int processControls(UVCCameraData *data, Request *request); UVCCameraData *cameraData(const Camera *camera) { @@ -363,24 +370,59 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request) return ret; } +void UVCCameraData::cancelPendingRequests() +{ + while (!pendingRequests_.empty()) { + Request *request = pendingRequests_.front(); + FrameBuffer *buffer = request->findBuffer(&stream_); + + buffer->cancel(); + pipe_->completeBuffer(request, buffer); + pipe_->completeRequest(request); + + pendingRequests_.pop(); + } +} + +void UVCCameraData::queuePendingRequests() +{ + PipelineHandlerUVC *pipe = static_cast(pipe_); + + while (!pendingRequests_.empty()) { + Request *request = pendingRequests_.front(); + FrameBuffer *buffer = request->findBuffer(&stream_); + + int ret = pipe->processControls(this, request); + if (ret < 0) { + buffer->cancel(); + pipe_->completeBuffer(request, buffer); + pipe_->completeRequest(request); + pendingRequests_.pop(); + continue; + } + + /* If we're missing v4l2 buffer slots, try again later */ + ret = video_->queueBuffer(buffer); + if (ret < 0) + break; + + pendingRequests_.pop(); + } +} + int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request) { UVCCameraData *data = cameraData(camera); - FrameBuffer *buffer = request->findBuffer(&data->stream_); - if (!buffer) { + + if (!request->findBuffer(&data->stream_)) { LOG(UVC, Error) << "Attempt to queue request with invalid stream"; return -ENOENT; } - int ret = processControls(data, request); - if (ret < 0) - return ret; - - ret = data->video_->queueBuffer(buffer); - if (ret < 0) - return ret; + data->pendingRequests_.push(request); + data->queuePendingRequests(); return 0; } @@ -668,6 +710,8 @@ void UVCCameraData::bufferReady(FrameBuffer *buffer) pipe_->completeBuffer(request, buffer); pipe_->completeRequest(request); + + queuePendingRequests(); } REGISTER_PIPELINE_HANDLER(PipelineHandlerUVC)