forked from External/mediamtx
parent
60aaed935b
commit
0f733bab26
12 changed files with 91 additions and 32 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
25
internal/conf/env/env.go
vendored
25
internal/conf/env/env.go
vendored
|
|
@ -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))
|
||||||
|
|
|
||||||
3
internal/conf/env/env_test.go
vendored
3
internal/conf/env/env_test.go
vendored
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue