Compare commits

...

6 Commits

4 changed files with 163 additions and 78 deletions

View File

@ -33,7 +33,7 @@ gst-launch-1.0 nvarguscamerasrc sensor-id=0 aelock=true awblock=true ! 'video/x-
### UDP Streaming Test ### UDP Streaming Test
#### Sender Endpoint #### Sender Endpoint
``` ```
gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)30/1' ! omxh264enc control-rate=2 bitrate=8000000 ! 'video/x-h264, stream-format=(string)byte-stream' ! h264parse ! rtph264pay mtu=1400 ! udpsink host=$HOST_IP port=5000 sync=false async=false gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)60/1' ! omxh264enc control-rate=2 bitrate=8000000 ! 'video/x-h264, stream-format=(string)byte-stream' ! h264parse ! rtph264pay mtu=1400 ! udpsink host=$HOST_IP port=5000 sync=false async=false
``` ```
#### Receiver Endpoint #### Receiver Endpoint
@ -71,11 +71,58 @@ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=RG12 -
#### Slave #### Slave
``` ```
v4l2-ctl -d /dev/video01 --set-fmt-video=width=1280,height=720,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap v4l2-ctl -d /dev/video1 --set-fmt-video=width=1280,height=720,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap
```
### AE Synchronized
First run the master pipeline and then the slave pipeline:
#### Master Pipeline
```
gst-launch-1.0 nvarguscamerasrc sensor-id=1 ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)60/1' ! fakesink
```
#### Slave Pipeline
```
gst-launch-1.0 nvarguscamerasrc sensor-id=0 aelock=true awblock=true ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12,framerate=(fraction)60/1' ! fakesink
```
### Run script
```
./script_to_control_gain_exposure.sh &
``` ```
## Appends ## Appends
#### Auto Exposure
The AE controls realays in the feedback provided by the Driver's camera sensor to the nvarguscamerasrc libraries,
and the custom DTSIs with the sensor parameters definitions.
As the AE has interdependency with the digital gain. This gain it's and operation on the Driver, and follows this setup:
```bash
/*
* Digital gain equation:
*
* RANGE: 1x, 7.97x
* GAIN: VAL / STEPS;
* STEPS: 1/32
*
* SCALE FACTOR = 100.000
*
* min_gain_val = 100.000
* max_gain_val = 797.000
* step_gain_val = 3125
*/
MT9M021 sensor datasheet:
* <a href="https://files.niemo.de/aptina_pdfs/MT9M021-M031_Developer_Guide.pdf">MT9M021 Developer Guide</a>
```
Where, the min_gain_val, max_gain_val, step_gain_val are part of the cameras' DTSI (tegra186-tx2-spiri-camera.dtsi) fixed parameters
as per the datasheet. The step_gain_val consists of the steps (1/32 for the register) scaled to a value that makes this fraction become an significant
in integer.
#### Kernel Changes #### Kernel Changes
The Driver for the MT9M021 cameras consists on the following structure, that adds the DTB and Kernel sources, along with its Makefiles that lead its portability to a Kernel source. The Driver for the MT9M021 cameras consists on the following structure, that adds the DTB and Kernel sources, along with its Makefiles that lead its portability to a Kernel source.

View File

@ -98,26 +98,25 @@ i2c8 = "/i2c@31e0000";
inherent_gain = "1"; inherent_gain = "1";
pix_clk_hz = "74250000"; pix_clk_hz = "74250000";
gain_factor = "1"; gain_factor = "3125";
framerate_factor = "1000000"; framerate_factor = "1000000";
exposure_factor = "1000000"; exposure_factor = "1000000";
min_gain_val = "4"; min_gain_val = "100000";
max_gain_val = "6476"; max_gain_val = "796000";
step_gain_val = "1"; step_gain_val = "1";
default_gain = "100"; default_gain = "100000";
min_hdr_ratio = "1"; min_hdr_ratio = "1";
max_hdr_ratio = "1"; max_hdr_ratio = "1";
min_framerate = "2000000"; min_framerate = "2000000";
max_framerate = "60000000"; max_framerate = "60000000";
step_framerate = "1"; step_framerate = "1";
default_framerate = "6000000"; // 60.0 fps default_framerate = "60000000"; // 60.0 fps
min_exp_time = "23"; // us min_exp_time = "500"; // us
max_exp_time = "14933"; // us max_exp_time = "16000"; // us
step_exp_time = "1"; step_exp_time = "1";
default_exp_time = "10000"; // us default_exp_time = "12000"; // us
}; };
ports { ports {
#address-cells = <0x1>; #address-cells = <0x1>;
@ -186,25 +185,25 @@ i2c8 = "/i2c@31e0000";
inherent_gain = "1"; inherent_gain = "1";
pix_clk_hz = "74250000"; pix_clk_hz = "74250000";
gain_factor = "1"; gain_factor = "3125";
framerate_factor = "1000000"; framerate_factor = "1000000";
exposure_factor = "1000000"; exposure_factor = "1000000";
min_gain_val = "4"; min_gain_val = "100000";
max_gain_val = "6476"; max_gain_val = "796000";
step_gain_val = "1"; step_gain_val = "1";
default_gain = "100"; default_gain = "100000";
min_hdr_ratio = "1"; min_hdr_ratio = "1";
max_hdr_ratio = "1"; max_hdr_ratio = "1";
min_framerate = "2000000"; min_framerate = "2000000";
max_framerate = "60000000"; max_framerate = "60000000";
step_framerate = "1"; step_framerate = "1";
default_framerate = "6000000"; // 60.0 fps default_framerate = "60000000"; // 60.0 fps
min_exp_time = "23"; // us min_exp_time = "500"; // us
max_exp_time = "14933"; // us max_exp_time = "16000"; // us
step_exp_time = "1"; step_exp_time = "1";
default_exp_time = "10000"; // us default_exp_time = "12000"; // us
}; };
ports { ports {
#address-cells = <0x1>; #address-cells = <0x1>;

View File

@ -135,8 +135,8 @@
#define MT9M021_ANALOG_GAIN_SHIFT 4 #define MT9M021_ANALOG_GAIN_SHIFT 4
#define MT9M021_ANALOG_GAIN_MASK 0x0030 #define MT9M021_ANALOG_GAIN_MASK 0x0030
#define MT9M021_GLOBAL_GAIN_MIN 4 #define MT9M021_GLOBAL_GAIN_MIN 100000
#define MT9M021_GLOBAL_GAIN_MAX 6476 #define MT9M021_GLOBAL_GAIN_MAX 796000
#define MT9M021_GLOBAL_GAIN_DEF 100 #define MT9M021_GLOBAL_GAIN_DEF 100
#define MT9M021_COARSE_INT_TIME_MIN 0x0001 #define MT9M021_COARSE_INT_TIME_MIN 0x0001
@ -399,28 +399,37 @@ static int mt9m021_set_gain(struct tegracam_device *tc_dev, s64 val)
int err = 0; int err = 0;
u16 gain_mul; u16 gain_mul;
u16 reg16 = 0; u16 reg16 = 0;
u8 integer, fraction; u64 gain = 0;
dev_dbg(dev, "Setting Gain to: %lld", val); dev_dbg(dev, "Setting Gain to: %lld", val);
if (val >= MT9M021_GAIN_8X_FIXED) { if (val >= MT9M021_GAIN_8X_FIXED) {
integer = val / MT9M021_GAIN_8X_FIXED;
fraction = ((val / 8) % 100) * 32 / 100;
gain_mul = MT9M021_GAIN_8X; gain_mul = MT9M021_GAIN_8X;
} else if (val >= MT9M021_GAIN_4X_FIXED) { } else if (val >= MT9M021_GAIN_4X_FIXED) {
integer = val / MT9M021_GAIN_4X_FIXED;
fraction = ((val / 4) % 100) * 32 / 100;
gain_mul = MT9M021_GAIN_4X; gain_mul = MT9M021_GAIN_4X;
} else if (val >= MT9M021_GAIN_2X_FIXED) { } else if (val >= MT9M021_GAIN_2X_FIXED) {
integer = val / MT9M021_GAIN_2X_FIXED;
fraction = ((val / 2) % 100) * 32 / 100;
gain_mul = MT9M021_GAIN_2X; gain_mul = MT9M021_GAIN_2X;
} else { } else {
integer = val / MT9M021_GAIN_1X_FIXED;
fraction = (val % 100) * 32 / 100;
gain_mul = MT9M021_GAIN_1X; gain_mul = MT9M021_GAIN_1X;
} }
/*
* Digital gain equation:
*
* RANGE: 1x, 7.97x
* GAIN: VAL / STEPS;
* STEPS: 1/32
*
* SCALE FACTOR = 100.000
*
* min_gain_val = 100.000
* max_gain_val = 797.000
* gain_factor = 3125
*
* gain maps to range 32 - 255
*/
gain = val / 3125;
/* Update analog gain multiplier */ /* Update analog gain multiplier */
err = mt9m021_read_reg16(s_data, MT9M021_DIGITAL_TEST, &reg16); err = mt9m021_read_reg16(s_data, MT9M021_DIGITAL_TEST, &reg16);
if (err) if (err)
@ -430,20 +439,18 @@ static int mt9m021_set_gain(struct tegracam_device *tc_dev, s64 val)
((gain_mul << MT9M021_ANALOG_GAIN_SHIFT) & ((gain_mul << MT9M021_ANALOG_GAIN_SHIFT) &
MT9M021_ANALOG_GAIN_MASK); MT9M021_ANALOG_GAIN_MASK);
err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16); err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16);
msleep(10); // msleep(10);
if (err) if (err)
goto exit; goto exit;
/* Update global gain */ /* Update global gain */
err = err =
mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN, mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN, gain);
(integer << 5) | fraction); // msleep(10);
msleep(10);
if (err) if (err)
goto exit; goto exit;
err = err =
mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN_CB, mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN_CB, gain);
(integer << 5) | fraction);
if (err) if (err)
goto exit; goto exit;
@ -513,7 +520,7 @@ static int mt9m021_set_coarse_time(struct mt9m021 *priv, s64 val)
err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME_CB, val); err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME_CB, val);
if (err) if (err)
return err; return err;
msleep(30); // msleep(30);
return 0; return 0;
} }
@ -530,9 +537,9 @@ static int mt9m021_set_exposure(struct tegracam_device *tc_dev, s64 val)
dev_dbg(dev, "Setting Exposure Time to : %lld", val); dev_dbg(dev, "Setting Exposure Time to : %lld", val);
/* Calculate coarse-time */ coarse_time =
coarse_time = mode->signal_properties.pixel_clock.val * val * mode->signal_properties.pixel_clock.val /
val / mode->image_properties.line_length / mode->image_properties.line_length /
mode->control_properties.exposure_factor; mode->control_properties.exposure_factor;
err = mt9m021_set_coarse_time(priv, coarse_time); err = mt9m021_set_coarse_time(priv, coarse_time);
@ -564,7 +571,7 @@ static int mt9m021_set_analog_gain(struct tegracam_device *tc_dev, s64 val)
((val << MT9M021_ANALOG_GAIN_SHIFT) & ((val << MT9M021_ANALOG_GAIN_SHIFT) &
MT9M021_ANALOG_GAIN_MASK); MT9M021_ANALOG_GAIN_MASK);
err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16); err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16);
msleep(30); // msleep(30);
if (err) if (err)
goto exit; goto exit;
@ -620,7 +627,7 @@ static int mt9m021_set_digital_gain(struct tegracam_device *tc_dev, s64 val,
err = mt9m021_write_reg16(s_data, gain_cb_reg, val); err = mt9m021_write_reg16(s_data, gain_cb_reg, val);
if (err) if (err)
goto exit; goto exit;
msleep(30); // msleep(30);
return 0; return 0;
@ -643,7 +650,7 @@ static int mt9m021_set_test_pattern(struct tegracam_device *tc_dev, s32 val)
else else
err = mt9m021_write_reg16(s_data, MT9M021_TEST_PATTERN, err = mt9m021_write_reg16(s_data, MT9M021_TEST_PATTERN,
val); val);
msleep(30); // msleep(30);
if (err) if (err)
goto exit; goto exit;
@ -956,13 +963,15 @@ static int mt9m021_col_correction(struct mt9m021 *priv)
if (ret < 0) if (ret < 0)
return ret; return ret;
msleep(200); // msleep(200);
// usleep(200);
/* Enable Streaming */ /* Enable Streaming */
ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_START_STREAM]); ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_START_STREAM]);
if (ret < 0) if (ret < 0)
return ret; return ret;
msleep(200); // msleep(200);
// usleep(200);
/* Disable Streaming */ /* Disable Streaming */
ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_STOP_STREAM]); ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_STOP_STREAM]);
@ -973,7 +982,8 @@ static int mt9m021_col_correction(struct mt9m021 *priv)
ret = mt9m021_write_reg16(s_data, MT9M021_COLUMN_CORRECTION, 0xE007); ret = mt9m021_write_reg16(s_data, MT9M021_COLUMN_CORRECTION, 0xE007);
if (ret < 0) if (ret < 0)
return ret; return ret;
msleep(200); // msleep(200);
// usleep(200);
return ret; return ret;
} }

View File

@ -0,0 +1,29 @@
#!/bin/bash
initial_gain=0
initial_exposure_time=0
while true; do sleep 0.5;
# Read center camera controls
echo `v4l2-ctl -d /dev/video1 --get-ctrl=gain --get-ctrl=exposure` > controls
awk '{print $2}' controls > get_control
actual_gain=`cat get_control`
awk '{print $4}' controls > get_control
actual_exposure_time=`cat get_control`
# Print controls
#echo -e "\n**Center Camera Controls**"
#cat controls
# Remove temp files
rm controls get_control
# Set R/L camera controls manually
if [ $actual_gain -ne $initial_gain ]; then
v4l2-ctl -d /dev/video0 --set-ctrl=gain=$actual_gain
fi
if [ $actual_exposure_time -ne $initial_exposure_time ]; then
v4l2-ctl -d /dev/video0 --set-ctrl=exposure=$actual_exposure_time
fi
# Define new initial value
initial_gain=$actual_gain
initial_exposure_time=$actual_exposure_time
done