1
0
Fork 0
forked from External/mediamtx

add rpiCameraAWBGains (#2858) (#2954)

This commit is contained in:
Alessandro Ros 2024-01-28 21:48:21 +01:00 committed by GitHub
parent 60aaed935b
commit 0f733bab26
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 91 additions and 32 deletions

View file

@ -298,6 +298,12 @@ components:
type: string type: string
rpiCameraAWB: rpiCameraAWB:
type: string type: string
rpiCameraAWBGains:
type: array
minItems: 2
maxItems: 2
items:
type: number
rpiCameraDenoise: rpiCameraDenoise:
type: string type: string
rpiCameraShutter: rpiCameraShutter:

View file

@ -66,6 +66,7 @@ func TestConfFromFile(t *testing.T) {
RPICameraSharpness: 1, RPICameraSharpness: 1,
RPICameraExposure: "normal", RPICameraExposure: "normal",
RPICameraAWB: "auto", RPICameraAWB: "auto",
RPICameraAWBGains: []float64{0, 0},
RPICameraDenoise: "off", RPICameraDenoise: "off",
RPICameraMetering: "centre", RPICameraMetering: "centre",
RPICameraFPS: 30, RPICameraFPS: 30,

View file

@ -188,6 +188,31 @@ func loadEnvInternal(env map[string]string, prefix string, prv reflect.Value) er
} }
return nil return nil
case rt.Elem() == reflect.TypeOf(float64(0)):
if ev, ok := env[prefix]; ok {
if ev == "" {
prv.Elem().Set(reflect.MakeSlice(prv.Elem().Type(), 0, 0))
} else {
if prv.IsNil() {
prv.Set(reflect.New(rt))
}
raw := strings.Split(ev, ",")
vals := make([]float64, len(raw))
for i, v := range raw {
tmp, err := strconv.ParseFloat(v, 64)
if err != nil {
return err
}
vals[i] = tmp
}
prv.Elem().Set(reflect.ValueOf(vals))
}
}
return nil
case rt.Elem().Kind() == reflect.Struct: case rt.Elem().Kind() == reflect.Struct:
if ev, ok := env[prefix]; ok && ev == "" { // special case: empty list if ev, ok := env[prefix]; ok && ev == "" { // special case: empty list
prv.Elem().Set(reflect.MakeSlice(prv.Elem().Type(), 0, 0)) prv.Elem().Set(reflect.MakeSlice(prv.Elem().Type(), 0, 0))

View file

@ -85,6 +85,7 @@ type testStruct struct {
MyDurationOpt *myDuration `json:"myDurationOpt"` MyDurationOpt *myDuration `json:"myDurationOpt"`
MyDurationOptUnset *myDuration `json:"myDurationOptUnset"` MyDurationOptUnset *myDuration `json:"myDurationOptUnset"`
MyMap map[string]*mapEntry `json:"myMap"` MyMap map[string]*mapEntry `json:"myMap"`
MySliceFloat []float64 `json:"mySliceFloat"`
MySliceString []string `json:"mySliceString"` MySliceString []string `json:"mySliceString"`
MySliceStringEmpty []string `json:"mySliceStringEmpty"` MySliceStringEmpty []string `json:"mySliceStringEmpty"`
MySliceStringOpt *[]string `json:"mySliceStringOpt"` MySliceStringOpt *[]string `json:"mySliceStringOpt"`
@ -113,6 +114,7 @@ func TestLoad(t *testing.T) {
"MYPREFIX_MYMAP_MYKEY": "", "MYPREFIX_MYMAP_MYKEY": "",
"MYPREFIX_MYMAP_MYKEY2_MYVALUE": "asd", "MYPREFIX_MYMAP_MYKEY2_MYVALUE": "asd",
"MYPREFIX_MYMAP_MYKEY2_MYSTRUCT_MYPARAM": "456", "MYPREFIX_MYMAP_MYKEY2_MYSTRUCT_MYPARAM": "456",
"MYPREFIX_MYSLICEFLOAT": "0.5,0.5",
"MYPREFIX_MYSLICESTRING": "val1,val2", "MYPREFIX_MYSLICESTRING": "val1,val2",
"MYPREFIX_MYSLICESTRINGEMPTY": "", "MYPREFIX_MYSLICESTRINGEMPTY": "",
"MYPREFIX_MYSLICESTRINGOPT": "aa", "MYPREFIX_MYSLICESTRINGOPT": "aa",
@ -160,6 +162,7 @@ func TestLoad(t *testing.T) {
}, },
}, },
}, },
MySliceFloat: []float64{0.5, 0.5},
MySliceString: []string{ MySliceString: []string{
"val1", "val1",
"val2", "val2",

View file

@ -130,38 +130,39 @@ type Path struct {
SourceRedirect string `json:"sourceRedirect"` SourceRedirect string `json:"sourceRedirect"`
// Raspberry Pi Camera source // Raspberry Pi Camera source
RPICameraCamID int `json:"rpiCameraCamID"` RPICameraCamID int `json:"rpiCameraCamID"`
RPICameraWidth int `json:"rpiCameraWidth"` RPICameraWidth int `json:"rpiCameraWidth"`
RPICameraHeight int `json:"rpiCameraHeight"` RPICameraHeight int `json:"rpiCameraHeight"`
RPICameraHFlip bool `json:"rpiCameraHFlip"` RPICameraHFlip bool `json:"rpiCameraHFlip"`
RPICameraVFlip bool `json:"rpiCameraVFlip"` RPICameraVFlip bool `json:"rpiCameraVFlip"`
RPICameraBrightness float64 `json:"rpiCameraBrightness"` RPICameraBrightness float64 `json:"rpiCameraBrightness"`
RPICameraContrast float64 `json:"rpiCameraContrast"` RPICameraContrast float64 `json:"rpiCameraContrast"`
RPICameraSaturation float64 `json:"rpiCameraSaturation"` RPICameraSaturation float64 `json:"rpiCameraSaturation"`
RPICameraSharpness float64 `json:"rpiCameraSharpness"` RPICameraSharpness float64 `json:"rpiCameraSharpness"`
RPICameraExposure string `json:"rpiCameraExposure"` RPICameraExposure string `json:"rpiCameraExposure"`
RPICameraAWB string `json:"rpiCameraAWB"` RPICameraAWB string `json:"rpiCameraAWB"`
RPICameraDenoise string `json:"rpiCameraDenoise"` RPICameraAWBGains []float64 `json:"rpiCameraAWBGains"`
RPICameraShutter int `json:"rpiCameraShutter"` RPICameraDenoise string `json:"rpiCameraDenoise"`
RPICameraMetering string `json:"rpiCameraMetering"` RPICameraShutter int `json:"rpiCameraShutter"`
RPICameraGain float64 `json:"rpiCameraGain"` RPICameraMetering string `json:"rpiCameraMetering"`
RPICameraEV float64 `json:"rpiCameraEV"` RPICameraGain float64 `json:"rpiCameraGain"`
RPICameraROI string `json:"rpiCameraROI"` RPICameraEV float64 `json:"rpiCameraEV"`
RPICameraHDR bool `json:"rpiCameraHDR"` RPICameraROI string `json:"rpiCameraROI"`
RPICameraTuningFile string `json:"rpiCameraTuningFile"` RPICameraHDR bool `json:"rpiCameraHDR"`
RPICameraMode string `json:"rpiCameraMode"` RPICameraTuningFile string `json:"rpiCameraTuningFile"`
RPICameraFPS float64 `json:"rpiCameraFPS"` RPICameraMode string `json:"rpiCameraMode"`
RPICameraIDRPeriod int `json:"rpiCameraIDRPeriod"` RPICameraFPS float64 `json:"rpiCameraFPS"`
RPICameraBitrate int `json:"rpiCameraBitrate"` RPICameraIDRPeriod int `json:"rpiCameraIDRPeriod"`
RPICameraProfile string `json:"rpiCameraProfile"` RPICameraBitrate int `json:"rpiCameraBitrate"`
RPICameraLevel string `json:"rpiCameraLevel"` RPICameraProfile string `json:"rpiCameraProfile"`
RPICameraAfMode string `json:"rpiCameraAfMode"` RPICameraLevel string `json:"rpiCameraLevel"`
RPICameraAfRange string `json:"rpiCameraAfRange"` RPICameraAfMode string `json:"rpiCameraAfMode"`
RPICameraAfSpeed string `json:"rpiCameraAfSpeed"` RPICameraAfRange string `json:"rpiCameraAfRange"`
RPICameraLensPosition float64 `json:"rpiCameraLensPosition"` RPICameraAfSpeed string `json:"rpiCameraAfSpeed"`
RPICameraAfWindow string `json:"rpiCameraAfWindow"` RPICameraLensPosition float64 `json:"rpiCameraLensPosition"`
RPICameraTextOverlayEnable bool `json:"rpiCameraTextOverlayEnable"` RPICameraAfWindow string `json:"rpiCameraAfWindow"`
RPICameraTextOverlay string `json:"rpiCameraTextOverlay"` RPICameraTextOverlayEnable bool `json:"rpiCameraTextOverlayEnable"`
RPICameraTextOverlay string `json:"rpiCameraTextOverlay"`
// Hooks // Hooks
RunOnInit string `json:"runOnInit"` RunOnInit string `json:"runOnInit"`
@ -206,6 +207,7 @@ func (pconf *Path) setDefaults() {
pconf.RPICameraSharpness = 1 pconf.RPICameraSharpness = 1
pconf.RPICameraExposure = "normal" pconf.RPICameraExposure = "normal"
pconf.RPICameraAWB = "auto" pconf.RPICameraAWB = "auto"
pconf.RPICameraAWBGains = []float64{0, 0}
pconf.RPICameraDenoise = "off" pconf.RPICameraDenoise = "off"
pconf.RPICameraMetering = "centre" pconf.RPICameraMetering = "centre"
pconf.RPICameraFPS = 30 pconf.RPICameraFPS = 30
@ -467,6 +469,9 @@ func (pconf *Path) validate(conf *Conf, name string) error {
default: default:
return fmt.Errorf("invalid 'rpiCameraAWB' value") return fmt.Errorf("invalid 'rpiCameraAWB' value")
} }
if len(pconf.RPICameraAWBGains) != 2 {
return fmt.Errorf("invalid 'rpiCameraAWBGains' value")
}
switch pconf.RPICameraDenoise { switch pconf.RPICameraDenoise {
case "off", "cdn_off", "cdn_fast", "cdn_hq": case "off", "cdn_off", "cdn_fast", "cdn_hq":
default: default:

View file

@ -23,6 +23,7 @@ func pathConfCanBeUpdated(oldPathConf *conf.Path, newPathConf *conf.Path) bool {
clone.RPICameraSharpness = newPathConf.RPICameraSharpness clone.RPICameraSharpness = newPathConf.RPICameraSharpness
clone.RPICameraExposure = newPathConf.RPICameraExposure clone.RPICameraExposure = newPathConf.RPICameraExposure
clone.RPICameraAWB = newPathConf.RPICameraAWB clone.RPICameraAWB = newPathConf.RPICameraAWB
clone.RPICameraAWBGains = newPathConf.RPICameraAWBGains
clone.RPICameraDenoise = newPathConf.RPICameraDenoise clone.RPICameraDenoise = newPathConf.RPICameraDenoise
clone.RPICameraShutter = newPathConf.RPICameraShutter clone.RPICameraShutter = newPathConf.RPICameraShutter
clone.RPICameraMetering = newPathConf.RPICameraMetering clone.RPICameraMetering = newPathConf.RPICameraMetering

View file

@ -346,6 +346,11 @@ static void fill_dynamic_controls(ControlList *ctrls, const parameters_t *params
} }
ctrls->set(controls::AwbMode, awb_mode); ctrls->set(controls::AwbMode, awb_mode);
if (params->awb_gain_red > 0 && params->awb_gain_blue > 0) {
ctrls->set(controls::ColourGains,
Span<const float, 2>({params->awb_gain_red, params->awb_gain_blue}));
}
int denoise_mode; int denoise_mode;
if (strcmp(params->denoise, "cdn_off") == 0) { if (strcmp(params->denoise, "cdn_off") == 0) {
denoise_mode = controls::draft::NoiseReductionModeMinimal; denoise_mode = controls::draft::NoiseReductionModeMinimal;

View file

@ -61,6 +61,10 @@ bool parameters_unserialize(parameters_t *params, const uint8_t *buf, size_t buf
params->exposure = base64_decode(val); params->exposure = base64_decode(val);
} else if (strcmp(key, "AWB") == 0) { } else if (strcmp(key, "AWB") == 0) {
params->awb = base64_decode(val); params->awb = base64_decode(val);
} else if (strcmp(key, "AWBGainRed") == 0) {
params->awb_gain_red = atof(val);
} else if (strcmp(key, "AWBGainBlue") == 0) {
params->awb_gain_blue = atof(val);
} else if (strcmp(key, "Denoise") == 0) { } else if (strcmp(key, "Denoise") == 0) {
params->denoise = base64_decode(val); params->denoise = base64_decode(val);
} else if (strcmp(key, "Shutter") == 0) { } else if (strcmp(key, "Shutter") == 0) {

View file

@ -20,6 +20,8 @@ typedef struct {
float sharpness; float sharpness;
char *exposure; char *exposure;
char *awb; char *awb;
float awb_gain_red;
float awb_gain_blue;
char *denoise; char *denoise;
unsigned int shutter; unsigned int shutter;
char *metering; char *metering;

View file

@ -21,6 +21,8 @@ type Params struct {
Sharpness float64 Sharpness float64
Exposure string Exposure string
AWB string AWB string
AWBGainRed float64
AWBGainBlue float64
Denoise string Denoise string
Shutter int Shutter int
Metering string Metering string

View file

@ -39,6 +39,8 @@ func paramsFromConf(logLevel conf.LogLevel, cnf *conf.Path) rpicamera.Params {
Sharpness: cnf.RPICameraSharpness, Sharpness: cnf.RPICameraSharpness,
Exposure: cnf.RPICameraExposure, Exposure: cnf.RPICameraExposure,
AWB: cnf.RPICameraAWB, AWB: cnf.RPICameraAWB,
AWBGainRed: cnf.RPICameraAWBGains[0],
AWBGainBlue: cnf.RPICameraAWBGains[1],
Denoise: cnf.RPICameraDenoise, Denoise: cnf.RPICameraDenoise,
Shutter: cnf.RPICameraShutter, Shutter: cnf.RPICameraShutter,
Metering: cnf.RPICameraMetering, Metering: cnf.RPICameraMetering,

View file

@ -409,6 +409,9 @@ pathDefaults:
# auto-white-balance mode. # auto-white-balance mode.
# values: auto, incandescent, tungsten, fluorescent, indoor, daylight, cloudy, custom # values: auto, incandescent, tungsten, fluorescent, indoor, daylight, cloudy, custom
rpiCameraAWB: auto rpiCameraAWB: auto
# auto-white-balance fixed gains. This can be used in place of rpiCameraAWB.
# format: [red,blue]
rpiCameraAWBGains: [0, 0]
# denoise operating mode. # denoise operating mode.
# values: off, cdn_off, cdn_fast, cdn_hq # values: off, cdn_off, cdn_fast, cdn_hq
rpiCameraDenoise: "off" rpiCameraDenoise: "off"