mediamtx/utils.go

127 lines
2.4 KiB
Go

package main
import (
"fmt"
"net"
"strconv"
"github.com/aler9/gortsplib"
"github.com/aler9/sdp/v3"
)
func parseIpCidrList(in []string) ([]interface{}, error) {
if len(in) == 0 {
return nil, nil
}
var ret []interface{}
for _, t := range in {
_, ipnet, err := net.ParseCIDR(t)
if err == nil {
ret = append(ret, ipnet)
continue
}
ip := net.ParseIP(t)
if ip != nil {
ret = append(ret, ip)
continue
}
return nil, fmt.Errorf("unable to parse ip/network '%s'", t)
}
return ret, nil
}
func ipEqualOrInRange(ip net.IP, ips []interface{}) bool {
for _, item := range ips {
switch titem := item.(type) {
case net.IP:
if titem.Equal(ip) {
return true
}
case *net.IPNet:
if titem.Contains(ip) {
return true
}
}
}
return false
}
type doubleBuffer struct {
buf1 []byte
buf2 []byte
curBuf bool
}
func newDoubleBuffer(size int) *doubleBuffer {
return &doubleBuffer{
buf1: make([]byte, size),
buf2: make([]byte, size),
}
}
func (db *doubleBuffer) swap() []byte {
var ret []byte
if !db.curBuf {
ret = db.buf1
} else {
ret = db.buf2
}
db.curBuf = !db.curBuf
return ret
}
func sdpForServer(tracks []*gortsplib.Track) (*sdp.SessionDescription, []byte) {
sout := &sdp.SessionDescription{
SessionName: func() *sdp.SessionName {
ret := sdp.SessionName("Stream")
return &ret
}(),
Origin: &sdp.Origin{
Username: "-",
NetworkType: "IN",
AddressType: "IP4",
UnicastAddress: "127.0.0.1",
},
TimeDescriptions: []sdp.TimeDescription{
{Timing: sdp.Timing{0, 0}},
},
}
for i, track := range tracks {
mout := &sdp.MediaDescription{
MediaName: sdp.MediaName{
Media: track.Media.MediaName.Media,
Protos: []string{"RTP", "AVP"}, // override protocol
Formats: track.Media.MediaName.Formats,
},
Bandwidth: track.Media.Bandwidth,
Attributes: func() []sdp.Attribute {
var ret []sdp.Attribute
for _, attr := range track.Media.Attributes {
if attr.Key == "rtpmap" || attr.Key == "fmtp" {
ret = append(ret, attr)
}
}
// control attribute is mandatory, and is the path that is appended
// to the stream path in SETUP
ret = append(ret, sdp.Attribute{
Key: "control",
Value: "trackID=" + strconv.FormatInt(int64(i), 10),
})
return ret
}(),
}
sout.MediaDescriptions = append(sout.MediaDescriptions, mout)
}
bytsout, _ := sout.Marshal()
return sout, bytsout
}