summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/sdp/v3/extmap.go
blob: 1242a8cf06bba1249b47540b7d41863b78ee5141 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package sdp

import (
	"fmt"
	"net/url"
	"strconv"
	"strings"
)

// Default ext values
const (
	DefExtMapValueABSSendTime     = 1
	DefExtMapValueTransportCC     = 2
	DefExtMapValueSDESMid         = 3
	DefExtMapValueSDESRTPStreamID = 4

	ABSSendTimeURI     = "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"
	TransportCCURI     = "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"
	SDESMidURI         = "urn:ietf:params:rtp-hdrext:sdes:mid"
	SDESRTPStreamIDURI = "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"
	AudioLevelURI      = "urn:ietf:params:rtp-hdrext:ssrc-audio-level"
)

// ExtMap represents the activation of a single RTP header extension
type ExtMap struct {
	Value     int
	Direction Direction
	URI       *url.URL
	ExtAttr   *string
}

// Clone converts this object to an Attribute
func (e *ExtMap) Clone() Attribute {
	return Attribute{Key: "extmap", Value: e.string()}
}

// Unmarshal creates an Extmap from a string
func (e *ExtMap) Unmarshal(raw string) error {
	parts := strings.SplitN(raw, ":", 2)
	if len(parts) != 2 {
		return fmt.Errorf("%w: %v", errSyntaxError, raw)
	}

	fields := strings.Fields(parts[1])
	if len(fields) < 2 {
		return fmt.Errorf("%w: %v", errSyntaxError, raw)
	}

	valdir := strings.Split(fields[0], "/")
	value, err := strconv.ParseInt(valdir[0], 10, 64)
	if (value < 1) || (value > 246) {
		return fmt.Errorf("%w: %v -- extmap key must be in the range 1-256", errSyntaxError, valdir[0])
	}
	if err != nil {
		return fmt.Errorf("%w: %v", errSyntaxError, valdir[0])
	}

	var direction Direction
	if len(valdir) == 2 {
		direction, err = NewDirection(valdir[1])
		if err != nil {
			return err
		}
	}

	uri, err := url.Parse(fields[1])
	if err != nil {
		return err
	}

	if len(fields) == 3 {
		tmp := fields[2]
		e.ExtAttr = &tmp
	}

	e.Value = int(value)
	e.Direction = direction
	e.URI = uri
	return nil
}

// Marshal creates a string from an ExtMap
func (e *ExtMap) Marshal() string {
	return e.Name() + ":" + e.string()
}

func (e *ExtMap) string() string {
	output := fmt.Sprintf("%d", e.Value)
	dirstring := e.Direction.String()
	if dirstring != directionUnknownStr {
		output += "/" + dirstring
	}

	if e.URI != nil {
		output += " " + e.URI.String()
	}

	if e.ExtAttr != nil {
		output += " " + *e.ExtAttr
	}

	return output
}

// Name returns the constant name of this object
func (e *ExtMap) Name() string {
	return "extmap"
}