1
1
package gortsplib
2
2
3
3
import (
4
- "crypto/rand"
5
4
"fmt"
6
5
"net"
7
6
"strconv"
@@ -15,159 +14,124 @@ import (
15
14
"github.com/bluenviron/gortsplib/v4/pkg/liberrors"
16
15
)
17
16
18
- type clientMedia struct {
19
- c * Client
20
- media * description.Media
21
- secure bool
22
-
23
- srtpOutCtx * wrappedSRTPContext
24
- srtpInCtx * wrappedSRTPContext
25
- onPacketRTCP OnPacketRTCPFunc
26
- formats map [uint8 ]* clientFormat
27
- tcpChannel int
28
- udpRTPListener * clientUDPListener
29
- udpRTCPListener * clientUDPListener
30
- writePacketRTCPInQueue func ([]byte ) error
31
- bytesReceived * uint64
32
- bytesSent * uint64
33
- rtpPacketsInError * uint64
34
- rtcpPacketsReceived * uint64
35
- rtcpPacketsSent * uint64
36
- rtcpPacketsInError * uint64
37
- }
38
-
39
- func (cm * clientMedia ) initialize () error {
40
- cm .onPacketRTCP = func (rtcp.Packet ) {}
41
- cm .bytesReceived = new (uint64 )
42
- cm .bytesSent = new (uint64 )
43
- cm .rtpPacketsInError = new (uint64 )
44
- cm .rtcpPacketsReceived = new (uint64 )
45
- cm .rtcpPacketsSent = new (uint64 )
46
- cm .rtcpPacketsInError = new (uint64 )
47
-
48
- cm .formats = make (map [uint8 ]* clientFormat )
49
-
50
- for _ , forma := range cm .media .Formats {
51
- f := & clientFormat {
52
- cm : cm ,
53
- format : forma ,
54
- onPacketRTP : func (* rtp.Packet ) {},
55
- }
56
- err := f .initialize ()
57
- if err != nil {
58
- return err
59
- }
60
-
61
- cm .formats [forma .PayloadType ()] = f
62
- }
63
-
64
- if cm .secure {
65
- var srtpOutKey []byte
66
- if cm .c .state == clientStatePreRecord {
67
- srtpOutKey = cm .c .announceData [cm .media ].srtpOutKey
68
- } else {
69
- srtpOutKey = make ([]byte , srtpKeyLength )
70
- _ , err := rand .Read (srtpOutKey )
71
- if err != nil {
72
- return err
73
- }
74
- }
75
-
76
- ssrcs := make ([]uint32 , len (cm .formats ))
77
- n := 0
78
- for _ , cf := range cm .formats {
79
- ssrcs [n ] = cf .localSSRC
80
- n ++
81
- }
82
-
83
- cm .srtpOutCtx = & wrappedSRTPContext {
84
- key : srtpOutKey ,
85
- ssrcs : ssrcs ,
86
- }
87
- err := cm .srtpOutCtx .initialize ()
88
- if err != nil {
89
- return err
90
- }
91
- }
92
-
93
- return nil
94
- }
95
-
96
- func (cm * clientMedia ) close () {
97
- if cm .udpRTPListener != nil {
98
- cm .udpRTPListener .close ()
99
- cm .udpRTCPListener .close ()
100
- }
101
- }
102
-
103
- func (cm * clientMedia ) createUDPListeners (
17
+ func createUDPListenerPair (
18
+ c * Client ,
104
19
multicast bool ,
105
20
multicastInterface * net.Interface ,
106
21
rtpAddress string ,
107
22
rtcpAddress string ,
108
- ) error {
23
+ ) ( * clientUDPListener , * clientUDPListener , error ) {
109
24
if rtpAddress != ":0" {
110
25
l1 := & clientUDPListener {
111
- c : cm . c ,
26
+ c : c ,
112
27
multicast : multicast ,
113
28
multicastInterface : multicastInterface ,
114
29
address : rtpAddress ,
115
30
}
116
31
err := l1 .initialize ()
117
32
if err != nil {
118
- return err
33
+ return nil , nil , err
119
34
}
120
35
121
36
l2 := & clientUDPListener {
122
- c : cm . c ,
37
+ c : c ,
123
38
multicast : multicast ,
124
39
multicastInterface : multicastInterface ,
125
40
address : rtcpAddress ,
126
41
}
127
42
err = l2 .initialize ()
128
43
if err != nil {
129
44
l1 .close ()
130
- return err
45
+ return nil , nil , err
131
46
}
132
47
133
- cm .udpRTPListener , cm .udpRTCPListener = l1 , l2
134
- return nil
48
+ return l1 , l2 , nil
135
49
}
136
50
137
51
// pick two consecutive ports in range 65535-10000
138
52
// RTP port must be even and RTCP port odd
139
53
for {
140
54
v , err := randInRange ((65535 - 10000 ) / 2 )
141
55
if err != nil {
142
- return err
56
+ return nil , nil , err
143
57
}
144
58
145
59
rtpPort := v * 2 + 10000
146
60
rtcpPort := rtpPort + 1
147
61
148
- cm . udpRTPListener = & clientUDPListener {
149
- c : cm . c ,
62
+ l1 : = & clientUDPListener {
63
+ c : c ,
150
64
address : net .JoinHostPort ("" , strconv .FormatInt (int64 (rtpPort ), 10 )),
151
65
}
152
- err = cm . udpRTPListener .initialize ()
66
+ err = l1 .initialize ()
153
67
if err != nil {
154
- cm .udpRTPListener = nil
155
68
continue
156
69
}
157
70
158
- cm . udpRTCPListener = & clientUDPListener {
159
- c : cm . c ,
71
+ l2 : = & clientUDPListener {
72
+ c : c ,
160
73
address : net .JoinHostPort ("" , strconv .FormatInt (int64 (rtcpPort ), 10 )),
161
74
}
162
- err = cm . udpRTCPListener .initialize ()
75
+ err = l2 .initialize ()
163
76
if err != nil {
164
- cm .udpRTPListener .close ()
165
- cm .udpRTPListener = nil
166
- cm .udpRTCPListener = nil
77
+ l2 .close ()
167
78
continue
168
79
}
169
80
170
- return nil
81
+ return l1 , l2 , nil
82
+ }
83
+ }
84
+
85
+ type clientMedia struct {
86
+ c * Client
87
+ media * description.Media
88
+ secure bool
89
+ udpRTPListener * clientUDPListener
90
+ udpRTCPListener * clientUDPListener
91
+ tcpChannel int
92
+ localSSRCs map [uint8 ]uint32
93
+ srtpInCtx * wrappedSRTPContext
94
+ srtpOutCtx * wrappedSRTPContext
95
+
96
+ onPacketRTCP OnPacketRTCPFunc
97
+ formats map [uint8 ]* clientFormat
98
+ writePacketRTCPInQueue func ([]byte ) error
99
+ bytesReceived * uint64
100
+ bytesSent * uint64
101
+ rtpPacketsInError * uint64
102
+ rtcpPacketsReceived * uint64
103
+ rtcpPacketsSent * uint64
104
+ rtcpPacketsInError * uint64
105
+ }
106
+
107
+ func (cm * clientMedia ) initialize () {
108
+ cm .onPacketRTCP = func (rtcp.Packet ) {}
109
+ cm .bytesReceived = new (uint64 )
110
+ cm .bytesSent = new (uint64 )
111
+ cm .rtpPacketsInError = new (uint64 )
112
+ cm .rtcpPacketsReceived = new (uint64 )
113
+ cm .rtcpPacketsSent = new (uint64 )
114
+ cm .rtcpPacketsInError = new (uint64 )
115
+
116
+ cm .formats = make (map [uint8 ]* clientFormat )
117
+
118
+ for _ , forma := range cm .media .Formats {
119
+ f := & clientFormat {
120
+ cm : cm ,
121
+ format : forma ,
122
+ localSSRC : cm .localSSRCs [forma .PayloadType ()],
123
+ onPacketRTP : func (* rtp.Packet ) {},
124
+ }
125
+ f .initialize ()
126
+ cm .formats [forma .PayloadType ()] = f
127
+ }
128
+ }
129
+
130
+ func (cm * clientMedia ) close () {
131
+ cm .stop ()
132
+
133
+ for _ , ct := range cm .formats {
134
+ ct .close ()
171
135
}
172
136
}
173
137
@@ -198,10 +162,6 @@ func (cm *clientMedia) start() {
198
162
}
199
163
}
200
164
201
- for _ , ct := range cm .formats {
202
- ct .start ()
203
- }
204
-
205
165
if cm .udpRTPListener != nil {
206
166
cm .udpRTPListener .start ()
207
167
cm .udpRTCPListener .start ()
@@ -213,10 +173,6 @@ func (cm *clientMedia) stop() {
213
173
cm .udpRTPListener .stop ()
214
174
cm .udpRTCPListener .stop ()
215
175
}
216
-
217
- for _ , ct := range cm .formats {
218
- ct .stop ()
219
- }
220
176
}
221
177
222
178
func (cm * clientMedia ) findFormatByRemoteSSRC (ssrc uint32 ) * clientFormat {
@@ -460,6 +416,13 @@ func (cm *clientMedia) writePacketRTCP(pkt rtcp.Packet) error {
460
416
buf = encr
461
417
}
462
418
419
+ cm .c .writerMutex .RLock ()
420
+ defer cm .c .writerMutex .RUnlock ()
421
+
422
+ if cm .c .writer == nil {
423
+ return nil
424
+ }
425
+
463
426
ok := cm .c .writer .push (func () error {
464
427
return cm .writePacketRTCPInQueue (buf )
465
428
})
0 commit comments