From 41a3fd503d1d88e0879b2b42eab4f948ef43ea25 Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Wed, 21 Aug 2024 00:05:40 +0200 Subject: [PATCH] rpi: add H264 software encoder (#2581) (#3670) This allows to use the RPI camera on the Raspberry Pi 5 too. --- apidocs/openapi.yaml | 18 +++--- internal/conf/conf_test.go | 9 +-- internal/conf/path.go | 23 +++++--- .../rpicamera/mtxrpicamdownloader/VERSION | 2 +- internal/staticsources/rpicamera/params.go | 9 +-- internal/staticsources/rpicamera/source.go | 9 +-- mediamtx.yml | 58 ++++++++++--------- 7 files changed, 71 insertions(+), 57 deletions(-) diff --git a/apidocs/openapi.yaml b/apidocs/openapi.yaml index 4e0ce1b5cf9..94fd864a909 100644 --- a/apidocs/openapi.yaml +++ b/apidocs/openapi.yaml @@ -402,14 +402,6 @@ components: type: string rpiCameraFPS: type: number - rpiCameraIDRPeriod: - type: integer - rpiCameraBitrate: - type: integer - rpiCameraProfile: - type: string - rpiCameraLevel: - type: string rpiCameraAfMode: type: string rpiCameraAfRange: @@ -426,6 +418,16 @@ components: type: boolean rpiCameraTextOverlay: type: string + rpiCameraCodec: + type: string + rpiCameraIDRPeriod: + type: integer + rpiCameraBitrate: + type: integer + rpiCameraProfile: + type: string + rpiCameraLevel: + type: string # Hooks runOnInit: diff --git a/internal/conf/conf_test.go b/internal/conf/conf_test.go index f0d1529ad85..88982317d57 100644 --- a/internal/conf/conf_test.go +++ b/internal/conf/conf_test.go @@ -69,14 +69,15 @@ func TestConfFromFile(t *testing.T) { RPICameraDenoise: "off", RPICameraMetering: "centre", RPICameraFPS: 30, - RPICameraIDRPeriod: 60, - RPICameraBitrate: 1000000, - RPICameraProfile: "main", - RPICameraLevel: "4.1", RPICameraAfMode: "continuous", RPICameraAfRange: "normal", RPICameraAfSpeed: "normal", RPICameraTextOverlay: "%Y-%m-%d %H:%M:%S - MediaMTX", + RPICameraCodec: "auto", + RPICameraIDRPeriod: 60, + RPICameraBitrate: 1000000, + RPICameraProfile: "main", + RPICameraLevel: "4.1", RunOnDemandStartTimeout: 5 * StringDuration(time.Second), RunOnDemandCloseAfter: 10 * StringDuration(time.Second), }, pa) diff --git a/internal/conf/path.go b/internal/conf/path.go index 242d1309181..2cff904e749 100644 --- a/internal/conf/path.go +++ b/internal/conf/path.go @@ -152,10 +152,6 @@ type Path struct { RPICameraTuningFile string `json:"rpiCameraTuningFile"` RPICameraMode string `json:"rpiCameraMode"` RPICameraFPS float64 `json:"rpiCameraFPS"` - RPICameraIDRPeriod int `json:"rpiCameraIDRPeriod"` - RPICameraBitrate int `json:"rpiCameraBitrate"` - RPICameraProfile string `json:"rpiCameraProfile"` - RPICameraLevel string `json:"rpiCameraLevel"` RPICameraAfMode string `json:"rpiCameraAfMode"` RPICameraAfRange string `json:"rpiCameraAfRange"` RPICameraAfSpeed string `json:"rpiCameraAfSpeed"` @@ -164,6 +160,11 @@ type Path struct { RPICameraFlickerPeriod int `json:"rpiCameraFlickerPeriod"` RPICameraTextOverlayEnable bool `json:"rpiCameraTextOverlayEnable"` RPICameraTextOverlay string `json:"rpiCameraTextOverlay"` + RPICameraCodec string `json:"rpiCameraCodec"` + RPICameraIDRPeriod int `json:"rpiCameraIDRPeriod"` + RPICameraBitrate int `json:"rpiCameraBitrate"` + RPICameraProfile string `json:"rpiCameraProfile"` + RPICameraLevel string `json:"rpiCameraLevel"` // Hooks RunOnInit string `json:"runOnInit"` @@ -211,14 +212,15 @@ func (pconf *Path) setDefaults() { pconf.RPICameraDenoise = "off" pconf.RPICameraMetering = "centre" pconf.RPICameraFPS = 30 - pconf.RPICameraIDRPeriod = 60 - pconf.RPICameraBitrate = 1000000 - pconf.RPICameraProfile = "main" - pconf.RPICameraLevel = "4.1" pconf.RPICameraAfMode = "continuous" pconf.RPICameraAfRange = "normal" pconf.RPICameraAfSpeed = "normal" pconf.RPICameraTextOverlay = "%Y-%m-%d %H:%M:%S - MediaMTX" + pconf.RPICameraCodec = "auto" + pconf.RPICameraIDRPeriod = 60 + pconf.RPICameraBitrate = 1000000 + pconf.RPICameraProfile = "main" + pconf.RPICameraLevel = "4.1" // Hooks pconf.RunOnDemandStartTimeout = 10 * StringDuration(time.Second) @@ -550,6 +552,11 @@ func (pconf *Path) validate( default: return fmt.Errorf("invalid 'rpiCameraAfSpeed' value") } + switch pconf.RPICameraCodec { + case "auto", "hardwareH264", "softwareH264": + default: + return fmt.Errorf("invalid 'rpiCameraCodec' value") + } // Hooks diff --git a/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION b/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION index 1defe531bfa..a4b6ac3ded6 100644 --- a/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION +++ b/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION @@ -1 +1 @@ -v2.1.0 +v2.2.0 diff --git a/internal/staticsources/rpicamera/params.go b/internal/staticsources/rpicamera/params.go index b5460d3ec6d..ec8641104fd 100644 --- a/internal/staticsources/rpicamera/params.go +++ b/internal/staticsources/rpicamera/params.go @@ -25,10 +25,6 @@ type params struct { TuningFile string Mode string FPS float64 - IDRPeriod int - Bitrate int - Profile string - Level string AfMode string AfRange string AfSpeed string @@ -37,4 +33,9 @@ type params struct { FlickerPeriod int TextOverlayEnable bool TextOverlay string + Codec string + IDRPeriod int + Bitrate int + Profile string + Level string } diff --git a/internal/staticsources/rpicamera/source.go b/internal/staticsources/rpicamera/source.go index 6f2c72b6ae4..75e702888c8 100644 --- a/internal/staticsources/rpicamera/source.go +++ b/internal/staticsources/rpicamera/source.go @@ -50,10 +50,6 @@ func paramsFromConf(logLevel conf.LogLevel, cnf *conf.Path) params { TuningFile: cnf.RPICameraTuningFile, Mode: cnf.RPICameraMode, FPS: cnf.RPICameraFPS, - IDRPeriod: cnf.RPICameraIDRPeriod, - Bitrate: cnf.RPICameraBitrate, - Profile: cnf.RPICameraProfile, - Level: cnf.RPICameraLevel, AfMode: cnf.RPICameraAfMode, AfRange: cnf.RPICameraAfRange, AfSpeed: cnf.RPICameraAfSpeed, @@ -62,6 +58,11 @@ func paramsFromConf(logLevel conf.LogLevel, cnf *conf.Path) params { FlickerPeriod: cnf.RPICameraFlickerPeriod, TextOverlayEnable: cnf.RPICameraTextOverlayEnable, TextOverlay: cnf.RPICameraTextOverlay, + Codec: cnf.RPICameraCodec, + IDRPeriod: cnf.RPICameraIDRPeriod, + Bitrate: cnf.RPICameraBitrate, + Profile: cnf.RPICameraProfile, + Level: cnf.RPICameraLevel, } } diff --git a/mediamtx.yml b/mediamtx.yml index 9bc18f1293f..ba713a9d08c 100644 --- a/mediamtx.yml +++ b/mediamtx.yml @@ -508,62 +508,54 @@ pathDefaults: # ID of the camera rpiCameraCamID: 0 - # width of frames + # Width of frames rpiCameraWidth: 1920 - # height of frames + # Height of frames rpiCameraHeight: 1080 - # flip horizontally + # Flip horizontally rpiCameraHFlip: false - # flip vertically + # Flip vertically rpiCameraVFlip: false - # brightness [-1, 1] + # Brightness [-1, 1] rpiCameraBrightness: 0 - # contrast [0, 16] + # Contrast [0, 16] rpiCameraContrast: 1 - # saturation [0, 16] + # Saturation [0, 16] rpiCameraSaturation: 1 - # sharpness [0, 16] + # Sharpness [0, 16] rpiCameraSharpness: 1 - # exposure mode. + # Exposure mode. # values: normal, short, long, custom rpiCameraExposure: normal - # auto-white-balance mode. + # Auto-white-balance mode. # values: auto, incandescent, tungsten, fluorescent, indoor, daylight, cloudy, custom rpiCameraAWB: auto - # auto-white-balance fixed gains. This can be used in place of rpiCameraAWB. + # 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 rpiCameraDenoise: "off" - # fixed shutter speed, in microseconds. + # Fixed shutter speed, in microseconds. rpiCameraShutter: 0 - # metering mode of the AEC/AGC algorithm. + # Metering mode of the AEC/AGC algorithm. # values: centre, spot, matrix, custom rpiCameraMetering: centre - # fixed gain + # Fixed gain rpiCameraGain: 0 # EV compensation of the image [-10, 10] rpiCameraEV: 0 # Region of interest, in format x,y,width,height rpiCameraROI: - # whether to enable HDR on Raspberry Camera 3. + # Whether to enable HDR on Raspberry Camera 3. rpiCameraHDR: false - # tuning file + # Tuning file rpiCameraTuningFile: - # sensor mode, in format [width]:[height]:[bit-depth]:[packing] + # Sensor mode, in format [width]:[height]:[bit-depth]:[packing] # bit-depth and packing are optional. rpiCameraMode: # frames per second rpiCameraFPS: 30 - # period between IDR frames - rpiCameraIDRPeriod: 60 - # bitrate - rpiCameraBitrate: 1000000 - # H264 profile - rpiCameraProfile: main - # H264 level - rpiCameraLevel: '4.1' # Autofocus mode # values: auto, manual, continuous rpiCameraAfMode: continuous @@ -584,11 +576,21 @@ pathDefaults: rpiCameraAfWindow: # Manual flicker correction period, in microseconds. rpiCameraFlickerPeriod: 0 - # enables printing text on each frame. + # Enables printing text on each frame. rpiCameraTextOverlayEnable: false - # text that is printed on each frame. + # Text that is printed on each frame. # format is the one of the strftime() function. rpiCameraTextOverlay: '%Y-%m-%d %H:%M:%S - MediaMTX' + # Codec. Available values: auto, hardwareH264, softwareH264 + rpiCameraCodec: auto + # Period between IDR frames + rpiCameraIDRPeriod: 60 + # Bitrate + rpiCameraBitrate: 1000000 + # H264 profile + rpiCameraProfile: main + # H264 level + rpiCameraLevel: '4.1' ############################################### # Default path settings -> Hooks