<div dir="ltr">Hi all,<div><br></div><div>Gentle ping to get some feedback on this one.</div><div><br></div><div>Regards,</div><div>Naush</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 26 Nov 2020 at 09:51, Naushir Patuck <<a href="mailto:naush@raspberrypi.com">naush@raspberrypi.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Applications now have the ability to pass in controls that need to be<br>
applied on startup, rather than doing it through Request where there might<br>
be some frames of delay in getting the controls applied.<br>
<br>
This commit adds the ability to pass in a set of libcamera controls into<br>
the pipeline handlers through the pipeline_handler::start() method. These<br>
controls are provided by the application through the camera::start()<br>
public API.<br>
<br>
Signed-off-by: Naushir Patuck <<a href="mailto:naush@raspberrypi.com" target="_blank">naush@raspberrypi.com</a>><br>
Reviewed-by: David Plowman <<a href="mailto:david.plowman@raspberrypi.com" target="_blank">david.plowman@raspberrypi.com</a>><br>
Tested-by: David Plowman <<a href="mailto:david.plowman@raspberrypi.com" target="_blank">david.plowman@raspberrypi.com</a>><br>
---<br>
Documentation/guides/pipeline-handler.rst | 4 ++--<br>
include/libcamera/camera.h | 2 +-<br>
include/libcamera/internal/pipeline_handler.h | 2 +-<br>
src/libcamera/camera.cpp | 11 ++++++-----<br>
src/libcamera/pipeline/ipu3/ipu3.cpp | 4 ++--<br>
src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 4 ++--<br>
src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 ++--<br>
src/libcamera/pipeline/simple/simple.cpp | 4 ++--<br>
src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 4 ++--<br>
src/libcamera/pipeline/vimc/vimc.cpp | 4 ++--<br>
src/libcamera/pipeline_handler.cpp | 1 +<br>
11 files changed, 23 insertions(+), 21 deletions(-)<br>
<br>
diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst<br>
index 57aee455..63275a12 100644<br>
--- a/Documentation/guides/pipeline-handler.rst<br>
+++ b/Documentation/guides/pipeline-handler.rst<br>
@@ -209,7 +209,7 @@ methods for the overridden class members.<br>
int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;<br>
<br>
- int start(Camera *camera) override;<br>
+ int start(Camera *camera, ControlList *controls) override;<br>
void stop(Camera *camera) override;<br>
<br>
int queueRequestDevice(Camera *camera, Request *request) override;<br>
@@ -239,7 +239,7 @@ methods for the overridden class members.<br>
return -1;<br>
}<br>
<br>
- int PipelineHandlerVivid::start(Camera *camera)<br>
+ int PipelineHandlerVivid::start(Camera *camera, ControlList *controls)<br>
{<br>
return -1;<br>
}<br>
diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h<br>
index 5c5f1a05..f94f8599 100644<br>
--- a/include/libcamera/camera.h<br>
+++ b/include/libcamera/camera.h<br>
@@ -103,7 +103,7 @@ public:<br>
std::unique_ptr<Request> createRequest(uint64_t cookie = 0);<br>
int queueRequest(Request *request);<br>
<br>
- int start();<br>
+ int start(ControlList *controls = nullptr);<br>
int stop();<br>
<br>
private:<br>
diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h<br>
index c12c8904..bd3c4a81 100644<br>
--- a/include/libcamera/internal/pipeline_handler.h<br>
+++ b/include/libcamera/internal/pipeline_handler.h<br>
@@ -78,7 +78,7 @@ public:<br>
virtual int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;<br>
<br>
- virtual int start(Camera *camera) = 0;<br>
+ virtual int start(Camera *camera, ControlList *controls) = 0;<br>
virtual void stop(Camera *camera) = 0;<br>
<br>
int queueRequest(Camera *camera, Request *request);<br>
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp<br>
index dffbd6bd..de9c6c86 100644<br>
--- a/src/libcamera/camera.cpp<br>
+++ b/src/libcamera/camera.cpp<br>
@@ -943,9 +943,10 @@ int Camera::queueRequest(Request *request)<br>
/**<br>
* \brief Start capture from camera<br>
*<br>
- * Start the camera capture session. Once the camera is started the application<br>
- * can queue requests to the camera to process and return to the application<br>
- * until the capture session is terminated with \a stop().<br>
+ * Start the camera capture session, optionally providing a list of controls to<br>
+ * action before starting. Once the camera is started the application can queue<br>
+ * requests to the camera to process and return to the application until the<br>
+ * capture session is terminated with \a stop().<br>
*<br>
* \context This function may only be called when the camera is in the<br>
* Configured state as defined in \ref camera_operation, and shall be<br>
@@ -956,7 +957,7 @@ int Camera::queueRequest(Request *request)<br>
* \retval -ENODEV The camera has been disconnected from the system<br>
* \retval -EACCES The camera is not in a state where it can be started<br>
*/<br>
-int Camera::start()<br>
+int Camera::start(ControlList *controls)<br>
{<br>
Private *const d = LIBCAMERA_D_PTR();<br>
<br>
@@ -967,7 +968,7 @@ int Camera::start()<br>
LOG(Camera, Debug) << "Starting capture";<br>
<br>
ret = d->pipe_->invokeMethod(&PipelineHandler::start,<br>
- ConnectionTypeBlocking, this);<br>
+ ConnectionTypeBlocking, this, controls);<br>
if (ret)<br>
return ret;<br>
<br>
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
index 4cedb32b..8a1918d5 100644<br>
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
@@ -105,7 +105,7 @@ public:<br>
int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;<br>
<br>
- int start(Camera *camera) override;<br>
+ int start(Camera *camera, ControlList *controls) override;<br>
void stop(Camera *camera) override;<br>
<br>
int queueRequestDevice(Camera *camera, Request *request) override;<br>
@@ -596,7 +596,7 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera)<br>
return 0;<br>
}<br>
<br>
-int PipelineHandlerIPU3::start(Camera *camera)<br>
+int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *controls)<br>
{<br>
IPU3CameraData *data = cameraData(camera);<br>
CIO2Device *cio2 = &data->cio2_;<br>
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp<br>
index 7ad66f21..ddb30e49 100644<br>
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp<br>
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp<br>
@@ -237,7 +237,7 @@ public:<br>
int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;<br>
<br>
- int start(Camera *camera) override;<br>
+ int start(Camera *camera, ControlList *controls) override;<br>
void stop(Camera *camera) override;<br>
<br>
int queueRequestDevice(Camera *camera, Request *request) override;<br>
@@ -726,7 +726,7 @@ int PipelineHandlerRPi::exportFrameBuffers([[maybe_unused]] Camera *camera, Stre<br>
return ret;<br>
}<br>
<br>
-int PipelineHandlerRPi::start(Camera *camera)<br>
+int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *controls)<br>
{<br>
RPiCameraData *data = cameraData(camera);<br>
int ret;<br>
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp<br>
index 1b1922a9..2e8d2930 100644<br>
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp<br>
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp<br>
@@ -187,7 +187,7 @@ public:<br>
int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;<br>
<br>
- int start(Camera *camera) override;<br>
+ int start(Camera *camera, ControlList *controls) override;<br>
void stop(Camera *camera) override;<br>
<br>
int queueRequestDevice(Camera *camera, Request *request) override;<br>
@@ -822,7 +822,7 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera)<br>
return 0;<br>
}<br>
<br>
-int PipelineHandlerRkISP1::start(Camera *camera)<br>
+int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *controls)<br>
{<br>
RkISP1CameraData *data = cameraData(camera);<br>
int ret;<br>
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp<br>
index 0d3078f7..b047aeb9 100644<br>
--- a/src/libcamera/pipeline/simple/simple.cpp<br>
+++ b/src/libcamera/pipeline/simple/simple.cpp<br>
@@ -126,7 +126,7 @@ public:<br>
int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;<br>
<br>
- int start(Camera *camera) override;<br>
+ int start(Camera *camera, ControlList *controls) override;<br>
void stop(Camera *camera) override;<br>
<br>
bool match(DeviceEnumerator *enumerator) override;<br>
@@ -646,7 +646,7 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream,<br>
return data->video_->exportBuffers(count, buffers);<br>
}<br>
<br>
-int SimplePipelineHandler::start(Camera *camera)<br>
+int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] ControlList *controls)<br>
{<br>
SimpleCameraData *data = cameraData(camera);<br>
V4L2VideoDevice *video = data->video_;<br>
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp<br>
index 0f3241cc..87b0f03d 100644<br>
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp<br>
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp<br>
@@ -76,7 +76,7 @@ public:<br>
int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;<br>
<br>
- int start(Camera *camera) override;<br>
+ int start(Camera *camera, ControlList *controls) override;<br>
void stop(Camera *camera) override;<br>
<br>
int queueRequestDevice(Camera *camera, Request *request) override;<br>
@@ -236,7 +236,7 @@ int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,<br>
return data->video_->exportBuffers(count, buffers);<br>
}<br>
<br>
-int PipelineHandlerUVC::start(Camera *camera)<br>
+int PipelineHandlerUVC::start(Camera *camera, [[maybe_unused]] ControlList *controls)<br>
{<br>
UVCCameraData *data = cameraData(camera);<br>
unsigned int count = data->stream_.configuration().bufferCount;<br>
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp<br>
index 914b6b54..d81b8598 100644<br>
--- a/src/libcamera/pipeline/vimc/vimc.cpp<br>
+++ b/src/libcamera/pipeline/vimc/vimc.cpp<br>
@@ -92,7 +92,7 @@ public:<br>
int exportFrameBuffers(Camera *camera, Stream *stream,<br>
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;<br>
<br>
- int start(Camera *camera) override;<br>
+ int start(Camera *camera, ControlList *controls) override;<br>
void stop(Camera *camera) override;<br>
<br>
int queueRequestDevice(Camera *camera, Request *request) override;<br>
@@ -313,7 +313,7 @@ int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream,<br>
return data->video_->exportBuffers(count, buffers);<br>
}<br>
<br>
-int PipelineHandlerVimc::start(Camera *camera)<br>
+int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] ControlList *controls)<br>
{<br>
VimcCameraData *data = cameraData(camera);<br>
unsigned int count = data->stream_.configuration().bufferCount;<br>
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp<br>
index 894200ee..bafcf21b 100644<br>
--- a/src/libcamera/pipeline_handler.cpp<br>
+++ b/src/libcamera/pipeline_handler.cpp<br>
@@ -351,6 +351,7 @@ const ControlList &PipelineHandler::properties(const Camera *camera) const<br>
* \fn PipelineHandler::start()<br>
* \brief Start capturing from a group of streams<br>
* \param[in] camera The camera to start<br>
+ * \param[in] controls Controls for the IPA to action before starting the camera<br>
*<br>
* Start the group of streams that have been configured for capture by<br>
* \a configure(). The intended caller of this method is the Camera class which<br>
-- <br>
2.25.1<br>
<br>
</blockquote></div>