aboutsummaryrefslogtreecommitdiffci
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
-rw-r--r--patches/0002-pipeline-simple-capture-bayer-order-from-mbus-code.patch59
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();
+ }
+