mirror of
https://github.com/bluenviron/mediamtx.git
synced 2026-07-04 15:07:51 +00:00
rpi: add unified rpiCameraH264Profile, rpiCameraH264Level params (#5894)
These replace rpiCameraHardwareH264Profile, rpiCameraHardwareH264Level, rpiCameraSoftwareH264Profile, rpiCameraSoftwareH264Level.
This commit is contained in:
@@ -926,12 +926,24 @@ components:
|
||||
deprecated: true
|
||||
rpiCameraHardwareH264Profile:
|
||||
type: string
|
||||
nullable: true
|
||||
deprecated: true
|
||||
rpiCameraHardwareH264Level:
|
||||
type: string
|
||||
nullable: true
|
||||
deprecated: true
|
||||
rpiCameraSoftwareH264Profile:
|
||||
type: string
|
||||
nullable: true
|
||||
deprecated: true
|
||||
rpiCameraSoftwareH264Level:
|
||||
type: string
|
||||
nullable: true
|
||||
deprecated: true
|
||||
rpiCameraH264Profile:
|
||||
type: string
|
||||
rpiCameraH264Level:
|
||||
type: string
|
||||
rpiCameraJPEGQuality:
|
||||
type: integer
|
||||
format: uint64
|
||||
|
||||
+39
-41
@@ -93,47 +93,45 @@ func TestConfFromFile(t *testing.T) {
|
||||
pa, ok := conf.Paths["cam1"]
|
||||
require.Equal(t, true, ok)
|
||||
require.Equal(t, &Path{
|
||||
Name: "cam1",
|
||||
Source: "publisher",
|
||||
SourceOnDemandStartTimeout: 10 * Duration(time.Second),
|
||||
SourceOnDemandCloseAfter: 10 * Duration(time.Second),
|
||||
OverridePublisher: true,
|
||||
AlwaysAvailableTracks: []AlwaysAvailableTrack{},
|
||||
RecordPath: "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f",
|
||||
RecordFormat: RecordFormatFMP4,
|
||||
RecordPartDuration: Duration(1 * time.Second),
|
||||
RecordMaxPartSize: 50 * 1024 * 1024,
|
||||
RecordSegmentDuration: 3600000000000,
|
||||
RecordDeleteAfter: 86400000000000,
|
||||
RTSPUDPSourcePortRange: []uint{10000, 65535},
|
||||
WHEPSTUNGatherTimeout: 5 * Duration(time.Second),
|
||||
WHEPHandshakeTimeout: 10 * Duration(time.Second),
|
||||
WHEPTrackGatherTimeout: 2 * Duration(time.Second),
|
||||
RPICameraWidth: 1920,
|
||||
RPICameraHeight: 1080,
|
||||
RPICameraContrast: 1,
|
||||
RPICameraSaturation: 1,
|
||||
RPICameraSharpness: 1,
|
||||
RPICameraExposure: "normal",
|
||||
RPICameraAWB: "auto",
|
||||
RPICameraAWBGains: []float64{0, 0},
|
||||
RPICameraDenoise: "off",
|
||||
RPICameraMetering: "centre",
|
||||
RPICameraFPS: 30,
|
||||
RPICameraAfMode: "continuous",
|
||||
RPICameraAfRange: "normal",
|
||||
RPICameraAfSpeed: "normal",
|
||||
RPICameraTextOverlay: "%Y-%m-%d %H:%M:%S - MediaMTX",
|
||||
RPICameraCodec: "auto",
|
||||
RPICameraIDRPeriod: 60,
|
||||
RPICameraBitrate: 5000000,
|
||||
RPICameraHardwareH264Profile: "main",
|
||||
RPICameraHardwareH264Level: "4.1",
|
||||
RPICameraSoftwareH264Profile: "baseline",
|
||||
RPICameraSoftwareH264Level: "4.1",
|
||||
RPICameraMJPEGQuality: 60,
|
||||
RunOnDemandStartTimeout: 5 * Duration(time.Second),
|
||||
RunOnDemandCloseAfter: 10 * Duration(time.Second),
|
||||
Name: "cam1",
|
||||
Source: "publisher",
|
||||
SourceOnDemandStartTimeout: 10 * Duration(time.Second),
|
||||
SourceOnDemandCloseAfter: 10 * Duration(time.Second),
|
||||
OverridePublisher: true,
|
||||
AlwaysAvailableTracks: []AlwaysAvailableTrack{},
|
||||
RecordPath: "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f",
|
||||
RecordFormat: RecordFormatFMP4,
|
||||
RecordPartDuration: Duration(1 * time.Second),
|
||||
RecordMaxPartSize: 50 * 1024 * 1024,
|
||||
RecordSegmentDuration: 3600000000000,
|
||||
RecordDeleteAfter: 86400000000000,
|
||||
RTSPUDPSourcePortRange: []uint{10000, 65535},
|
||||
WHEPSTUNGatherTimeout: 5 * Duration(time.Second),
|
||||
WHEPHandshakeTimeout: 10 * Duration(time.Second),
|
||||
WHEPTrackGatherTimeout: 2 * Duration(time.Second),
|
||||
RPICameraWidth: 1920,
|
||||
RPICameraHeight: 1080,
|
||||
RPICameraContrast: 1,
|
||||
RPICameraSaturation: 1,
|
||||
RPICameraSharpness: 1,
|
||||
RPICameraExposure: "normal",
|
||||
RPICameraAWB: "auto",
|
||||
RPICameraAWBGains: []float64{0, 0},
|
||||
RPICameraDenoise: "off",
|
||||
RPICameraMetering: "centre",
|
||||
RPICameraFPS: 30,
|
||||
RPICameraAfMode: "continuous",
|
||||
RPICameraAfRange: "normal",
|
||||
RPICameraAfSpeed: "normal",
|
||||
RPICameraTextOverlay: "%Y-%m-%d %H:%M:%S - MediaMTX",
|
||||
RPICameraCodec: "auto",
|
||||
RPICameraIDRPeriod: 60,
|
||||
RPICameraBitrate: 5000000,
|
||||
RPICameraH264Profile: "auto",
|
||||
RPICameraH264Level: "4.1",
|
||||
RPICameraMJPEGQuality: 60,
|
||||
RunOnDemandStartTimeout: 5 * Duration(time.Second),
|
||||
RunOnDemandCloseAfter: 10 * Duration(time.Second),
|
||||
}, pa)
|
||||
}()
|
||||
|
||||
|
||||
+59
-27
@@ -314,10 +314,12 @@ type Path struct {
|
||||
RPICameraBitrate uint `json:"rpiCameraBitrate"`
|
||||
RPICameraProfile *string `json:"rpiCameraProfile,omitempty" deprecated:"true"`
|
||||
RPICameraLevel *string `json:"rpiCameraLevel,omitempty" deprecated:"true"`
|
||||
RPICameraHardwareH264Profile string `json:"rpiCameraHardwareH264Profile"`
|
||||
RPICameraHardwareH264Level string `json:"rpiCameraHardwareH264Level"`
|
||||
RPICameraSoftwareH264Profile string `json:"rpiCameraSoftwareH264Profile"`
|
||||
RPICameraSoftwareH264Level string `json:"rpiCameraSoftwareH264Level"`
|
||||
RPICameraHardwareH264Profile *string `json:"rpiCameraHardwareH264Profile,omitempty" deprecated:"true"`
|
||||
RPICameraHardwareH264Level *string `json:"rpiCameraHardwareH264Level,omitempty" deprecated:"true"`
|
||||
RPICameraSoftwareH264Profile *string `json:"rpiCameraSoftwareH264Profile,omitempty" deprecated:"true"`
|
||||
RPICameraSoftwareH264Level *string `json:"rpiCameraSoftwareH264Level,omitempty" deprecated:"true"`
|
||||
RPICameraH264Profile string `json:"rpiCameraH264Profile"`
|
||||
RPICameraH264Level string `json:"rpiCameraH264Level"`
|
||||
RPICameraJPEGQuality *uint `json:"rpiCameraJPEGQuality,omitempty" deprecated:"true"`
|
||||
RPICameraMJPEGQuality uint `json:"rpiCameraMJPEGQuality"`
|
||||
RPICameraPrimaryName string `json:"-"` // filled by Validate()
|
||||
@@ -388,10 +390,8 @@ func (pconf *Path) setDefaults() {
|
||||
pconf.RPICameraCodec = "auto"
|
||||
pconf.RPICameraIDRPeriod = 60
|
||||
pconf.RPICameraBitrate = 5000000
|
||||
pconf.RPICameraHardwareH264Profile = "main"
|
||||
pconf.RPICameraHardwareH264Level = "4.1"
|
||||
pconf.RPICameraSoftwareH264Profile = "baseline"
|
||||
pconf.RPICameraSoftwareH264Level = "4.1"
|
||||
pconf.RPICameraH264Profile = "auto"
|
||||
pconf.RPICameraH264Level = "4.1"
|
||||
pconf.RPICameraMJPEGQuality = 60
|
||||
|
||||
// Hooks
|
||||
@@ -628,37 +628,69 @@ func (pconf *Path) validate(
|
||||
if pconf.RPICameraProfile != nil {
|
||||
l.Log(logger.Warn, "parameter 'rpiCameraProfile' is deprecated"+
|
||||
" and has been replaced with 'rpiCameraHardwareH264Profile'")
|
||||
pconf.RPICameraHardwareH264Profile = *pconf.RPICameraProfile
|
||||
pconf.RPICameraHardwareH264Profile = pconf.RPICameraProfile
|
||||
}
|
||||
|
||||
if pconf.RPICameraLevel != nil {
|
||||
l.Log(logger.Warn, "parameter 'rpiCameraLevel' is deprecated"+
|
||||
" and has been replaced with 'rpiCameraHardwareH264Level'")
|
||||
pconf.RPICameraHardwareH264Level = *pconf.RPICameraLevel
|
||||
pconf.RPICameraHardwareH264Level = pconf.RPICameraLevel
|
||||
}
|
||||
|
||||
switch pconf.RPICameraHardwareH264Profile {
|
||||
case "baseline", "main", "high":
|
||||
if pconf.RPICameraHardwareH264Profile != nil {
|
||||
l.Log(logger.Warn, "parameter 'rpiCameraHardwareH264Profile' is deprecated"+
|
||||
" and has been replaced with 'rpiCameraH264Profile'")
|
||||
|
||||
switch *pconf.RPICameraHardwareH264Profile {
|
||||
case "baseline", "main", "high":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraHardwareH264Profile' value")
|
||||
}
|
||||
}
|
||||
|
||||
if pconf.RPICameraHardwareH264Level != nil {
|
||||
l.Log(logger.Warn, "parameter 'rpiCameraHardwareH264Level' is deprecated"+
|
||||
" and has been replaced with 'rpiCameraH264Level'")
|
||||
|
||||
switch *pconf.RPICameraHardwareH264Level {
|
||||
case "4.0", "4.1", "4.2":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraHardwareH264Level' value")
|
||||
}
|
||||
}
|
||||
|
||||
if pconf.RPICameraSoftwareH264Profile != nil {
|
||||
l.Log(logger.Warn, "parameter 'rpiCameraSoftwareH264Profile' is deprecated"+
|
||||
" and has been replaced with 'rpiCameraH264Profile'")
|
||||
|
||||
switch *pconf.RPICameraSoftwareH264Profile {
|
||||
case "baseline", "main", "high":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraSoftwareH264Profile' value")
|
||||
}
|
||||
}
|
||||
|
||||
if pconf.RPICameraSoftwareH264Level != nil {
|
||||
l.Log(logger.Warn, "parameter 'rpiCameraSoftwareH264Level' is deprecated"+
|
||||
" and has been replaced with 'rpiCameraH264Level'")
|
||||
|
||||
switch *pconf.RPICameraSoftwareH264Level {
|
||||
case "4.0", "4.1", "4.2":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraSoftwareH264Level' value")
|
||||
}
|
||||
}
|
||||
|
||||
switch pconf.RPICameraH264Profile {
|
||||
case "auto", "baseline", "main", "high":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraHardwareH264Profile' value")
|
||||
return fmt.Errorf("invalid 'rpiCameraH264Profile' value")
|
||||
}
|
||||
|
||||
switch pconf.RPICameraHardwareH264Level {
|
||||
switch pconf.RPICameraH264Level {
|
||||
case "4.0", "4.1", "4.2":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraHardwareH264Level' value")
|
||||
}
|
||||
|
||||
switch pconf.RPICameraSoftwareH264Profile {
|
||||
case "baseline", "main", "high":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraSoftwareH264Profile' value")
|
||||
}
|
||||
|
||||
switch pconf.RPICameraSoftwareH264Level {
|
||||
case "4.0", "4.1", "4.2":
|
||||
default:
|
||||
return fmt.Errorf("invalid 'rpiCameraSoftwareH264Level' value")
|
||||
return fmt.Errorf("invalid 'rpiCameraH264Level' value")
|
||||
}
|
||||
|
||||
if pconf.RPICameraJPEGQuality != nil {
|
||||
|
||||
@@ -13,45 +13,43 @@ import (
|
||||
)
|
||||
|
||||
type cameraParams struct {
|
||||
LogLevel string
|
||||
CameraID uint32
|
||||
Width uint32
|
||||
Height uint32
|
||||
HFlip bool
|
||||
VFlip bool
|
||||
Brightness float32
|
||||
Contrast float32
|
||||
Saturation float32
|
||||
Sharpness float32
|
||||
Exposure string
|
||||
AWB string
|
||||
AWBGainRed float32
|
||||
AWBGainBlue float32
|
||||
Denoise string
|
||||
Shutter uint32
|
||||
Metering string
|
||||
Gain float32
|
||||
EV float32
|
||||
ROI string
|
||||
HDR bool
|
||||
TuningFile string
|
||||
Mode string
|
||||
FPS float32
|
||||
AfMode string
|
||||
AfRange string
|
||||
AfSpeed string
|
||||
LensPosition float32
|
||||
AfWindow string
|
||||
FlickerPeriod uint32
|
||||
TextOverlayEnable bool
|
||||
TextOverlay string
|
||||
Codec string
|
||||
IDRPeriod uint32
|
||||
Bitrate uint32
|
||||
HardwareH264Profile string
|
||||
HardwareH264Level string
|
||||
SoftwareH264Profile string
|
||||
SoftwareH264Level string
|
||||
LogLevel string
|
||||
CameraID uint32
|
||||
Width uint32
|
||||
Height uint32
|
||||
HFlip bool
|
||||
VFlip bool
|
||||
Brightness float32
|
||||
Contrast float32
|
||||
Saturation float32
|
||||
Sharpness float32
|
||||
Exposure string
|
||||
AWB string
|
||||
AWBGainRed float32
|
||||
AWBGainBlue float32
|
||||
Denoise string
|
||||
Shutter uint32
|
||||
Metering string
|
||||
Gain float32
|
||||
EV float32
|
||||
ROI string
|
||||
HDR bool
|
||||
TuningFile string
|
||||
Mode string
|
||||
FPS float32
|
||||
AfMode string
|
||||
AfRange string
|
||||
AfSpeed string
|
||||
LensPosition float32
|
||||
AfWindow string
|
||||
FlickerPeriod uint32
|
||||
TextOverlayEnable bool
|
||||
TextOverlay string
|
||||
Codec string
|
||||
IDRPeriod uint32
|
||||
Bitrate uint32
|
||||
H264Profile string
|
||||
H264Level string
|
||||
|
||||
SecondaryWidth uint32
|
||||
SecondaryHeight uint32
|
||||
@@ -102,13 +100,51 @@ func (p *cameraParams) fromConf(logLevel conf.LogLevel, cnf *conf.Path) {
|
||||
p.FlickerPeriod = uint32(cnf.RPICameraFlickerPeriod)
|
||||
p.TextOverlayEnable = cnf.RPICameraTextOverlayEnable
|
||||
p.TextOverlay = cnf.RPICameraTextOverlay
|
||||
p.Codec = cnf.RPICameraCodec
|
||||
|
||||
p.Codec = func() string {
|
||||
if cnf.RPICameraCodec == "auto" {
|
||||
if !cnf.RPICameraSecondary {
|
||||
if supportsHardwareH264() {
|
||||
return "hardwareH264"
|
||||
}
|
||||
return "softwareH264"
|
||||
}
|
||||
return "mjpeg"
|
||||
}
|
||||
return cnf.RPICameraCodec
|
||||
}()
|
||||
|
||||
p.IDRPeriod = uint32(cnf.RPICameraIDRPeriod)
|
||||
p.Bitrate = uint32(cnf.RPICameraBitrate)
|
||||
p.HardwareH264Profile = cnf.RPICameraHardwareH264Profile
|
||||
p.HardwareH264Level = cnf.RPICameraHardwareH264Level
|
||||
p.SoftwareH264Profile = cnf.RPICameraSoftwareH264Profile
|
||||
p.SoftwareH264Level = cnf.RPICameraSoftwareH264Level
|
||||
|
||||
p.H264Profile = func() string {
|
||||
if p.Codec == "hardwareH264" && cnf.RPICameraHardwareH264Profile != nil {
|
||||
return *cnf.RPICameraHardwareH264Profile
|
||||
}
|
||||
if p.Codec == "softwareH264" && cnf.RPICameraSoftwareH264Profile != nil {
|
||||
return *cnf.RPICameraSoftwareH264Profile
|
||||
}
|
||||
|
||||
if cnf.RPICameraH264Profile == "auto" {
|
||||
if p.Codec == "hardwareH264" {
|
||||
return "main"
|
||||
}
|
||||
return "baseline"
|
||||
}
|
||||
|
||||
return cnf.RPICameraH264Profile
|
||||
}()
|
||||
|
||||
p.H264Level = func() string {
|
||||
if p.Codec == "hardwareH264" && cnf.RPICameraHardwareH264Level != nil {
|
||||
return *cnf.RPICameraHardwareH264Level
|
||||
}
|
||||
if p.Codec == "softwareH264" && cnf.RPICameraSoftwareH264Level != nil {
|
||||
return *cnf.RPICameraSoftwareH264Level
|
||||
}
|
||||
|
||||
return cnf.RPICameraH264Level
|
||||
}()
|
||||
|
||||
p.SecondaryWidth = uint32(cnf.RPICameraSecondaryWidth)
|
||||
p.SecondaryHeight = uint32(cnf.RPICameraSecondaryHeight)
|
||||
|
||||
@@ -1 +1 @@
|
||||
4d9f7785e225af4c84d54dc36a5e44fc255188e3a2db291ccf7fa3093adc549d
|
||||
63f305e54d124427d39f3f428cbc22ca004bc5f0f5ea550ed2998299f11c4b4a
|
||||
|
||||
@@ -1 +1 @@
|
||||
8448f91064c9d659aa28dd22141ab4b82918d5990a8c3939cebcb2013a58f346
|
||||
5873f9fc54cb80714bf7ca577481de3a6ff9b928325b4ec87dde99c3bfd5b3f3
|
||||
|
||||
@@ -1 +1 @@
|
||||
v2.6.0
|
||||
v2.6.1
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//go:build (linux && arm) || (linux && arm64)
|
||||
|
||||
package rpicamera
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type v4l2Capability struct {
|
||||
Driver [16]byte
|
||||
Card [32]byte
|
||||
BusInfo [32]byte
|
||||
Version uint32
|
||||
Capabilities uint32
|
||||
DeviceCaps uint32
|
||||
Reserved [3]uint32
|
||||
}
|
||||
|
||||
const VIDIOC_QUERYCAP = 0x80685600
|
||||
|
||||
func supportsHardwareH264() bool {
|
||||
file, err := os.OpenFile("/dev/video11", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var caps v4l2Capability
|
||||
|
||||
_, _, errno := syscall.Syscall(
|
||||
syscall.SYS_IOCTL,
|
||||
file.Fd(),
|
||||
uintptr(VIDIOC_QUERYCAP),
|
||||
uintptr(unsafe.Pointer(&caps)),
|
||||
)
|
||||
if errno != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.HasPrefix(caps.Card[:], []byte("bcm2835-codec"))
|
||||
}
|
||||
+12
-11
@@ -701,22 +701,23 @@ pathDefaults:
|
||||
# format is the one of the strftime() function.
|
||||
rpiCameraTextOverlay: "%Y-%m-%d %H:%M:%S - MediaMTX"
|
||||
# Codec (auto, hardwareH264, softwareH264 or mjpeg).
|
||||
# When is "auto" and stream is primary, it defaults to hardwareH264 (if available) or softwareH264.
|
||||
# When is "auto" and stream is secondary, it defaults to mjpeg.
|
||||
# When is "auto", it defaults to:
|
||||
# * hardwareH264 when stream is primary and hardware encoder is available
|
||||
# * softwareH264 when stream is primary and hardware encoder is not available
|
||||
# * mjpeg when stream is secondary
|
||||
rpiCameraCodec: auto
|
||||
# Period between IDR frames (when codec is hardwareH264 or softwareH264).
|
||||
rpiCameraIDRPeriod: 60
|
||||
# Bitrate (when codec is hardwareH264 or softwareH264).
|
||||
rpiCameraBitrate: 5000000
|
||||
# Hardware H264 profile (baseline, main or high) (when codec is hardwareH264).
|
||||
rpiCameraHardwareH264Profile: main
|
||||
# Hardware H264 level (4.0, 4.1 or 4.2) (when codec is hardwareH264).
|
||||
rpiCameraHardwareH264Level: "4.1"
|
||||
# Software H264 profile (baseline, main or high) (when codec is softwareH264).
|
||||
rpiCameraSoftwareH264Profile: baseline
|
||||
# Software H264 level (4.0, 4.1 or 4.2) (when codec is softwareH264).
|
||||
rpiCameraSoftwareH264Level: "4.1"
|
||||
# M-JPEG JPEG quality (when codec is mjpeg).
|
||||
# H264 profile (auto, baseline, main or high).
|
||||
# When is "auto", it defaults to:
|
||||
# * main when codec is hardwareH264
|
||||
# * baseline when codec is softwareH264
|
||||
rpiCameraH264Profile: auto
|
||||
# H264 level (4.0, 4.1 or 4.2).
|
||||
rpiCameraH264Level: "4.1"
|
||||
# M-JPEG quality (0-100).
|
||||
rpiCameraMJPEGQuality: 60
|
||||
|
||||
###############################################
|
||||
|
||||
Reference in New Issue
Block a user