@@ -21,6 +21,7 @@
#include <libcamera/stream.h>
#include "libcamera/internal/ipa_proxy.h"
+#include "libcamera/internal/request.h"
namespace libcamera {
@@ -59,7 +60,7 @@ public:
void stop(Camera *camera);
bool hasPendingRequests(const Camera *camera) const;
- void registerRequest(Request *request);
+ std::unique_ptr<Request> createRequest(Camera *camera, uint64_t cookie);
void queueRequest(Request *request);
bool completeBuffer(Request *request, FrameBuffer *buffer);
@@ -74,6 +75,8 @@ protected:
void registerCamera(std::shared_ptr<Camera> camera);
void hotplugMediaDevice(MediaDevice *media);
+ virtual std::unique_ptr<Request> createRequestDevice(Camera *camera,
+ uint64_t cookie);
virtual int queueRequestDevice(Camera *camera, Request *request) = 0;
virtual void stopDevice(Camera *camera) = 0;
@@ -45,9 +45,10 @@ public:
using BufferMap = std::map<const Stream *, FrameBuffer *>;
- Request(Camera *camera, uint64_t cookie = 0);
+ Request(std::unique_ptr<Private> d, uint64_t cookie = 0);
~Request();
+ static std::unique_ptr<Request> create(std::unique_ptr<Private> d, uint64_t);
void reuse(ReuseFlag flags = Default);
ControlList &controls() { return *controls_; }
@@ -1236,12 +1236,8 @@ std::unique_ptr<Request> Camera::createRequest(uint64_t cookie)
if (ret < 0)
return nullptr;
- std::unique_ptr<Request> request = std::make_unique<Request>(this, cookie);
-
- /* Associate the request with the pipeline handler. */
- d->pipe_->registerRequest(request.get());
-
- return request;
+ /* Create a Request from the pipeline handler. */
+ return d->pipe_->createRequest(this, cookie);
}
/**
@@ -371,20 +371,25 @@ bool PipelineHandler::hasPendingRequests(const Camera *camera) const
}
/**
- * \fn PipelineHandler::registerRequest()
- * \brief Register a request for use by the pipeline handler
- * \param[in] request The request to register
+ * \fn PipelineHandler::createRequest()
+ * \brief Create a request and register it for use by the pipeline handler
+ * \param[in] camera The camera the Request belongs to
+ * \param[in] cookie The Request unique identifier
*
- * This function is called when the request is created, and allows the pipeline
- * handler to perform any one-time initialization it requries for the request.
+ * This function is called to create a Request by calling createRequestDevice()
+ * which can be optionally provided by the PipelineHandler derived classes.
*/
-void PipelineHandler::registerRequest(Request *request)
+std::unique_ptr<Request> PipelineHandler::createRequest(Camera *camera, uint64_t cookie)
{
+ std::unique_ptr<Request> request = createRequestDevice(camera, cookie);
+
/*
* Connect the request prepared signal to notify the pipeline handler
* when a request is ready to be processed.
*/
request->_d()->prepared.connect(this, &PipelineHandler::doQueueRequests);
+
+ return request;
}
/**
@@ -462,6 +467,27 @@ void PipelineHandler::doQueueRequests()
}
}
+/**
+ * \brief Create a Request from the pipeline handler
+ * \param[in] camera The camera the Request belongs to
+ * \param[in] cookie The Request unique identifier
+ *
+ * A virtual function that PipelineHandler derived classes are free to override
+ * in order to initialize a Request with a custom Request::Private derived
+ * class.
+ *
+ * This is the base class implementation that use Request::Private to
+ * initialize the Request.
+ *
+ * \return A unique pointer to a newly created Request
+ */
+std::unique_ptr<Request>
+PipelineHandler::createRequestDevice(Camera *camera, uint64_t cookie)
+{
+ auto d = std::make_unique<Request::Private>(camera);
+ return Request::create(std::move(d), cookie);
+}
+
/**
* \fn PipelineHandler::queueRequestDevice()
* \brief Queue a request to the device
@@ -336,7 +336,7 @@ void Request::Private::timeout()
/**
* \brief Create a capture request for a camera
- * \param[in] camera The camera that creates the request
+ * \param[in] d The request private data
* \param[in] cookie Opaque cookie for application use
*
* The \a cookie is stored in the request and is accessible through the
@@ -344,12 +344,17 @@ void Request::Private::timeout()
* the request to an external resource in the request completion handler, and is
* completely opaque to libcamera.
*/
-Request::Request(Camera *camera, uint64_t cookie)
- : Extensible(std::make_unique<Private>(camera)),
- cookie_(cookie), status_(RequestPending)
+std::unique_ptr<Request> Request::create(std::unique_ptr<Private> d,
+ uint64_t cookie)
+{
+ return std::make_unique<Request>(std::move(d), cookie);
+}
+
+Request::Request(std::unique_ptr<Request::Private> d, uint64_t cookie)
+ : Extensible(std::move(d)), cookie_(cookie), status_(RequestPending)
{
controls_ = new ControlList(controls::controls,
- camera->_d()->validator());
+ _d()->camera()->_d()->validator());
/**
* \todo Add a validator for metadata controls.
@@ -38,10 +38,6 @@ protected:
if (camera_->start() != -EACCES)
return TestFail;
- Request request(camera_.get());
- if (camera_->queueRequest(&request) != -EACCES)
- return TestFail;
-
/* Test operations which should pass. */
if (camera_->release())
return TestFail;
@@ -68,10 +64,6 @@ protected:
if (camera_->start() != -EACCES)
return TestFail;
- Request request(camera_.get());
- if (camera_->queueRequest(&request) != -EACCES)
- return TestFail;
-
/* Test operations which should pass. */
if (camera_->stop())
return TestFail;
@@ -95,10 +87,6 @@ protected:
if (camera_->acquire() != -EBUSY)
return TestFail;
- Request request1(camera_.get());
- if (camera_->queueRequest(&request1) != -EACCES)
- return TestFail;
-
/* Test operations which should pass. */
std::unique_ptr<Request> request2 = camera_->createRequest();
if (!request2)