Files
gortsplib/pkg/headers/rtpinfo.go

101 lines
1.9 KiB
Go

package headers
import (
"fmt"
"strconv"
"strings"
"github.com/aler9/gortsplib/pkg/base"
)
// RTPInfoEntry is an entry of an RTP-Info header.
type RTPInfoEntry struct {
URL *base.URL
SequenceNumber uint16
Timestamp uint32
}
// RTPInfo is a RTP-Info header.
type RTPInfo []*RTPInfoEntry
// ReadRTPInfo decodes a RTP-Info header.
func ReadRTPInfo(v base.HeaderValue) (*RTPInfo, error) {
if len(v) == 0 {
return nil, fmt.Errorf("value not provided")
}
if len(v) > 1 {
return nil, fmt.Errorf("value provided multiple times (%v)", v)
}
h := &RTPInfo{}
for _, tmp := range strings.Split(v[0], ",") {
e := &RTPInfoEntry{}
for _, kv := range strings.Split(tmp, ";") {
tmp := strings.SplitN(kv, "=", 2)
if len(tmp) != 2 {
return nil, fmt.Errorf("unable to parse key-value (%v)", kv)
}
k, v := tmp[0], tmp[1]
switch k {
case "url":
vu, err := base.ParseURL(v)
if err != nil {
return nil, err
}
e.URL = vu
case "seq":
vi, err := strconv.ParseUint(v, 10, 16)
if err != nil {
return nil, err
}
e.SequenceNumber = uint16(vi)
case "rtptime":
vi, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return nil, err
}
e.Timestamp = uint32(vi)
default:
return nil, fmt.Errorf("invalid key: %v", k)
}
}
*h = append(*h, e)
}
return h, nil
}
// Clone clones a RTPInfo.
func (h RTPInfo) Clone() *RTPInfo {
nh := &RTPInfo{}
for _, e := range h {
*nh = append(*nh, &RTPInfoEntry{
URL: e.URL,
SequenceNumber: e.SequenceNumber,
Timestamp: e.Timestamp,
})
}
return nh
}
// Write encodes a RTP-Info header.
func (h RTPInfo) Write() base.HeaderValue {
var rets []string
for _, e := range h {
rets = append(rets, "url="+e.URL.String()+
";seq="+strconv.FormatUint(uint64(e.SequenceNumber), 10)+
";rtptime="+strconv.FormatUint(uint64(e.Timestamp), 10))
}
return base.HeaderValue{strings.Join(rets, ",")}
}