gstreamer: Apply controls after acquiring buffers
diff mbox series

Message ID 20261026130820.27075-1-sugi@nemui.org
State New
Headers show
Series
  • gstreamer: Apply controls after acquiring buffers
Related show

Commit Message

Tatsuki Sugiura Oct. 26, 2026, 1:08 p.m. UTC
GstLibcameraSrcState::queueRequest() calls GstCameraControls::applyControls()
before acquiring the buffers for the request. applyControls() merges the
pending controls into the request and then clears them, so they are consumed
even when the request is dropped immediately afterwards because the buffer
pool is empty, gst_buffer_pool_acquire_buffer() fails and queueRequest()
returns -ENOBUFS.

The source task retries on -ENOBUFS far faster than requests complete, so most
controls an application sets on a playing pipeline are consumed by a request
that is never queued. Measured on an OV5675 behind the software ISP, 640x480
into fakesink: of 150 changes to the "saturation" property over 1.5 s, none
reached the IPA. Re-sending each value until the request metadata confirmed it
landed 2 of 20, after 919 attempts in all, so retrying from the application is
not a workaround. Controls set before PLAYING are unaffected, as setCamera()
rebuilds the pending controls from the accumulator.

Apply the controls after the buffer acquisition loop instead, so that they are
only consumed once the request is known to be queueable. The same test then
reports 49 of 150, which is all of them: only about 45 requests are queued in
1.5 s.

This change was made with the assistance of Claude Code; the behaviour
described above was measured on the affected machine.

Signed-off-by: Tatsuki Sugiura <sugi@nemui.org>
---
 src/gstreamer/gstlibcamerasrc.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Patch
diff mbox series

diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index 9541aa3..e408d72 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -186,9 +186,6 @@  int GstLibcameraSrcState::queueRequest()
 	if (!request)
 		return -ENOMEM;
 
-	/* Apply controls */
-	controls_.applyControls(request);
-
 	std::unique_ptr<RequestWrap> wrap =
 		std::make_unique<RequestWrap>(std::move(request));
 
@@ -210,6 +207,13 @@  int GstLibcameraSrcState::queueRequest()
 		wrap->attachBuffer(srcpad, buffer);
 	}
 
+	/*
+	 * Apply the controls now that the request is known to be queueable.
+	 * applyControls() consumes the pending controls, so calling it before
+	 * the buffers are acquired would drop them along with the request.
+	 */
+	controls_.applyControls(wrap->request_);
+
 	GST_TRACE_OBJECT(src_, "Requesting buffers");
 
 	{