| author | 2026-09-07 18:27:22 +0700 | |
|---|---|---|
| committer | 2026-09-07 18:27:22 +0700 | |
| commit | 1940f4bb7b89a3b04bd0d5f02d0198aa99e5930f (patch) | |
| tree | 70aeffe7e219763634391676f8851bd0624e011c /patches/0002-pipeline-simple-capture-bayer-order-from-mbus-code.patch | |
| parent | 6d105f40c8ce52bfc3d09e038471a09702857de2 (diff) | |
| download | libcamera-1940f4bb7b89a3b04bd0d5f02d0198aa99e5930f.tar.gz libcamera-1940f4bb7b89a3b04bd0d5f02d0198aa99e5930f.zip | |
fix: pipeline: simple: take the capture bayer order from mbus code
fixes the issue with rear camera breaking video devices
Diffstat (limited to 'patches/0002-pipeline-simple-capture-bayer-order-from-mbus-code.patch')
| -rw-r--r-- | patches/0002-pipeline-simple-capture-bayer-order-from-mbus-code.patch | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/patches/0002-pipeline-simple-capture-bayer-order-from-mbus-code.patch b/patches/0002-pipeline-simple-capture-bayer-order-from-mbus-code.patch new file mode 100644 index 0000000..ac0298a --- /dev/null +++ b/patches/0002-pipeline-simple-capture-bayer-order-from-mbus-code.patch @@ -0,0 +1,59 @@ +pipeline: simple: Take the capture Bayer order from the reported media bus code + +When the media bus code that reaches the video node differs from the one the +pipeline was enumerated with, the simple pipeline handler recomputes the Bayer +order for the capture device by applying the configured transform to the +sensor's native order. That assumes the sensor's flip controls mirror the pixel +array and nothing else, so that the order after flipping is the mirror of the +order before it. + +The OV13858 on the Microsoft Surface Pro 12in breaks that assumption. It +reports V4L2_CTRL_FLAG_MODIFY_LAYOUT on V4L2_CID_HFLIP, so libcamera treats +flips as altering the Bayer order, and the sensor is mounted upside down +(camera_sensor_rotation is 180), so libcamera flips it to compensate. The +driver, however, keeps reporting SRGGB10_1X10 in every flip state, and +measurements off the CAMSS RDI video node with the sensor's own colour bar +pattern show that the flipped sensor really does emit RGGB, while the derived +order is GBRG: + + flips 0/0: greens on (0,0)/(1,1), i.e. GBRG emitted, SRGGB10 reported + flips 1/1: greens on (0,1)/(1,0), i.e. RGGB emitted, SRGGB10 reported + +The capture device is therefore configured as GBRG while every subdev along the +pipeline reports RGGB. camss validates exactly that pair in its +video_check_format(), so VIDIOC_STREAMON fails and the camera never produces a +frame: + + ERROR V4L2 v4l2_videodevice.cpp:1998 /dev/video2[57:cap]: Failed to start streaming: Broken pipe + +Derive the order from the code the pipeline actually reports instead. For a +sensor whose driver does change its code on flip the two are identical, so +nothing changes there, and for a driver that compensates the flip internally +the capture device now agrees with the subdev it is fed from. + +--- a/src/libcamera/pipeline/simple/simple.cpp ++++ b/src/libcamera/pipeline/simple/simple.cpp +@@ -1529,12 +1529,19 @@ + videoFormat = video->toV4L2PixelFormat(pipeConfig->captureFormat); + } else { + /* +- * Bayer pattern has changed because of the transform that was applied on +- * the sensor. Get the V4L2PixelFormat corresponding to the configured Bayer +- * pattern. ++ * The media bus code reaching the video node is not the one the ++ * pipeline was enumerated with, which for a Bayer sensor means ++ * the pattern changed, typically because a transform was ++ * applied to the sensor. ++ * ++ * Take the order from the code the pipeline actually reports ++ * rather than deriving it from the transform. A driver is free ++ * to compensate a flip internally, in which case the derived ++ * order and the reported one disagree, and it is the reported ++ * one that the capture device is validated against. + */ + BayerFormat cfgBayer = BayerFormat::fromPixelFormat(pipeConfig->captureFormat); +- cfgBayer.order = data->sensor_->bayerOrder(config->combinedTransform()); ++ cfgBayer.order = BayerFormat::fromMbusCode(format.code).order; + videoFormat = cfgBayer.toV4L2PixelFormat(); + } + |