From patchwork Thu Mar 25 13:42:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 11718 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com 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 5826BC32E9 for ; Thu, 25 Mar 2021 13:42:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 166E268D74; Thu, 25 Mar 2021 14:42:49 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Wsqc09ge"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 92FA368D78 for ; Thu, 25 Mar 2021 14:42:38 +0100 (CET) Received: from Q.local (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3805E8F0; Thu, 25 Mar 2021 14:42:38 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1616679758; bh=jy5bYpvfy4XXzv0fMaKRnM42klCMw03KqumuNftoGeA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wsqc09gez3ixKcPSpBs1qrJJ2oglb6bTSKvF9IrbzJYz9KPQQNyd2M5D8BC8R+LZh 0IYj7ShWb3eky9zGI5xvHErDmPdUlpLMctcN1APq1fQTDf68zTeUmaPKgl7QTnTDgI yPi5ENC8L7pdaetMQpZd6hpxiz3MAFKDNtBrOZes= From: Kieran Bingham To: libcamera devel Date: Thu, 25 Mar 2021 13:42:28 +0000 Message-Id: <20210325134231.1400051-11-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210325134231.1400051-1-kieran.bingham@ideasonboard.com> References: <20210325134231.1400051-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 08/11] libcamera: camera: Extend with a Stopping state 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When the camera is being stop()ped, active requests will complete. These may trigger an application to re-queue those requests to the camera but that is not permitted. Extend the camera state to include a stopping state which is entered as soon as a call to stop() is made. At this point, any request queued will be rejected with a warning, while any pending requests are either successfully completed or cancelled. When the pipeline handler has finished stopping, the camera state will transition to the CameraConfigured state where it can begin to accept requests again, and be restarted. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/camera.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 336ab8695ab3..7f7956ba732f 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -339,6 +339,7 @@ public: CameraAvailable, CameraAcquired, CameraConfigured, + CameraStopping, CameraRunning, }; @@ -382,6 +383,7 @@ static const char *const camera_state_names[] = { "Available", "Acquired", "Configured", + "Stopping", "Running", }; @@ -492,6 +494,7 @@ void Camera::Private::setState(State state) * node [shape = doublecircle ]; Available; * node [shape = circle ]; Acquired; * node [shape = circle ]; Configured; + * node [shape = circle ]; Stopping; * node [shape = circle ]; Running; * * Available -> Available [label = "release()"]; @@ -504,7 +507,8 @@ void Camera::Private::setState(State state) * Configured -> Configured [label = "configure(), createRequest()"]; * Configured -> Running [label = "start()"]; * - * Running -> Configured [label = "stop()"]; + * Running -> Stopping [label = "stop()"]; + * Stopping -> Configured; * Running -> Running [label = "createRequest(), queueRequest()"]; * } * \enddot @@ -524,6 +528,12 @@ void Camera::Private::setState(State state) * release() the camera and to get back to the Available state or start() * it to progress to the Running state. * + * \subsubsection Stopping + * The camera has been asked to stop. Pending reqeusts are being completed or + * cancelled, and no new requests are permitted to be queued. The camera will + * transition to the Configured state when all queued requests have been + * returned to the application. + * * \subsubsection Running * The camera is running and ready to process requests queued by the * application. The camera remains in this state until it is stopped and moved @@ -1071,6 +1081,8 @@ int Camera::stop() LOG(Camera, Debug) << "Stopping capture"; + d->setState(Private::CameraStopping); + d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking, this); @@ -1091,7 +1103,9 @@ void Camera::requestComplete(Request *request) Private *const d = LIBCAMERA_D_PTR(); /* Disconnected cameras are still able to complete requests. */ - int ret = d->isAccessAllowed(__FUNCTION__, Private::CameraRunning); + int ret = d->isAccessAllowed(__FUNCTION__, + Private::CameraStopping, + Private::CameraRunning); if (ret < 0 && ret != -ENODEV) LOG(Camera, Fatal) << "Trying to complete a request when stopped";