summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2021-03-24 10:44:12 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2021-03-29 12:33:51 +0100
commitaa7d4ebf96d1b339ad1e1221d1154db6b845a1e2 (patch)
treec080939b01a0564f19a704e043c908d5ef3a1f7d /src
parent651e3fab6329498a7f46703ce5bb92c49cc37624 (diff)
libcamera: camera: Extend with a Stopping state
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, and is an error in the application. 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. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/camera.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 96a579eb..45bbc354 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -339,6 +339,7 @@ public:
CameraAvailable,
CameraAcquired,
CameraConfigured,
+ CameraStopping,
CameraRunning,
};
@@ -383,6 +384,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 requests 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
@@ -1067,6 +1077,8 @@ int Camera::stop()
LOG(Camera, Debug) << "Stopping capture";
+ d->setState(Private::CameraStopping);
+
d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,
this);
@@ -1087,7 +1099,8 @@ void Camera::requestComplete(Request *request)
Private *const d = LIBCAMERA_D_PTR();
/* Disconnected cameras are still able to complete requests. */
- if (d->isAccessAllowed(Private::CameraRunning, true))
+ if (d->isAccessAllowed(Private::CameraStopping, Private::CameraRunning,
+ true))
LOG(Camera, Fatal) << "Trying to complete a request when stopped";
requestCompleted.emit(request);