Skip to content

isp: wait 200 ms for AE to settle, not a full second - #334

Open
vrilutza wants to merge 2 commits into
patjak:masterfrom
vrilutza:ae-settle-200ms
Open

isp: wait 200 ms for AE to settle, not a full second#334
vrilutza wants to merge 2 commits into
patjak:masterfrom
vrilutza:ae-settle-200ms

Conversation

@vrilutza

@vrilutza vrilutza commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

The auto-exposure wait in fthd_start_channel() goes from mdelay(1000) to msleep(200). It is paid on every VIDIOC_STREAMON, not once per open.

Two commits, because they do different things. Measured on a MacBookPro14,1, mean of five repetitions each against a module built from clean master, min and max in brackets:

                     STREAMON              system CPU burned
master               1078 ms [1077-1081]      986 ms [978-991]
+ msleep             1097 ms [1091-1103]        1 ms [1-1]
+ msleep + 200 ms     288 ms [287-294]           1 ms [0-1]

The msleep shortens nothing — it stops burning a CPU for the second. The 200 ms is what shortens the wait. Taking the value change without the msleep would mean 200 ms of a busy-held CPU instead of 1000, which is an improvement of the wrong kind, so both are here.

Why 200. The value has been 1000 ms since 2015 and there is nothing in the history behind it. Sweeping it as a module parameter, four interleaved repetitions per value with the light held constant, each run compared against its own final brightness: from 100 ms up the first frame already has the brightness the stream settles on; at 50 ms and below it comes out black. Repeated with 60 s of idle before each run so the exposure could not start from the previous state — 100 ms still good, three times out of three. 200 ms is twice the smallest value that worked.

Worth pointing at: a full second is not even the better choice. It delivers a first frame 10% brighter than where the stream settles, where 100 ms lands on it.

What this does not cover. One camera, and the measurement is of luma only — if the wait was also protecting the white balance, this would not have seen it. The driver also still waits blind rather than polling the firmware's CISP_CMD_CH_AE_* state; if someone who knows the ISP wants to replace the wait with a poll, this patch should be thrown away in favour of that.


The series

Seven PRs on this driver, all on master (364b1c6), all found while debugging a camera problem on a MacBookPro14,1:

#328 two small cleanups: missing break, hardcoded buffer count
#329 control values discarded at every VIDIOC_STREAMON
#330 cmd.y1 never assigned in the crop command — one line
#331 ALIGN(width, 7) aligns nothing; second commit re-does 545cb18 and should wait
#332 one firmware timeout leaves the driver with no usable buffers
#333 the camera writes in front of any buffer that is not page aligned
#334 (this one) the auto-exposure wait: 1000 ms → 200 ms

They can be taken in any order, with one exception: the second commit of #331 should not be taken yet — reasons in that PR.

(Until 23 August there was a second exception: #328 and #334 both carried the same mdelaymsleep commit, so whichever merged first made the other conflict. I have dropped it from #328; it lives in #334. The seven are now independent of each other.)

There is one more patch not sent yet: the channel-start crop returns the top left corner of the frame at any size below the sensor. It is measured and ready, and it sits on top of #330. I am holding it back rather than adding an eighth PR to the pile.

fthd_start_channel() ends with mdelay(1000), which busy-waits with the
CPU held for a full second. It runs from the vb2 start_streaming
callback, in process context with the queue mutex held, so it is allowed
to sleep.

Every VIDIOC_STREAMON pays this, and so does every format
renegotiation, which is a visible stall in applications that switch
resolution or restart capture.

Measured on a MacBookPro14,1 by timing the VIDIOC_STREAMON ioctl and
reading the calling process' rusage across it, five repetitions, median
[min-max]:

	                  STREAMON            system CPU
	clean master      1078 ms [1077-1081]  986 ms [978-991]
	with this change  1097 ms [1091-1103]    1 ms [1-1]

The wait itself is unchanged -- both wait a second -- so this does not
make streaming start any sooner. It gives the second back to the rest of
the system.

Signed-off-by: Viorel Cernateanu <vrilutza@gmail.com>
Comment thread fthd_isp.c Outdated
/* Wait for the exposure to settle before the first frame goes out. The value
* has been 1000 ms since the first version of the driver, with nothing in the
* history behind the number, and it is paid on every VIDIOC_STREAMON rather
* than once per open. */

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Needed to settle AE" is enough to understand why it's needed. The comment can be removed since it is found in the commit message. 200ms seems fine for now but we might want to fine-tune it in the future. It would be interesting to see what the Apple driver does.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is back to just /* Needed to settle AE */.

On the Apple driver: I do not have it, so I cannot answer that part. The 200 ms is twice the smallest value that still gave a settled first frame in the sweep in the commit message — happy to move it if you find a better number.

The wait is paid on every VIDIOC_STREAMON, not once per open. The value
has been 1000 ms since 2015 and there is nothing in the history behind
it.

Measured on a MacBookPro14,1 by turning it into a module parameter and
sweeping it, four interleaved repetitions per value with the light held
constant, each run compared against its own final brightness:

	ae_ms   STREAMON   first frame   black frames
	 1000     1103 ms      110%           0
	  200      297 ms      102%           0
	  100      196 ms      101%           0
	   50      144 ms        1%           1

From 100 ms up the first frame is already at the brightness the stream
settles on; below that it comes out black. Note that a full second is
not even the better choice -- it delivers a first frame 10% brighter
than where the stream settles.

Repeated with 60 s of idle before each run, so the exposure could not
start from the state left by the previous one: 100 ms still gives a good
first frame, three times out of three. 200 ms is twice the smallest
value that worked, on the only camera I have.

The measurement is of luma only, so if the wait was also protecting the
white balance this would not have seen it.

Signed-off-by: Viorel Cernateanu <vrilutza@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants