setExposureTimeRange values don't take effect for initial capture requests

I’m hitting an issue with setExposureTimeRange, and wanted to know if it’s expected behavior or not. This is with L4T 32.1. The problem is that my calls to setExposureTimeRange before starting any capture requests don’t seem to have any effect. I have to specify the settings a second time and restart the capture requests in order for the image to be affected.

In terms of code, the following sequence does not work… i.e. regardless of the exposure and gain values I specify, the resulting images always look the same. However, the metadata for the images reports the values that I specified, which is confusing.

captureStream = UniqueObj<OutputStream>(iCaptureSession->createOutputStream(streamSettings.get()));
request = UniqueObj<Request>(iCaptureSession->createRequest());
iRequest = interface_cast<IRequest>(request);
iRequest->enableOutputStream(captureStream.get());
iSourceSettings = interface_cast<ISourceSettings>(iRequest->getSourceSettings());
iAutoControlSettings = interface_cast<IAutoControlSettings>(iRequest->getAutoControlSettings());
iSourceSettings->setExposureTimeRange(exp_range);
iSourceSettings->setGainRange(gain_range);
iAutoControlSettings->setIspDigitalGainRange(ispgain_range);
frameConsumer = UniqueObj<FrameConsumer>(FrameConsumer::create(captureStream.get()));
iFrameConsumer = interface_cast<IFrameConsumer>(frameConsumer);
iCaptureSession->repeat(request.get());

This sequence does work… i.e. after the second repeat call the images look as expected.

captureStream = UniqueObj<OutputStream>(iCaptureSession->createOutputStream(streamSettings.get()));
request = UniqueObj<Request>(iCaptureSession->createRequest());
iRequest = interface_cast<IRequest>(request);
iRequest->enableOutputStream(captureStream.get());
iSourceSettings = interface_cast<ISourceSettings>(iRequest->getSourceSettings());
iAutoControlSettings = interface_cast<IAutoControlSettings>(iRequest->getAutoControlSettings());
frameConsumer = UniqueObj<FrameConsumer>(FrameConsumer::create(captureStream.get()));
iFrameConsumer = interface_cast<IFrameConsumer>(frameConsumer);
iCaptureSession->repeat(request.get());
usleep(20000); // without this the settings below don't reliably take effect
iSourceSettings->setExposureTimeRange(exp_range);
iSourceSettings->setGainRange(gain_range);
iAutoControlSettings->setIspDigitalGainRange(ispgain_range);
iCaptureSession->stopRepeat();
iCaptureSession->waitForIdle();
iCaptureSession->repeat(request.get());

In the first case am I doing anything in an incorrect order? Is this expected behavior?

hello kes25c,

may I know what’s your exposure-time range setting also your sensor capability reporting?
you might check the sensor device tree and please also share the settings.
for example,

<i>$l4t-r32.1/kernel_src/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-modules/tegra186-camera-imx185-a00.dtsi</i>

        i2c@3180000 {
                tca9546@70 {
                        i2c@0 {
                        imx185_a@1a {
                                compatible = "nvidia,imx185";
                                mode0 {/*mode IMX185_MODE_1920X1080_CROP_30FPS*/
                                        ...
                                        min_exp_time = "30"; /* us */
                                        max_exp_time = "660000"; /* us */

These cameras have two sensor modes (I’m using mode 1). Querying with iSensorMode->getExposureTimeRange(), the ranges reported are:

mode 0 => [40000, 33698000] ns
mode 1 => [20000, 33698000] ns

Looking in the dtb it shows:

min_exp_time = “40”;
max_exp_time = “33698”;

min_exp_time = “20”;
max_exp_time = “33698”;

Which seems to match since those are in us.

To see if the settings are taking effect I’ve been starting at 1ms exposure and fixed the gains to 1:

iSourceSettings->setExposureTimeRange([1000000, 1000000]);
iSourceSettings->setGainRange([1, 1]);
iAutoControlSettings->setIspDigitalGainRange([1, 1]);

Capture ~30 seconds of images. Then restart my app and double the exposure that is set, i.e.

iSourceSettings->setExposureTimeRange([2000000, 2000000]);
iSourceSettings->setGainRange([1, 1]);
iAutoControlSettings->setIspDigitalGainRange([1, 1]);

Capture ~30 seconds of images. Keep repeating that for 4000000, 8000000, and 16000000 to see if the image brightness roughly doubles for each set of images. For these tests I’m not moving the cameras or changing the scene lighting at all. If I use the first sequence of calls I showed in my original post all of the image sets look the same. If I use the second sequence of calls they roughly double in brightness each time as expected.

I can share the code to my test application if that helps. It’s based off the sample apps. It sets exposure/gains, starts streaming a camera, and then capture jpegs or h264 video for a specified amount of time before shutting down.

hello kes25c,

I’m able to configure the exposure time and tell the brightness difference.
please refer to my code snippet as below, 09_camera_jpeg_capture

static const Range<uint64_t>   testExposureTimeRange(20000000, 20000000);
iSourceSettings->setExposureTimeRange(testExposureTimeRange);