Why v4l2-ctrl takes 5 frames insted of 1 frame?

Hello,

I am trying to capture a single frame on IMX264 using v4l2-ctrl command given bellow.

v4l2-ctl -V --set-fmt-video=width=2464,height=2058,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=1 --stream-to=imx264.raw -d /dev/video1

In dmesg it shows 5 frames are captured.

[  467.367208] imx264 31-0010: imx264_power_on: power on
[  467.373671] nvcsi 150c0000.nvcsi: csi port:0
[  467.378555] nvcsi 150c0000.nvcsi: csi port:2
[  467.383034] nvcsi 150c0000.nvcsi: csi port:4
[  467.423510] tegra-vi4 15700000.vi: Create Surface with imgW=2464, imgH=2058, memFmt=32
[  467.432246] nvcsi 150c0000.nvcsi: csi4_start_streaming ports index=2, lanes=4
[  467.439407] nvcsi 150c0000.nvcsi: csi4_stream_init
[  467.444221] nvcsi 150c0000.nvcsi: csi4_stream_config
[  467.449200] nvcsi 150c0000.nvcsi: csi4_stream_config (2) read VC0_DPCM_CTRL = 00000000
[  467.457124] nvcsi 150c0000.nvcsi: csi4_phy_config
[  467.461836] nvcsi 150c0000.nvcsi: NVCSI_CIL_CONFIG = 00000000
[  467.467596] nvcsi 150c0000.nvcsi: cil_settingtime is pulled from device
[  467.474211] nvcsi 150c0000.nvcsi: cil core clock: 204, csi clock: 102
[  467.480657] nvcsi 150c0000.nvcsi: cil_settingtime was autocalculated
[  467.487014] nvcsi 150c0000.nvcsi: csi settle time: 33, cil settle time: 25
[  467.493908] imx264 31-0010: imx264_s_stream++ enable 1
[  467.586715] video4linux video1: tegra_channel_capture_frame: vi4 got SOF syncpt buf[ffffffc07a97b000]
[  467.595951] video4linux video1: tegra_channel_release_frame: vi4 got EOF syncpt buf[ffffffc07a97b000]
[  467.605174] video4linux video1: release_buffer: capture init latency is 183 ms
[  467.612404] video4linux video1: release_buffer: release buf[ffffffc07a97b000] <b>frame[1]</b> to user-space
[  467.720022] video4linux video1: tegra_channel_capture_frame: vi4 got SOF syncpt buf[ffffffc07a978800]
[  467.729253] video4linux video1: tegra_channel_release_frame: vi4 got EOF syncpt buf[ffffffc07a978800]
[  467.738475] video4linux video1: release_buffer: release buf[ffffffc07a978800] <b>frame[2]</b> to user-space
[  467.853348] video4linux video1: tegra_channel_capture_frame: vi4 got SOF syncpt buf[ffffffc07a97a400]
[  467.862600] video4linux video1: tegra_channel_release_frame: vi4 got EOF syncpt buf[ffffffc07a97a400]
[  467.872032] video4linux video1: release_buffer: release buf[ffffffc07a97a400] <b>frame[3]</b> to user-space
[  467.986670] video4linux video1: tegra_channel_capture_frame: vi4 got SOF syncpt buf[ffffffc07a978000]
[  467.995970] video4linux video1: tegra_channel_release_frame: vi4 got EOF syncpt buf[ffffffc07a978000]
[  468.005215] video4linux video1: release_buffer: release buf[ffffffc07a978000] <b>frame[4]</b> to user-space
[  468.041854] video4linux video1: release_buffer: release buf[ffffffc07a97b000] <b>frame[5]</b> to user-space
[  468.051153] imx264 31-0010: imx264_s_stream++ enable 0
[  468.077525] nvcsi 150c0000.nvcsi: csi4_stop_streaming ports index=0, lanes=4
[  468.084598] nvcsi 150c0000.nvcsi: csi4_phy_config
[  468.089327] nvcsi 150c0000.nvcsi: NVCSI_CIL_CONFIG = 00000004
[  468.095089] nvcsi 150c0000.nvcsi: csi4_stream_check_status
[  468.100592] nvcsi 150c0000.nvcsi: csi4_cil_check_status 340
[  468.117252] imx264 31-0010: imx264_power_off: power off

Why It is capturing 5 frames instead of one frame?
Is there any way to capture only single frame?

hello Rathore0129,

  1. may I know which JetPack release you’re working with.
  2. there’s internal buffering, you might refer code snippet as below.
<i>$l4t-r32.1/kernel_src/kernel/nvidia/drivers/media/platform/tegra/camera/vi/channel.c</i>

void tegra_channel_ring_buffer(struct tegra_channel *chan,
                                        struct vb2_v4l2_buffer *vb,
                                        struct timespec *ts, int state)
{
...
        /* release buffer N at N+2 frame start event */
        if (chan->num_buffers >= (chan->capture_queue_depth - 1))
                free_ring_buffers(chan, 1);
  1. were you like to decrease the capture latency? may I know what’s your use-case, thanks

Hi Jerry,

  1. I am working with JetPack 3.3 (L4T 28.2.1 for Jetson TX2).
  2. In my source code I didn’t found “tegra_channel_ring_buffer” function. Is there any way to get only single frame with JetPack 3.3 (L4T 28.2.1 for Jetson TX2).
  3. I want to take synchronized images from sensors, so I think this can be helpful if it takes only single frame from each sensor.

You can refer link given bellow for better understanding of use-case.
https://devtalk.nvidia.com/default/topic/1055611/jetson-tx2/camera-syncronization-with-tegra-tx2/

hello Rathore0129,

In my source code I didn’t found “tegra_channel_ring_buffer” function.
I was sharing l4t-r32.1 kernel sources, please refer to below for JetPack 3.3

<i>$l4t-r28.2.1/kernel_src/kernel/kernel-4.4/drivers/media/platform/tegra/camera/vi/channel.c</i>

void tegra_channel_ring_buffer(struct tegra_channel *chan,
                                        struct vb2_v4l2_buffer *vb,
                                        struct timespec *ts, int state)
{
        ...
        /* release buffer N at N+2 frame start event */
        if (chan->num_buffers >= (QUEUED_BUFFERS - 1))
                free_ring_buffers(chan, 1);
}

Is there any way to get only single frame with JetPack 3.3 (L4T 28.2.1 for Jetson TX2).
you cannot, there’s ring buffer mechanism for the whole capture pipeline.
however, you should have post synchronization by using capture timestamp.
please also refer to similar topics for timestamp synchronization issues, Topic 1047944, Topic 1046381, and Topic 1038131.
thanks