Setup:
I am using a Jetson Orin Nano Developer Kit (8 GB) running Jetpack 6.2, connected to an IMX219 Arducam camera.
Issue
When I run my application, which uses GStreamer, I am not able to set the maximum value for gainrange and exposuretimerange. Instead, I get the following warning (as seen in the screenshot):
GST_ARGUS: NvArgusCameraSrc: Setting Gain Range : 1 9
GST_ARGUS: Invalid max gain value, using default maximum gain: 0.000000 instead.
Code used to set gain range
if (g_strcmp0(tokens[0], "gainrange") == 0) {
if (!tokens[1] || !tokens[2]) {
g_print("Invalid gainrange values. Use: gainrange <min> <max>\n");
} else if (app->src) {
gchar *range_str = g_strdup_printf("%s %s", tokens[1], tokens[2]);
g_print("Setting gainrange to %s\n", range_str);
g_object_set(app->src, "gainrange", range_str, NULL);
g_free(range_str);
}
}
I am using g_object_set() to set the gain range, but the system behaves as if the maximum gain value is 0.000, which triggers the fallback message shown above.
Looking into gstnvarguscamerasrc.cpp
I found the following logic inside the plugin:
if (src->controls.gainRange.low < sensorModeAnalogGainRange.min()) {
GST_ARGUS_PRINT("Invalid min gain value, using default minimum gain: %f instead.\n",
sensorModeAnalogGainRange.min());
src->controls.gainRange.low = sensorModeAnalogGainRange.min();
}
if (src->controls.gainRange.high > sensorModeAnalogGainRange.max()) {
GST_ARGUS_PRINT("Invalid max gain value, using default maximum gain: %f instead.\n",
sensorModeAnalogGainRange.max());
src->controls.gainRange.high = sensorModeAnalogGainRange.max();
}
The key point is that sensorModeAnalogGainRange.max() is returning 0.000, which causes the code to reject the values I set.
However, at startup the values are correct
The same function is used when the pipeline starts, and at that moment it correctly prints the gain and exposure ranges:
Main camera pipeline started.
GST_ARGUS: Creating output stream
CONSUMER: Waiting until producer is connected …
GST_ARGUS: Available Sensor modes :
GST_ARGUS: 3280 x 2464 FR = 21.000000 fps Duration = 47619048 ;
Analog Gain range min 1.000000, max 10.625000;
Exposure Range min 13000, max 683709000;
...
The corresponding code:
for (index = 0; index < modes.size(); index++) {
iSensorMode[index] = interface_cast<ISensorMode>(modes[index]);
if (!iSensorMode[index] || src->argus_in_error)
ORIGINATE_ERROR("NULL SensorMode interface detected");
sensorModeAnalogGainRange = iSensorMode[index]->getAnalogGainRange();
limitExposureTimeRange = iSensorMode[index]->getExposureTimeRange();
GST_ARGUS_PRINT("%d x %d FR = %f fps Duration = %lu ; Analog Gain range min %f, max %f; Exposure Range min %ju, max %ju;\n\n",
iSensorMode[index]->getResolution().width(),
iSensorMode[index]->getResolution().height(),
(1e9 / (iSensorMode[index]->getFrameDurationRange().min())),
iSensorMode[index]->getFrameDurationRange().min(),
sensorModeAnalogGainRange.min(),
sensorModeAnalogGainRange.max(),
limitExposureTimeRange.min(),
limitExposureTimeRange.max());
}
So, at initialization the min/max values are correct, but later when I set a new gain or exposure value through my application, the .max() function reports 0.000.
Additional information
I found a similar thread here:
Nvarguscamerasrc with gstreamer not reading max and min gain/exposure correctly from sensor in cpp lib – NVIDIA Developer Forums
However, there was no confirmed solution.
Also, if I run the following command from the terminal (even before the pipeline goes to PLAYING), the values are applied successfully:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 gainrange="1.0 10.6" exposuretimerange="13000 683709000" ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvvidconv ! nveglglessink -e
So it works from the command line, but not when I try to update the values programmatically during pipeline execution.
Question
-
Why does
sensorModeAnalogGainRange.max()return0.000when called after initialization? -
Is there a specific point in the pipeline lifecycle when the gain/exposure ranges can or cannot be updated?
-
What is the correct approach to update
gainrangeandexposuretimerangedynamically?
Any insights or solutions would be greatly appreciated.