Nvarguscamerasrc with gstreamer not reading max and min gain/exposure correctly from sensor in cpp lib

Configuraiton: orin nano 8 gb, custom carrier board (forecr dual lan) with an imx477 camera.

Issue: Migrating from jetpack 5.1.1 to 6.2.1. From the command line, I can run commands fine, but the same command using gstreamer objects in cpp causes weird flipped min/max values.

On the command line running:

gst-launch-1.0 nvarguscamerasrc exposuretimerange=“13000 350000000” gainrange=“1 16” aelock=false wbmode=0 aeantibanding=1 ee-mode=0 awblock=true ! ‘video/x-raw(memory:NVMM), width=3840,height=2160,framerate=30/1’ ! nvjpegenc ! filesink location=image_test.jpg

is successful with:

GST_ARGUS: NvArgusCameraSrc: Setting Exposure Time Range : 13000 350000000
GST_ARGUS: NvArgusCameraSrc: Setting Gain Range : 1 16
Setting pipeline to PAUSED …
Pipeline is live and does not need PREROLL …
Pipeline is PREROLLED …
Setting pipeline to PLAYING …
New clock: GstSystemClock
GST_ARGUS: Creating output stream
CONSUMER: Waiting until producer is connected…
GST_ARGUS: Available Sensor modes :
GST_ARGUS: 3840 x 2160 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1920 x 1080 FR = 59.999999 fps Duration = 16666667 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: Running with following settings:
Camera index = 0
Camera mode = 0
Output Stream W = 3840 H = 2160
seconds to Run = 0
Frame Rate = 29.999999
GST_ARGUS: Setup Complete, Starting captures for 0 seconds
GST_ARGUS: Starting repeat capture requests.
CONSUMER: Producer has connected; continuing.
NvMMLiteBlockCreate : Block : BlockType = 1
Redistribute latency…
^Chandling interrupt.
Interrupt: Stopping pipeline …
Execution ended after 0:00:05.594453259
Setting pipeline to NULL …
GST_ARGUS: Cleaning up
CONSUMER: Done Success
GST_ARGUS: Done Success
Freeing pipeline …

But if I set up the same pipeline in cpp and set the exposure and gain with:

g_object_set(G_OBJECT(source), “exposuretimerange”, “13000 350000000”, NULL);
g_object_set(G_OBJECT(source), “gainrange”, “1 16”, NULL);

I get errors:

GST_ARGUS: NvArgusCameraSrc: Setting Exposure Time Range : 13000 350000000
GST_ARGUS: NvArgusCameraSrc: Setting Gain Range : 1 16
GST_ARGUS: Invalid min gain value, using default minimum gain: 8.000000 instead.
GST_ARGUS: Invalid max gain value, using default maximum gain: 0.000000 instead.
GST_ARGUS: Invalid min exp value, using default minimum exp: 29999998 instead.
GST_ARGUS: Invalid max exp value, using default maximum exp: 0 instead.

This code worked fine in JP 5.1.1 but is having the errors above in JP 6.2.1. I’m not quite sure why or how to debug. The error is saying it’s setting the min and max reversed as well, and the values dont match the min / max retrieved from the command line.

The output of journalctl -u nvargus-daemon gives these errors:

(Argus) Error BadParameter: Bad gain range: [1.00, 0.00] (in src/api/RequestImpl.cpp, function setGainRange(), line 694)
(Argus) Error BadParameter: Bad exposure time range: [13000, 0] (in src/api/RequestImpl.cpp, function setExposureTimeRange(), line 656)

Which would possibly suggest that the inputs from g_object_set are getting mixed up somewhere. There are no errors in journalctl when running the command from the command line.

Any advice on how to debug this issue, or where to look would be helpful.

Some further debugging shows that this only seems to happen if I try to change the exposure and gain ranges after the camera pipeline has started. Should I be able to change these values after the pipeline has been started? If I set the values then start the pipeline there’s no problems. Or if I stop and restart the pipeline on every exposure/gain setting change.

I was able to set these values after the pipeline had started in JP 5.1.1, so I dont think this is necessarily a hardware constraint, and is likely more so a software issue/bug in JP 6.2.1? Is there a better way to change exposure and gain values on the fly, I’m trying to capture HDR images (I know, with a streaming camera, not ideal) so there’s alot of exposure setting changes.

hello adrian.battiston,

it should be able to change the exposure and gain values after the camera pipeline has started.
let’s have an alternative way for testing, please using v4l2-ctl for setting exposure/gain values while camera preview is running.
for instance,
enable camera preview,
$ gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),framerate=30/1,format=NV12' ! nvvidconv ! xvimagesink
using v4l2 IOCTL for setting exposure time.
$ v4l2-ctl -d /dev/video0 --set-ctrl exposure=33333

Hi Jerry, Thanks for the response.

We’re running headless so the xvimagesink component fails, but it runs fine with fakesink.

The v4l2-ctl command to update the exposure time is also successful (there aren’t any errors). But I can also send it almost any exposure value (0, -100, etc.) without seeing errors. Is the goal of this debugging to view the image change real time? Or should v4l2-ctl throw errors?

I also dont see any errors in dmesg or journalctl. Does v4l2-ctl log errors somewhere in particluar?

If I run v4l2-ctl command with verbose or other settings it also seems to succeed regardless of the exposure value.

Checking the exposure setting with

v4l2-ctl -d /dev/video0 --get-ctrl exposure

returns the proper min / max value when I send it wacky values that are outside of the range. For example setting a value of “1” and then getting returns “13” (the proper min value)

So it seems like setting exposure in real time works using v4l2-ctl.

hello adrian.battiston,

ya, this debug approach is viewing the image change real time.
it also looks correct by having --get-ctrl to retrieve the sensor settings.

this might be the application level bug.
please see-also Camera Driver Porting and also Topic 310858 for some known changes when porting DTS from JP-5 to JP-6 to debug further.

Thanks JerryChang, since the DTS is from a 3rd party I decided to leave it, but I think your suggestion would also have helped. I instead just migrated everything to use the argus / jetson_multimedia_api libraries and that has worked well without the issues I see from gstreamer. Thanks for the support.