@@ -88,6 +88,11 @@ class Camera final : public Object, public std::enable_shared_from_this<Camera>,
LIBCAMERA_DECLARE_PRIVATE()
public:
+ enum RequestCompletionMode {
+ InSubmissionOrder,
+ Immediately,
+ };
+
static std::shared_ptr<Camera> create(std::unique_ptr<Private> d,
const std::string &id,
const std::set<Stream *> &streams);
@@ -101,6 +106,9 @@ public:
int acquire();
int release();
+ int setRequestCompletionMode(RequestCompletionMode order);
+ RequestCompletionMode requestCompletionMode() const;
+
const ControlInfoMap &controls() const;
const ControlList &properties() const;
@@ -33,6 +33,9 @@ public:
PipelineHandler *pipe() { return pipe_.get(); }
+ void setRequestCompletionMode(RequestCompletionMode mode);
+ RequestCompletionMode requestCompletionMode() const;
+
std::list<Request *> queuedRequests_;
ControlInfoMap controlInfo_;
ControlList properties_;
@@ -67,6 +70,7 @@ private:
bool disconnected_;
std::atomic<State> state_;
+ RequestCompletionMode requestCompletionMode_;
std::unique_ptr<CameraControlValidator> validator_;
};
@@ -435,7 +435,8 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF
*/
Camera::Private::Private(PipelineHandler *pipe)
: requestSequence_(0), pipe_(pipe->shared_from_this()),
- disconnected_(false), state_(CameraAvailable)
+ disconnected_(false), state_(CameraAvailable),
+ requestCompletionMode_(Camera::InSubmissionOrder)
{
}
@@ -573,6 +574,28 @@ void Camera::Private::setState(State state)
state_.store(state, std::memory_order_release);
}
+/**
+ * \brief Set the request completion mode
+ * \param[in] mode The RequestCompletionMode
+ *
+ * This function set the request completion mode.
+ * InSubmissionOrder is the default mode.
+ */
+void Camera::Private::setRequestCompletionMode(RequestCompletionMode mode)
+{
+ requestCompletionMode_ = mode;
+}
+
+/**
+ * \brief Get the request completion mode
+ *
+ * \return The current RequestCompletionMode.
+ */
+Camera::RequestCompletionMode Camera::Private::requestCompletionMode() const
+{
+ return requestCompletionMode_;
+}
+
/**
* \class Camera
* \brief Camera device
@@ -702,6 +725,15 @@ std::shared_ptr<Camera> Camera::create(std::unique_ptr<Private> d,
return std::shared_ptr<Camera>(camera, Deleter());
}
+/**
+ * \enum Camera::RequestCompletionMode
+ * \brief The mode of request completion behavior
+ * \var Camera::RequestCompletionMode::InSubmissionOrder
+ * \brief requestCompleted will be emited according to the request submission order
+ * \var Camera::RequestCompletionMode::Immediately
+ * \brief requestCompleted will be emited immediately when a request is completed.
+ */
+
/**
* \brief Retrieve the ID of the camera
*
@@ -1237,6 +1269,40 @@ int Camera::stop()
return 0;
}
+/**
+ * \brief Set the request completion mode
+ * \param[in] mode The RequestCompletionMode
+ *
+ * This function set the request completion mode.
+ * InSubmissionOrder is the default mode.
+ *
+ * \return 0 on success or a negative error code otherwise
+ * \retval -EACCES The camera is running so can't change the behavior
+ */
+int Camera::setRequestCompletionMode(RequestCompletionMode mode)
+{
+ Private *const d = _d();
+
+ int ret = d->isAccessAllowed(Private::CameraAvailable,
+ Private::CameraConfigured);
+ if (ret < 0)
+ return -EACCES;
+
+ d->setRequestCompletionMode(mode);
+
+ return 0;
+}
+
+/**
+ * \brief Get the request completion mode
+ *
+ * \return The current RequestCompletionMode.
+ */
+Camera::RequestCompletionMode Camera::requestCompletionMode() const
+{
+ return _d()->requestCompletionMode();
+}
+
/**
* \brief Handle request completion and notify application
* \param[in] request The request that has completed
@@ -494,14 +494,20 @@ void PipelineHandler::completeRequest(Request *request)
Camera::Private *data = camera->_d();
- while (!data->queuedRequests_.empty()) {
- Request *req = data->queuedRequests_.front();
- if (req->status() == Request::RequestPending)
- break;
+ auto iter = data->queuedRequests_.begin();
+ while (iter != data->queuedRequests_.end()) {
+ if ((*iter)->status() != Request::RequestPending) {
+ ASSERT(!(*iter)->hasPendingBuffers());
+ camera->requestComplete((*iter));
+ iter = data->queuedRequests_.erase(iter);
+ continue;
+ }
- ASSERT(!req->hasPendingBuffers());
- data->queuedRequests_.pop_front();
- camera->requestComplete(req);
+ /* Break at the pending result to reflect the submission order */
+ if (camera->requestCompletionMode() == Camera::InSubmissionOrder) {
+ break;
+ }
+ iter++;
}
}
Add enum RequestCompletionMode to Camera with two value: InSubmissionOrder and Immediately. The purpose is to allow the application configure the order of signaling requestCompleted. The InSubmissionOrder mode is the default mode which signals according to the request submission order. The Immediately mode allows the pipeline handler to signal as soon as a request is completed. Applications need to reconstruct the order by self. Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org> --- include/libcamera/camera.h | 8 ++++ include/libcamera/internal/camera.h | 4 ++ src/libcamera/camera.cpp | 68 ++++++++++++++++++++++++++++- src/libcamera/pipeline_handler.cpp | 20 ++++++--- 4 files changed, 92 insertions(+), 8 deletions(-)