Arducam Camarray Hat Quad camera on Jetson Nano only outputs half selected framerate in GStreamer

Hi everyone, I’m stuck on a framerate issue with the Camarray Hat Quad Camera module (SKU B0397, 12MP4 Quadrascopic Camera Bundle Kit) on a Jetson Nano. The cameras are supposed to run at 10, 40, and 50 fps depending on the mode, but I’m only getting exactly half of whatever framerate I select. For example, camera mode 2 with Frame Rate = 50.000000 only outputs frames at around 25 fps. I’ve tried running the cameras a number of different ways with several GStreamer pipelines, and I’ve tested on two different Jetsons and two different multicam boards, so I don’t think it’s a hardware issue. Any ideas?

Thanks for the report. Can you share a bit more about your environment - the hardware, software stack, and how you’ve defined the camera modes? Also, the GStreamer pipeline template you’re using would help narrow things down.

Sure. Hardware is a Jetson Nano with the Arducam Camarray Hat Quad Camera module (SKU B0397). Software side is Python using GStreamer (Gst, GstRtspServer, GLib, GObject), and I’m running with GST_DEBUG=3. The camera modes I’ve defined are:

  • Mode 0: resolution [3040, 4056] (height, width), framerate 10
  • Mode 1: resolution [1520, 2028] (height, width), framerate 40
  • Mode 2: resolution [1080, 2028] (height, width), framerate 50

And the pipeline template I’m using is:
nvarguscamerasrc sensor-id={} aelock=true exposuretimerange=‘100000 10000000’ ! video/x-raw(memory:NVMM), format=NV12, width={}, height={}, framerate={}/1 ! nvvidconv flip-method=2 ! nvvidconv ! nvv4l2h265enc name=nv_encoder ! h265parse ! appsink name=sink emit-signals=True sync=True

Got it. Which device_idx and camera_mode are you using for the failing test? And can you paste the GST_ARGUS output showing the available sensor modes and the running settings? Also, how exactly are you measuring the fps?

For this test I’m using device_idx 0 and camera_mode 2. My appsink new-sample handler pulls the sample, extracts the buffer, prints the buffer length, and computes fps based on the time since the previous sample.

GST_ARGUS log shows the available sensor modes:

  • 4056 x 3040 FR = 10.000000 fps Duration = 100000000 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000
  • 2028 x 1520 FR = 40.000000 fps Duration = 25000000 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000
  • 2028 x 1080 FR = 50.000000 fps Duration = 20000000 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000

And the running settings:
GST_ARGUS: Running with following settings:

  • Camera index = 0
  • Camera mode = 2
  • Output Stream W = 2028 H = 1080
  • seconds to Run = 0
  • Frame Rate = 50.000000

Then it shows:
GST_ARGUS: Setup Complete, Starting captures for 0 seconds
GST_ARGUS: Starting repeat capture requests.

Thanks. Do you see any GStreamer warnings in the log while it runs? And what fps values are you actually measuring once the samples start flowing?

Yes, here are some warnings I see:

  • v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode: Failed to determine interlace mode (repeated)
  • v4l2 gstv4l2object.c:4476:gst_v4l2_object_probe_caps:<nv_encoder:src> Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: Unknown error -1
  • default gstutils.c:3981:gst_pad_create_stream_id_internal:nvarguscamerasrc0:src Creating random stream-id, consider implementing a deterministic way of creating a stream-id
  • v4l2bufferpool gstv4l2bufferpool.c:1087:gst_v4l2_buffer_pool_start:<nv_encoder:pool:src> Uncertain or not enough buffers, enabling copy threshold
  • v4l2bufferpool gstv4l2bufferpool.c:1536:gst_v4l2_buffer_pool_dqbuf:<nv_encoder:pool:src> Driver should never set v4l2_buffer.field to ANY
  • h265parse gsth265parse.c:1798:gst_h265_parse_parse_frame: Implement timestamp/duration interpolation based on SEI message (repeated)

Also NVMEDIA: H265 : Profile : 1

And the measured fps looks like this:

  • Received first sample, buffer len 10522, current fps = 0.2998456771699651
  • buffer len 11289, current fps = 29.251633690641412
  • buffer len 8845, current fps = 25.082399937806855
  • buffer len 9790, current fps = 25.816662050287754
  • buffer len 8254, current fps = 24.31522867064355
  • buffer len 7558, current fps = 27.142679643818596
  • buffer len 7259, current fps = 24.264027166335957

Thanks for the detailed logs. I think I see what’s happening here. The Camarray HAT Quad Camera module’s uploading framerate is the single camera’s framerate. When you use this module, the four cameras are shown at the same time, which cuts the framerate to half. That matches your observation exactly - you select Camera mode = 2 with Frame Rate = 50.000000, and the measured output lands around 24-27 fps.

Ah, that makes sense. So the 25.082399937806855, 25.816662050287754, 24.31522867064355, 27.142679643818596, and 24.264027166335957 values are basically half of 50 with some jitter? I was worried something was wrong with my pipeline.

Right, that’s the root cause. The Camarray HAT Quad Camera module outputs the four cameras simultaneously (quad view), so the effective framerate of the combined output is half of the single camera’s framerate. Your pipeline itself is fine - those warnings are mostly non-fatal GStreamer noise. This halved framerate behavior is actually expected for this module and is listed on the product page.

Just to summarize the key point: a single camera runs at its specified mode framerate (e.g., 10/40/50 fps), but when the quad camera module displays all four cameras at once, the resulting framerate is cut in half. You can check the listed framerate information here: https://www.arducam.com/product/12mp4-quadrascopic-camera-bundle-kit-b0397/