Compare commits
6 Commits
c2113b443d
...
69bc2fd5b4
Author | SHA1 | Date |
---|---|---|
dchvs | 69bc2fd5b4 | |
dchvs | d8cb8d7139 | |
dchvs | c26468be02 | |
dchvs | 4c34506a6a | |
dchvs | 897f1f78c1 | |
dchvs | e05aeb04a3 |
51
README.md
51
README.md
|
@ -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.
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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, ®16);
|
err = mt9m021_read_reg16(s_data, MT9M021_DIGITAL_TEST, ®16);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue