Closed aaronwmorris closed 1 year ago
If either AWB or AGC is enabled, the algorithm consumes a number of frames (usually 5 or so) to converge on target R/B gain and shutter/analoge gain values (respectively). Now you've set a manual shutter speed of 5 seconds, so the 5 frames of convergence are going to take 25 seconds to complete.
As a side node, something looks to be wrong in either the imx462 device driver or the camera helper. In your AWB-off case, you asked for an exposure of 5 seconds, but the capture completes in just over 1 second. This implies the shutter speed calculations are wrong. You should raise this with Arducam.
As a side node, something looks to be wrong in either the imx462 device driver or the camera helper. In your AWB-off case, you asked for an exposure of 5 seconds, but the capture completes in just over 1 second. This implies the shutter speed calculations are wrong. You should raise this with Arducam.
imx290 (supporting imx327, imx290, and imx462) is a native driver in our tree (and mainline), so one for me to look at. I suspect it may be a corrupt first frame issue.
Arducam do have a PiVariety version of imx462, and that we don't care about.
Running an IMX327 as that came to hand first.
Setting bcm2835_unicam module parameter debug to 5, and dev_debug in /sys/class/video4linux/video0 to 0x0a (V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARGS | V4L2_DEV_DEBUG_STREAMING - https://elixir.bootlin.com/linux/latest/source/include/media/v4l2-ioctl.h#L595) Logs:
[ 1386.118744] video0: VIDIOC_STREAMON: type=vid-cap
[ 1386.131183] unicam fe801000.csi: Running with 2 data lanes
[ 1386.307283] video0: VIDIOC_QBUF: 00:00:00.000000 index=0, type=vid-cap, request_fd=0, flags=0x00002002, field=any, sequence=0, memory=dmabuf, bytesused=3110400, offset/userptr=0x14, length=3112960
[ 1386.307312] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 1386.307410] unicam fe801000.csi: ISR: ISTA: 0x1, STA: 0x4002, sequence 0, lines done 0
[ 1386.307417] unicam fe801000.csi: Scheduling dummy buffer for node 0
[ 1386.307545] video0: VIDIOC_DQEVENT: type=0x4, pending=0, sequence=0, id=0, timestamp=1386.292559643
[ 1386.307563] frame_sequence=0
[ 1386.312804] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x5001, sequence 0, lines done 270
[ 1386.317954] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4003, sequence 0, lines done 540
[ 1386.323102] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4001, sequence 0, lines done 810
[ 1386.328251] unicam fe801000.csi: ISR: ISTA: 0x0, STA: 0xC002, sequence 0, lines done 1080
[ 1386.328290] video0: VIDIOC_DQBUF: 00:23:06.292554 index=0, type=vid-cap, request_fd=0, flags=0x00002000, field=any, sequence=0, memory=dmabuf, bytesused=3110400, offset/userptr=0x14, length=3112960
[ 1386.328314] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 1386.409017] video0: VIDIOC_STREAMOFF: type=vid-cap
118ms from STREAMON to frame start, so the sensor is doing the wrong thing.
If I stream with v4l2-ctl without changing any modes, then I get
[ 4119.024217] video0: VIDIOC_STREAMON: type=vid-cap
[ 4119.024300] video0:
[ 4119.024298] unicam fe801000.csi: ISR: ISTA: 0x1, STA: 0x4002, sequence 0, lines done 0
[ 4119.024312] VIDIOC_G_FMT:
[ 4119.024322] unicam fe801000.csi: Scheduling dummy buffer for node 0
[ 4119.024337] type=vid-cap, width=1920, height=1080, pixelformat=pRCC little-endian (0x43435270), field=none, bytesperline=2880, sizeimage=3110400, colorspace=11, flags=0x0, ycbcr_enc=0, quantization=0, xfer_func=0
[ 4119.029691] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x5001, sequence 0, lines done 270
[ 4119.034840] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4003, sequence 0, lines done 540
[ 4119.039989] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4001, sequence 0, lines done 810
[ 4119.045138] unicam fe801000.csi: ISR: ISTA: 0x0, STA: 0xC002, sequence 0, lines done 1080
[ 4119.045195] video0: VIDIOC_DQBUF: 01:08:38.985014 index=0, type=vid-cap, request_fd=0, flags=0x00002001, field=any, sequence=0, memory=mmap, bytesused=3110400, offset/userptr=0x0, length=3110400
[ 4119.045269] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 4119.045401] video0: VIDIOC_QBUF: 00:00:00.000000 index=0, type=vid-cap, request_fd=0, flags=0x00002003, field=any, sequence=0, memory=mmap, bytesused=3110400, offset/userptr=0x0, length=3110400
[ 4119.045463] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 4124.023602] unicam fe801000.csi: ISR: ISTA: 0x1, STA: 0x4000, sequence 1, lines done 0
[ 4124.023625] unicam fe801000.csi: Scheduling dummy buffer for node 0
[ 4124.028994] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x5003, sequence 1, lines done 270
[ 4124.034142] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4001, sequence 1, lines done 540
[ 4124.039291] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4003, sequence 1, lines done 810
[ 4124.044440] unicam fe801000.csi: ISR: ISTA: 0x0, STA: 0xC000, sequence 1, lines done 1080
[ 4124.044508] video0: VIDIOC_DQBUF: 01:08:43.984231 index=1, type=vid-cap, request_fd=0, flags=0x00002001, field=any, sequence=1, memory=mmap, bytesused=3110400, offset/userptr=0x2f8000, length=3110400
[ 4124.044582] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 4124.044686] video0: VIDIOC_QBUF: 00:00:00.000000 index=1, type=vid-cap, request_fd=0, flags=0x00002003, field=any, sequence=0, memory=mmap, bytesused=3110400, offset/userptr=0x2f8000, length=3110400
[ 4124.044747] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 4129.022902] unicam fe801000.csi: ISR: ISTA: 0x1, STA: 0x4002, sequence 2, lines done 0
[ 4129.022924] unicam fe801000.csi: Scheduling dummy buffer for node 0
[ 4129.028295] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x5001, sequence 2, lines done 270
[ 4129.033445] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4003, sequence 2, lines done 540
[ 4129.038593] unicam fe801000.csi: ISR: ISTA: 0x4, STA: 0x4001, sequence 2, lines done 810
[ 4129.043743] unicam fe801000.csi: ISR: ISTA: 0x0, STA: 0xC002, sequence 2, lines done 1080
[ 4129.043810] video0: VIDIOC_DQBUF: 01:08:48.983443 index=2, type=vid-cap, request_fd=0, flags=0x00002001, field=any, sequence=2, memory=mmap, bytesused=3110400, offset/userptr=0x5f0000, length=3110400
[ 4129.043884] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 4129.043977] video0: VIDIOC_QBUF: 00:00:00.000000 index=2, type=vid-cap, request_fd=0, flags=0x00002003, field=any, sequence=0, memory=mmap, bytesused=3110400, offset/userptr=0x5f0000, length=3110400
[ 4129.044037] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
[ 4129.525743] video0: VIDIOC_DQBUF: error -512: 00:00:00.000000 index=0, type=vid-cap, request_fd=0, flags=0x00000000, field=any, sequence=0, memory=mmap, bytesused=0, offset/userptr=0x0, length=0
[ 4129.525831] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000
Timestamps of 01:08:38.985014 01:08:43.984231 01:08:48.983443 are almost spot on the 5second period requested, but again only 81ms from STREAMON to first frame.
Having looked at the captured frames from it, the first is recognizable, whilst the following frames are totally blown out, so that largely confirms that the exposure on the first frame is incorrect.
In the normal manner that datasheets are unhelpful on details, it does list that "After standby mode is canceled, a normal image is output from 9 frames after the internal regulator stabilzation (20ms or more). The 20ms regulator stabilization is compensated for by an msleep(30) in imx290_start_streaming, but nothing is done over the initial 8 frames.
https://git.linuxtv.org/libcamera.git/tree/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp#n59 does set hideFramesModeSwitch
to 1, so does that frame not get dropped?
Patch to libcamera:
src/ipa/rpi/cam_helper/cam_helper_imx290.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp
index 7d6f5b549a73..b8914bf93ecb 100644
--- a/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp
+++ b/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp
@@ -19,6 +19,7 @@ public:
double gain(uint32_t gainCode) const override;
void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay, int &hblankDelay) const override;
+ unsigned int hideFramesStartup() const override;
unsigned int hideFramesModeSwitch() const override;
private:
@@ -54,6 +55,12 @@ void CamHelperImx290::getDelays(int &exposureDelay, int &gainDelay,
hblankDelay = 2;
}
+unsigned int CamHelperImx290::hideFramesStartup() const
+{
+ /* On startup, we seem to get 1 bad frame. */
+ return 1;
+}
+
unsigned int CamHelperImx290::hideFramesModeSwitch() const
{
/* After a mode switch, we seem to get 1 bad frame. */
--
2.34.1
fixes it for me so that the first frame is dropped on startup, as well as on mode switch. I'll leave it to naushir to upstream that.
I'll close this now as the fix should be merged into libcamera repos shortly.
Describe the bug Long exposures appear to be broken on imx462 cameras when AWB is disabled.
AWB enabled
I am not sure why the exposure is taking 20s in the first example. It could be the AWB code, but there should be enough illumination for this to not happen.
AWB Disabled
Exposure is received in less than 2 seconds. The same thing happens no matter how long of an exposure.
Bug report