v4l2: apply the control values userspace set before STREAMON - #329
Merged
patjak merged 1 commit intoSep 4, 2026
Merged
Conversation
This was referenced Jul 30, 2026
vrilutza
force-pushed
the
controls-at-streamon-and-width-align
branch
from
August 22, 2026 08:53
a9457b3 to
4b7d5e3
Compare
vrilutza
added a commit
to vrilutza/facetimehd
that referenced
this pull request
Aug 22, 2026
VIDIOC_ENUM_FRAMESIZES advertises a single discrete size while fthd_v4l2_adjust_format() clamps to FTHD_MIN_WIDTH/HEIGHT at the bottom and to the detected sensor size at the top, with the scaler covering everything between. VIDIOC_ENUM_FRAMEINTERVALS already accepts any width that is a multiple of eight up to the maximum, so the enumeration is the only place claiming the device does one size and nothing else. Applications that pick a resolution from the enumeration therefore never offer anything below the sensor's native size, even though the hardware scales down. In issue patjak#52 the reporter had to hand-edit Skype's shared.xml to force 640x480 and then 320x240 before the camera would work at all, and issue patjak#243 is a user asking why the enumeration shows one size; neither needed a driver change to capture at the smaller sizes, only a way to find out they exist. Report a stepwise range matching what adjust_format() does, keeping the sensor detection from 98b55fd as the upper bound: FTHD_MIN_WIDTH to the sensor width in steps of 8, FTHD_MIN_HEIGHT to the sensor height in steps of 1. The horizontal step of 8 is the constraint enum_frameintervals() has always enforced. Nothing enforces one vertically, and heights of 241, 245 and 481 were verified to capture correctly, so the vertical step is 1. Tested on a MacBookPro14,1, where CISP_CMD_CH_CAMERA_CONFIG_GET reports a 1296x736 sensor, so the upper bound comes from the detection rather than from FTHD_MAX_WIDTH/HEIGHT: [0]: 'YUYV' (YUYV 4:2:2) Size: Stepwise 320x240 - 1296x736 with step 8/1 and it takes v4l2-compliance 1.32.0 from "test Scaling: FAIL" to "test Scaling: OK". Depends on "v4l2: align the width to 8, not to 7" (patjak#329); without it the driver would advertise a step of 8 that adjust_format() does not honour. It should also not go in ahead of "isp: crop a centred window with the aspect ratio of the output" (patjak#330). Until that one is in, fthd_start_channel() asks the ISP for a crop window the size of the output placed at the sensor origin, so every size below the sensor comes back as the top left corner of the frame. Advertising the range first would hand applications exactly the resolutions that are framed wrong. Signed-off-by: Viorel Cernateanu <vrilutza@gmail.com> (cherry picked from commit 9992af1)
vrilutza
force-pushed
the
controls-at-streamon-and-width-align
branch
2 times, most recently
from
August 22, 2026 10:00
d66f0ca to
30f3ac7
Compare
This was referenced Aug 22, 2026
vrilutza
force-pushed
the
controls-at-streamon-and-width-align
branch
from
August 23, 2026 15:43
30f3ac7 to
8d14425
Compare
patjak
reviewed
Sep 2, 2026
| * away whatever userspace had set through VIDIOC_S_CTRL. The control | ||
| * values are pushed to the ISP from fthd_start_streaming() instead, | ||
| * once the channel is up. | ||
| */ |
Owner
There was a problem hiding this comment.
There is no need to explain what the code used to do here. Just removing the brightness and contrast commands is enough.
fthd_start_channel() programmed brightness and contrast to 0x80 unconditionally, so every VIDIOC_STREAMON discarded whatever userspace had configured. VIDIOC_G_CTRL kept reporting the requested value, because the control framework caches it, so the control read back correctly while the ISP ran with the default. Drop the two hardcoded commands and call v4l2_ctrl_handler_setup() once the channel is up. That covers saturation, hue and auto white balance too, which had the same problem. Measured on a MacBookPro14,1 at 640x360, mean luma of a frame taken with brightness set to 40 before STREAMON, against the same value set while streaming and against the default of 128: clean master with this patch set before STREAMON 37.38 0.02 set while streaming 0.01 0.01 default, 128 37.46 34.29 On master the pre-STREAMON frame matches the default rather than the value it asked for: the setting was discarded. With the patch it matches the value set while streaming, which is the negative control taken in the same run. Signed-off-by: Viorel Cernateanu <vrilutza@gmail.com>
vrilutza
force-pushed
the
controls-at-streamon-and-width-align
branch
from
September 3, 2026 11:51
8d14425 to
78e72b4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fthd_start_channel()forces brightness and contrast to0x80, so everyVIDIOC_STREAMONthrows away whatever the application had set.VIDIOC_G_CTRLkeeps reporting the value that was asked for, which is what makes it hard to see: the control reads back correctly while the ISP runs with the default.Drop the two hardcoded commands and call
v4l2_ctrl_handler_setup()once the channel is up. That covers saturation, hue and auto white balance too, which had the same problem.Measured on a MacBookPro14,1 against a module built from clean master. One
open(), four frames from the same file descriptor, 20 frames dropped between each so the exposure settles. Mean luma of the Y plane at 640x360:Before the change, brightness 40 set before
STREAMONgives the same picture as the default — not as 40. The third row is the negative control taken in the same run: the setting does work, it is only the pre-STREAMONvalue that is lost. The two master columns are the same module measured twice, interleaved with the patched one; absolute values move with the ambient light, the relation does not.After the change, the first row matches the third rather than the fourth.
The series
Seven PRs on this driver, all on master (
364b1c6), all found while debugging a camera problem on a MacBookPro14,1:break, hardcoded buffer countVIDIOC_STREAMONcmd.y1never assigned in the crop command — one lineALIGN(width, 7)aligns nothing; second commit re-does 545cb18 and should waitThey 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
mdelay→msleepcommit, 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.