diff --git a/internal/conf/path.go b/internal/conf/path.go index 7ace95fd..7128f6fd 100644 --- a/internal/conf/path.go +++ b/internal/conf/path.go @@ -701,9 +701,9 @@ func (pconf *Path) validate( if !pconf.RPICameraSecondary { switch pconf.RPICameraCodec { - case "auto", "hardwareH264", "softwareH264": + case "auto", "hardwareH264", "softwareH264", "mjpeg": default: - return fmt.Errorf("supported codecs for a primary RPI Camera stream are auto, hardwareH264, softwareH264") + return fmt.Errorf("supported codecs for a primary RPI Camera stream are auto, hardwareH264, softwareH264, mjpeg") } for otherName, otherPath := range conf.Paths { diff --git a/internal/staticsources/rpicamera/camera_params_arm_.go b/internal/staticsources/rpicamera/camera_params_arm_.go index a786ebbc..83bc34d1 100644 --- a/internal/staticsources/rpicamera/camera_params_arm_.go +++ b/internal/staticsources/rpicamera/camera_params_arm_.go @@ -50,6 +50,7 @@ type cameraParams struct { Bitrate uint32 H264Profile string H264Level string + MJPEGQuality uint32 SecondaryWidth uint32 SecondaryHeight uint32 @@ -146,6 +147,8 @@ func (p *cameraParams) fromConf(logLevel conf.LogLevel, cnf *conf.Path) { return cnf.RPICameraH264Level }() + p.MJPEGQuality = uint32(cnf.RPICameraMJPEGQuality) + p.SecondaryWidth = uint32(cnf.RPICameraSecondaryWidth) p.SecondaryHeight = uint32(cnf.RPICameraSecondaryHeight) p.SecondaryFPS = float32(cnf.RPICameraSecondaryFPS) diff --git a/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_32_TAR_GZ b/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_32_TAR_GZ index e2f05406..7bd669a7 100644 --- a/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_32_TAR_GZ +++ b/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_32_TAR_GZ @@ -1 +1 @@ -63f305e54d124427d39f3f428cbc22ca004bc5f0f5ea550ed2998299f11c4b4a +22aa13d2506cbfab4369114aca23643a2b5f0b2df681ef4407d4cd358973a2c7 diff --git a/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_64_TAR_GZ b/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_64_TAR_GZ index a2e08297..e914dbfb 100644 --- a/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_64_TAR_GZ +++ b/internal/staticsources/rpicamera/mtxrpicamdownloader/HASH_MTXRPICAM_64_TAR_GZ @@ -1 +1 @@ -5873f9fc54cb80714bf7ca577481de3a6ff9b928325b4ec87dde99c3bfd5b3f3 +6c58145ec21aae6a362e233e17e2fd93aa778848b5462848861128310270b3aa diff --git a/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION b/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION index 06646d7c..873ca0fa 100644 --- a/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION +++ b/internal/staticsources/rpicamera/mtxrpicamdownloader/VERSION @@ -1 +1 @@ -v2.6.1 +v2.7.0 diff --git a/internal/staticsources/rpicamera/source_arm_.go b/internal/staticsources/rpicamera/source_arm_.go index d05a0793..d980273a 100644 --- a/internal/staticsources/rpicamera/source_arm_.go +++ b/internal/staticsources/rpicamera/source_arm_.go @@ -51,13 +51,19 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error { } func (s *Source) runPrimary(params defs.StaticSourceRunParams) error { - var medias []*description.Media + var forma format.Format - forma := &format.H264{ - PayloadTyp: 96, - PacketizationMode: 1, + if params.Conf.RPICameraCodec == "auto" || params.Conf.RPICameraCodec == "hardwareH264" || params.Conf.RPICameraCodec == "softwareH264" { + forma = &format.H264{ + PayloadTyp: 96, + PacketizationMode: 1, + } + } else { + forma = &format.MJPEG{} } + var medias []*description.Media + media := &description.Media{ Type: description.MediaTypeVideo, Formats: []format.Format{forma}, @@ -78,24 +84,40 @@ func (s *Source) runPrimary(params defs.StaticSourceRunParams) error { medias = append(medias, mediaSecondary) } - encH264 := &rtph264.Encoder{ - PayloadType: 96, - PayloadMaxSize: s.RTPMaxPayloadSize, - PacketizationMode: 1, - } - err := encH264.Init() - if err != nil { - return err - } + var encode func(au []byte) ([]*rtp.Packet, error) - encode := func(au []byte) ([]*rtp.Packet, error) { - var nalus h264.AnnexB - err = nalus.Unmarshal(au) + if params.Conf.RPICameraCodec == "auto" || params.Conf.RPICameraCodec == "hardwareH264" || params.Conf.RPICameraCodec == "softwareH264" { + encH264 := &rtph264.Encoder{ + PayloadType: 96, + PayloadMaxSize: s.RTPMaxPayloadSize, + PacketizationMode: 1, + } + err := encH264.Init() if err != nil { - return nil, err + return err } - return encH264.Encode(nalus) + encode = func(au []byte) ([]*rtp.Packet, error) { + var nalus h264.AnnexB + err = nalus.Unmarshal(au) + if err != nil { + return nil, err + } + + return encH264.Encode(nalus) + } + } else { + encMJPEG := &rtpmjpeg.Encoder{ + PayloadMaxSize: s.RTPMaxPayloadSize, + } + err := encMJPEG.Init() + if err != nil { + return err + } + + encode = func(au []byte) ([]*rtp.Packet, error) { + return encMJPEG.Encode(au) + } } var subStream *stream.SubStream @@ -137,10 +159,10 @@ func (s *Source) runPrimary(params defs.StaticSourceRunParams) error { var onDataSecondary func(pts int64, ntp time.Time, au []byte) if params.Conf.RPICameraSecondaryWidth != 0 { - encJpeg := &rtpmjpeg.Encoder{ + secondaryEncMJPEG := &rtpmjpeg.Encoder{ PayloadMaxSize: s.RTPMaxPayloadSize, } - err := encJpeg.Init() + err := secondaryEncMJPEG.Init() if err != nil { panic(err) } @@ -148,7 +170,7 @@ func (s *Source) runPrimary(params defs.StaticSourceRunParams) error { onDataSecondary = func(pts int64, ntp time.Time, au []byte) { initializeSubStream() - pkts, err2 := encJpeg.Encode(au) + pkts, err2 := secondaryEncMJPEG.Encode(au) if err2 != nil { s.Log(logger.Error, err2.Error()) return @@ -180,8 +202,8 @@ func (s *Source) runPrimary(params defs.StaticSourceRunParams) error { onData: onData, onDataSecondary: onDataSecondary, } - err = cam.initialize() //nolint:staticcheck - if err != nil { //nolint:staticcheck + err := cam.initialize() //nolint:staticcheck + if err != nil { //nolint:staticcheck return err } defer cam.close()