This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: AE/AWB Settling Issue in VPAC

Part Number: TDA4VM

Tool/software:

Hi 

Creating a new thread since requested.

Since we had multiple conversations, consolidating my issues here

We are in the process of tuning the ISP (SDK 9_00_02_05) for IMX662 Sensor. The sensor supports gain and exposure control. The Gain range varies from 0dB to 30dB and Exposure range varies from 60us to 16600us. The gain is mapped in multiples of 10 ie 0 for 0dB, 10 for 1dB and 300 for 30dB. We have mapped it accordingly in get_imx662_ae_dyn_params() in gsttiovxisp.c. You can have a look at the patch for reference.

diff --git a/opt/edgeai-gst-plugins/ext/tiovx/gsttiovxisp.c b/opt/edgeai-gst-plugins/ext/tiovx/gsttiovxisp.c
index e815cf3..9ce3521 100644
--- a/opt/edgeai-gst-plugins/ext/tiovx/gsttiovxisp.c
+++ b/opt/edgeai-gst-plugins/ext/tiovx/gsttiovxisp.c
@@ -657,6 +657,8 @@ static int32_t get_ov2312_ae_dyn_params (IssAeDynamicParams * p_ae_dynPrms);
 
 static int32_t get_ox05b1s_ae_dyn_params (IssAeDynamicParams * p_ae_dynPrms);
 
+static int32_t get_imx662_ae_dyn_params (IssAeDynamicParams * p_ae_dynPrms);                            
+
 static void gst_tiovx_isp_map_2A_values (GstTIOVXISP * self, int exposure_time,
     int analog_gain, gint32 * exposure_time_mapped,
     gint32 * analog_gain_mapped);
@@ -706,7 +708,8 @@ gst_tiovx_isp_class_init (GstTIOVXISPClass * klass)
           "                                   SENSOR_ONSEMI_AR0233_UB953_MARS\n"
           "                                   SENSOR_SONY_IMX219_RPI\n"
           "                                   SENSOR_OX05B1S\n"
-          "                                   SENSOR_OV2312_UB953_LI",
+          "                                   SENSOR_OV2312_UB953_LI\n"
+	  "				      SENSOR_SONY_IMX662",
           NULL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
           GST_PARAM_MUTABLE_READY));
@@ -1854,6 +1857,8 @@ gst_tiovx_isp_postprocess (GstTIOVXMiso * miso)
       get_ov2312_ae_dyn_params (&sink_pad->sensor_in_data.ae_dynPrms);
     } else if (g_strcmp0 (self->sensor_name, "SENSOR_OX05B1S") == 0) {
       get_ox05b1s_ae_dyn_params (&sink_pad->sensor_in_data.ae_dynPrms);
+    } else if (g_strcmp0 (self->sensor_name, "SENSOR_SONY_IMX662") == 0) {             
+      get_imx662_ae_dyn_params (&sink_pad->sensor_in_data.ae_dynPrms);            
     } else {
       get_imx219_ae_dyn_params (&sink_pad->sensor_in_data.ae_dynPrms);
     }
@@ -2066,6 +2071,34 @@ get_ox05b1s_ae_dyn_params (IssAeDynamicParams * p_ae_dynPrms)
   return status;
 }
 
+static int32_t                                                                                
+get_imx662_ae_dyn_params (IssAeDynamicParams * p_ae_dynPrms)                                  
+{                                                                                             
+  int32_t status = -1;                                                                        
+  uint8_t count = 0;                                                                          
+                                                                                              
+  g_return_val_if_fail (p_ae_dynPrms, status);                                                
+                                                                                              
+  p_ae_dynPrms->targetBrightnessRange.min = 40;                                               
+  p_ae_dynPrms->targetBrightnessRange.max = 50;                                               
+  p_ae_dynPrms->targetBrightness = 45;                                                        
+  p_ae_dynPrms->threshold = 1;                                                                
+  p_ae_dynPrms->enableBlc = 1;                                                                
+  p_ae_dynPrms->exposureTimeStepSize = 1;                                                     
+                                                                                              
+  p_ae_dynPrms->exposureTimeRange[count].min = 60;                                           
+  p_ae_dynPrms->exposureTimeRange[count].max = 16600;                                         
+  p_ae_dynPrms->analogGainRange[count].min = 0;                                            
+  p_ae_dynPrms->analogGainRange[count].max = 300;                                            
+  p_ae_dynPrms->digitalGainRange[count].min = 256;                                            
+  p_ae_dynPrms->digitalGainRange[count].max = 256;                                            
+  count++;                                                                                    
+                                                                                              
+  p_ae_dynPrms->numAeDynParams = count;                                                       
+  status = 0;                                                                                 
+  return status;                                                                              
+}
+
 static void
 gst_tiovx_isp_map_2A_values (GstTIOVXISP * self, int exposure_time,
     int analog_gain, gint32 * exposure_time_mapped, gint32 * analog_gain_mapped)
@@ -2105,6 +2138,9 @@ gst_tiovx_isp_map_2A_values (GstTIOVXISP * self, int exposure_time,
 } else if (g_strcmp0 (self->sensor_name, "SENSOR_OX05B1S") == 0) {
     *exposure_time_mapped = (int) ((double)exposure_time * 2128 * 60 / 1000000 + 0.5);
     *analog_gain_mapped = analog_gain / 64;
+  }  else if (g_strcmp0 (self->sensor_name, "SENSOR_SONY_IMX662") == 0) {                            
+      *exposure_time_mapped = exposure_time;
+      *analog_gain_mapped = analog_gain;                                                   
   } else {
     GST_ERROR_OBJECT (self, "Unknown sensor: %s", self->sensor_name);
   }
diff --git a/opt/edgeai-tiovx-modules/src/tiovx_sensor_module.c b/opt/edgeai-tiovx-modules/src/tiovx_sensor_module.c
index 447fcaf..ffb8e64 100644
--- a/opt/edgeai-tiovx-modules/src/tiovx_sensor_module.c
+++ b/opt/edgeai-tiovx-modules/src/tiovx_sensor_module.c
@@ -450,6 +450,10 @@ vx_status tiovx_init_sensor(SensorObj *sensorObj, char *objName)
     {
         sensorObj->sensorParams.dccId=5;
     }
+    else if(strcmp(sensorObj->sensor_name, "SENSOR_SONY_IMX662") == 0)
+    {                                                                                 
+        sensorObj->sensorParams.dccId=662;
+    }  
     else
     {
         TIOVX_MODULE_ERROR("[SENSOR-MODULE] Invalid sensor name\n");

Also, we have configured the imx662_properties according to our sensor configuration. Attaching the same for reference

SENSOR_ID 662
PRJ_DIR ../imx662_output
SENSOR_NAME imx662
SENSOR_DCC_NAME SENSOR_SONY_IMX662

SENSOR_WIDTH 1920
SENSOR_HEIGHT 1080

# 0=RGGB; 1=GRBG; 2=GBRG; 3=BGGR, 4=MONO
COLOR_PATTERN 0

# sensor mode: 0 for linear (no decompanding), 1 for WDR (decompanding)
WDR_MODE 0

# raw sensor image BIT_DEPTH: it may be 8, 10, or 12 for linear sensors; typically 12 for WDR mode because of companding
BIT_DEPTH 10

# WDR BIT_DEPTH: WDR raw sensor image bitdepth after decompanding, typically 20 or 24
WDR_BIT_DEPTH 20

# WDR decompanding knee points (comma separated without spaces in between)
WDR_KNEE_X 0,512,1408,2176,4095,65535
WDR_KNEE_Y 0,2048,16384,65536,1048063,1048063

# Sensor black level to subtract before decompanding (for linear sensors only and some Sony WDR sensors)
BLACK_PRE  50

# Sensor black level to subtract after decompanding (for most WDR sensors and all linear sensors)
BLACK_POST  0

# GAMMA value for compressing 20/24-bit WDR raw to 16-bit ISP internal
# typically around 50 (0.5) for 24-bit WDR sensors and 70 (0.7) for 20-bit sensors
GAMMA_PRE 0

# LSB location for H3A input bit range (from bit-H3A_INPUT_LSB to bit-H3A_INPUT_LSB+9) 
H3A_INPUT_LSB 0

We are using the below gstreamer pipeline for streaming

media-ctl -d /dev/media1 --set-v4l2 '"imx662 7-0042":0[fmt:SRGGB10_1X10/1920x1080]'
gst-launch-1.0 v4l2src device=/dev/video2 io-mode=dmabuf-import ! \
video/x-bayer, width=1920, height=1080, framerate=30/1, format=rggb10 ! \
tiovxisp sink_0::device=/dev/v4l-subdev2 \
sensor-name="SENSOR_SONY_IMX662" \
dcc-isp-file=/opt/imaging/imx662/linear/dcc_viss.bin \
sink_0::dcc-2a-file=/opt/imaging/imx662/linear/dcc_2a.bin format-msb=9 ! \
video/x-raw, format=NV12, width=1920, height=1080, framerate=30/1 ! \
kmssink driver-name=tidss sync=false

What we noticed is irrespective of the configuration in get_imx662_ae_dyn_params() in gsttiovxisp.c and imx662_properties.txt, the exposure and gain always settle downs to minimum ie Gain=0 and Exposure=60us. We also tuned the ISP/VPAC as mentioned in https://www.ti.com/lit/an/sprad86a/sprad86a.pdf for multiple lighting conditions and still the behavior remained same. Also the images looked dark and AWB settling was also not proper. Attaching a sample image for reference.

And yes, AE is working in our TDA4VM as we enabled debug prints in the driver and noticed exposure being set to the Maximum (16600us) and then brought down to Minimum(60us). But after setting the exposure and gain once to minimum, the AE does not seem to work at all ie the exposure and gain remains same irrespective of the scene. We also tested with IMX219 setting and the AE algorithm seems to be working.

Lets us know, what could be the possible solutions for AE/AWB settling. Also let us know if you need details further from our end.

Thanks

  • Hi Yoosuf,

    (1) You would need to test your sensor driver to make sure that changing exposure time and gain (in dB) has the expected effect in raw image brightness.

    (2) AE output of gain value is linear rather than in dB.
    Setting the range in dB directly is not expected.

    Please refer to the links below for more details.

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1262114/faq-setting-up-auto-exposure-ae-for-your-image-sensor-with-tda4-am6xa-isp-vpac

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1303303/faq-am62a7-how-to-set-the-minimum-maximum-exposure-time-and-analog-gain-for-2a-algorithm

    Also, we have configured the imx662_properties according to our sensor configuration. Attaching the same for reference

    This should be fine.

    the images looked dark

    This is related to the AE issue of setting correct sensor exposure.

    AWB settling was also not proper.

    Please share your AWB calibration output picture in tuning tool.

  • You would need to test your sensor driver to make sure that changing exposure time and gain (in dB) has the expected effect in raw image brightness.

    Our camera driver is actively receiving the exposure and gain control, and the controls are getting reflected in the scene.

    AE output of gain value is linear rather than in dB.

    We have mapped it linearly, the Gain will have a step size of 0.3dB(0dB to 30dB with 0.3dB step) and as mentioned in the link: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1303303/faq-am62a7-how-to-set-the-minimum-maximum-exposure-time-and-analog-gain-for-2a-algorithm, we have mapped it directly in the get_imx662_ae_dyn_params().

    Attaching the AWB Calibration Output:

  • Hi Yoosuf,

    It look like you have resolved the AE related issues now.

    The AWB calibration does not look correct.
    Please check the AWB plugin guide under the help menu of tuning tool to see how these plots typically look like.

    There might be some issues with your light sources.
    The black circles should form a smooth curve.

  • Hi ,

    This was marked as resolved by mistake. We initially tested for D65, D50, TL84, and A Light as mentioned in the ISP tuning guide and the output was linear. But we had issues with AWB settling on other color temperatures and re-did the process with all the available light conditions. That's the reason the black dots are not aligned linearly.

    Also, the documentations are dated 1 year back. Are they still relevant? Since we had few differences between the ISP tuning guide and documentation?

    Thanks

  • Hi Yoosuf,

    This was marked as resolved by mistake.

    Is your AE able to adjust sensor exposure time and gain after fixing the gain dB mapping?

  • Hi Yoosuf,

    We initially tested for D65, D50, TL84, and A Light as mentioned in the ISP tuning guide and the output was linear. But we had issues with AWB settling on other color temperatures

    This is an AWB issue separate from AE.

    AWB calibration requires main references (forming the smooth curve) and additional references (away from the smooth curve).
    They cannot be mixed together.

    D65, D50, TL84, U30 and A light shall be all on the smooth curve rather than scattered around.
    CWF, WWF and other florescent lights may be scattered.
    Can you tell what light sources the black circles correspond to?

    Your plot looks weird and that is typically an issue with light sources (rarely an issue with lens).

  • This is the IMX390 driver under RTOS for your reference.

    git.ti.com/.../imx390

  • Hi Yoosef,

    This is a summary of how I calculate the values for the min and max gain and exposure for gsttiovxisp.c.

    For exposure, values are in units of microseconds. To calculate my minimum and maximum exposure range (for a Sony sensor) I need the framerate, exposure value, and vertical max. After that. we're just doing dimensional analysis.

    The exposure value should be less than the vertical max (number of horizontal bars).

    If I have a 60fps camera, the vertical max is 2250, and the minimum exposure value is 1, the minimum value for the exposure range is 7.

    1 / 2250 * 1/60 / 1E-6 = 7.407us ~ 7us

    If the maximum exposure value is 2249 (one less than the vertical max), the maximum value for the exposure range is 16659.

    2249 / 2250 * 1/60 / 1E-6 = 16659.259us ~ 16659us

    Here is the code snippet:

    static int32_t
    get_<sensor-name>_ae_dyn_params (IssAeDynamicParams * p_ae_dynPrms)
    {
            ...
            p_ae_dynPrms->exposureTimeRange[count].min = 7;
            p_ae_dynPrms->exposureTimeRange[count].max = 16659;
            ...
    };

    For the gain, you need to convert the dB gain values to a multiplier and then multiply that by 1024. The driver takes a 1x gain as 1024.

    If your gain is split into both analog and linear (digital) gain, you'll set both the analog min and max as well as the digital min and max.

    If I have a camera with a maximum of 30dB analog gain and 42dB digital gain, the values that I would set are the following:

    • Analog min: 0dB = 1x = 1024
    • Analog max: 30dB = 1024 * 10^(30/20) = 32381.723 ~ 32381
    • Digital min: 0dB = 1x = 1024
    • Digital max: 42dB = 1024 * 10^(42/20) = 128913.962 ~ 128913

    The following is the code snippet:

    static int32_t
    get_<sensor-name>_ae_dyn_params (IssAeDynamicParams * p_ae_dynPrms)
    {
            ...
            p_ae_dynPrms->analogGainRange[count].min = 1024;
            p_ae_dynPrms->analogGainRange[count].max = 32381;
            p_ae_dynPrms->digitalGainRange[count].min = 1024;
            p_ae_dynPrms->digitalGainRange[count].max = 128913;
            ...
    };

    The gain settings simply go underneath the exposure settings.

    In my experience the digital gain doesn't come into play until the analog gain has hit the maximum value within the sensor, but this is something you'll handle within the sensor driver itself.

    Best,
    Jared

  • Hi 

    In 1080p resolution, we have vertical max of 1250 and framerate of 60fps.

    • Min exposure = 4 => 60us
    • Max exposure = 1249 lines => 16600us

    For gain,

    • Min gain = 0dB => 0  in sensor driver
    • Max gain = 30dB => 300 in sensor driver

    Which maps in isp file as

    • Min gain = 1024
    • Max gain = 300*1024 = 307200

    analog_gain_mapped = analog_gain/1024;

    But this too doesn't seem to work. We still have the same issue. 

    Kindly provide suggestions if you have any.

  • Hi Yoosuf,

    But this too doesn't seem to work. We still have the same issue. 

    Could you please print out the "h3a_data" coming out of this function at the color checker scene above?

    https://git.ti.com/cgit/processor-sdk/imaging/tree/ti_2a_wrapper/src/ti_2a_wrapper.c?h=main#n828

  • Hi Yoosef,

    Additionally, your maximum gain calculation isn't correct. The equations look like the following:

    • loagrithmic_gain = 20 * log(linear_gain)
    • linear_gain * 1024 = isp_gain

    Therefore, the complete equation is the following:

    • 30dB = 1024 * 10^(30/20) = 32381.723 ~ 32381

    Best,
    Jared