Raspberry Pi v2 camera unexpectedly high frame rate

I am trying to get my Raspberry Pi v2 NoIR camera to run at 120fps. I was only expecting to manage this as VGA 640x480 resolution, but in fact, I can set the resolution to 1280x720 and get 120fps. (CPU utilisation is very high at 70% but such is life…)

This page suggests also that at 1280x720 you should only get 90fps. How is it that I am getting 120fps?

https://www.raspberrypi.org/documentation/raspbian/applications/camera.md

Taken from this page OpenCV GStreamer Capture really slow I was able to run this command to double check and it does seem to be about 120fps:

nano@nano-desktop:~$ gst-launch-1.0 -v nvarguscamerasrc exposuretimerange="1 1" gainrange="1 1" ! 'video/x-raw(memory:NVMM), format=NV12,width=1280, height=720, framerate=120/1' ! fpsdisplaysink video-sink=fakesink text-overlay=false
GST_ARGUS: NvArgusCameraSrc: Setting Exposure Time Range : 1 1
GST_ARGUS: Invalid Exposure Time Range Input
GST_ARGUS: NvArgusCameraSrc: Setting Gain Range : 1 1
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstFakeSink:fakesink0: sync = true
Setting pipeline to PLAYING ...
New clock: GstSystemClock
/GstPipeline:pipeline0/GstNvArgusCameraSrc:nvarguscamerasrc0.GstPad:src: caps = video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)120/1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)120/1
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0.GstGhostPad:sink.GstProxyPad:proxypad0: caps = video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)120/1
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstFakeSink:fakesink0.GstPad:sink: caps = video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)120/1
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0.GstGhostPad:sink: caps = video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)120/1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)120/1
GST_ARGUS: Creating output stream
CONSUMER: Waiting until producer is connected...
GST_ARGUS: Available Sensor modes :
GST_ARGUS: 3264 x 2464 FR = 21.000000 fps Duration = 47619048 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 3264 x 1848 FR = 28.000001 fps Duration = 35714284 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1920 x 1080 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1280 x 720 FR = 59.999999 fps Duration = 16666667 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1280 x 720 FR = 120.000005 fps Duration = 8333333 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: Running with following settings:
   Camera index = 0 
   Camera mode  = 4 
   Output Stream W = 1280 H = 720 
   seconds to Run    = 0 
   Frame Rate = 120.000005 
GST_ARGUS: Setup Complete, Starting captures for 0 seconds
GST_ARGUS: Starting repeat capture requests.
CONSUMER: Producer has connected; continuing.
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstFakeSink:fakesink0: sync = true
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 60, dropped: 0, current: 119.22, average: 119.22
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 119, dropped: 0, current: 116.55, average: 117.88
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 178, dropped: 0, current: 116.27, average: 117.34
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 237, dropped: 0, current: 116.56, average: 117.15
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 296, dropped: 0, current: 116.41, average: 117.00
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 355, dropped: 0, current: 116.56, average: 116.93
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 414, dropped: 0, current: 116.46, average: 116.86
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 473, dropped: 0, current: 116.48, average: 116.81
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 532, dropped: 0, current: 116.53, average: 116.78
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 590, dropped: 0, current: 114.47, average: 116.55
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 649, dropped: 0, current: 116.49, average: 116.54
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 708, dropped: 0, current: 116.52, average: 116.54
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 767, dropped: 0, current: 116.40, average: 116.53
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 826, dropped: 0, current: 116.49, average: 116.53
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 885, dropped: 0, current: 116.53, average: 116.53
/GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 944, dropped: 0, current: 116.42, average: 116.52
^Chandling interrupt.
Interrupt: Stopping pipeline ...
Execution ended after 0:00:08.859841917
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
GST_ARGUS: Cleaning up
CONSUMER: Done Success
GST_ARGUS: Done Success
Setting pipeline to NULL ...
Freeing pipeline ...

When I run the v4l2-ctl command, I see that only 60fps should be possible:

nano@nano-desktop:~$ v4l2-ctl --device /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'RG10'
	Name        : 10-bit Bayer RGRG/GBGB
		Size: Discrete 3264x2464
			Interval: Discrete 0.048s (21.000 fps)
		Size: Discrete 3264x1848
			Interval: Discrete 0.036s (28.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.017s (60.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.017s (60.000 fps)

Is libargus (?) doing frame doubling or am I actually getting 116.5 unique frames per second?

Many thanks as usual.

hello jetsonnvidia,

there’s known issue that v4l2-ctl cannot report different frame-rate with same resolution table, that’s why you’ll see two 1280x720 sensor mode with 60-fps.

may I have your confirmation that you’re having only single camera device connected?
thanks

1 Like

hello jetsonnvidia,

I’ve check the sensor table imx219_mode_tbls.h of Raspberry Pi v2, IMX219.
there’s 120-fps sensor modes for 1280x720.
for example,

static const struct camera_common_frmfmt imx219_frmfmt[] = {
...
        {{1280, 720},   imx219_60fps, 1, 0, IMX219_MODE_1280x720_60FPS},
        {{1280, 720},   imx219_120fps, 1, 0, IMX219_MODE_1280x720_120FPS},

I am not sure what’s additional post-processing was done on Raspberry Pi,
since you’re using nvarguscamerasrc plugin to have fixed exposure time range, you’re actually launch 120-fps sensor mode and getting ~120 frames per second.
thanks

1 Like

I am using the first version of the Nano development board so have only one CSI camera attached.

Thanks for the info about the bug. I streamed a recording to H264 and was able to achieve 116.5fps. I verified the video by filming my hand moving and was able to see each frame is unique. This is excellent to see, so I can confirm that the Nano can do 116.5fps with the Raspberry Pi v2 camera.