-
Notifications
You must be signed in to change notification settings - Fork 177
/
client_format.go
111 lines (94 loc) · 2.49 KB
/
client_format.go
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
109
110
111
package gortsplib
import (
"time"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/aler9/gortsplib/v2/pkg/format"
"github.com/aler9/gortsplib/v2/pkg/rtcpreceiver"
"github.com/aler9/gortsplib/v2/pkg/rtcpsender"
"github.com/aler9/gortsplib/v2/pkg/rtpreorderer"
)
type clientFormat struct {
c *Client
cm *clientMedia
format format.Format
udpReorderer *rtpreorderer.Reorderer // play
udpRTCPReceiver *rtcpreceiver.RTCPReceiver // play
rtcpSender *rtcpsender.RTCPSender // record
onPacketRTP func(*rtp.Packet)
}
func newClientFormat(cm *clientMedia, forma format.Format) *clientFormat {
return &clientFormat{
c: cm.c,
cm: cm,
format: forma,
onPacketRTP: func(*rtp.Packet) {},
}
}
func (ct *clientFormat) start() {
if ct.cm.c.state == clientStatePlay {
if ct.cm.udpRTPListener != nil {
ct.udpReorderer = rtpreorderer.New()
ct.udpRTCPReceiver = rtcpreceiver.New(
ct.cm.c.udpReceiverReportPeriod,
nil,
ct.format.ClockRate(), func(pkt rtcp.Packet) {
ct.cm.writePacketRTCP(pkt)
})
}
} else {
ct.rtcpSender = rtcpsender.New(
ct.format.ClockRate(),
func(pkt rtcp.Packet) {
ct.cm.writePacketRTCP(pkt)
})
}
}
// start writing after write*() has been allocated in order to avoid a crash
func (ct *clientFormat) startWriting() {
if ct.c.state != clientStatePlay && !ct.c.DisableRTCPSenderReports {
ct.rtcpSender.Start(ct.c.senderReportPeriod)
}
}
func (ct *clientFormat) stop() {
if ct.udpRTCPReceiver != nil {
ct.udpRTCPReceiver.Close()
ct.udpRTCPReceiver = nil
}
if ct.rtcpSender != nil {
ct.rtcpSender.Close()
}
}
func (ct *clientFormat) writePacketRTPWithNTP(pkt *rtp.Packet, ntp time.Time) error {
byts := make([]byte, maxPacketSize)
n, err := pkt.MarshalTo(byts)
if err != nil {
return err
}
byts = byts[:n]
select {
case <-ct.c.done:
return ct.c.closeError
default:
}
ct.c.writer.queue(func() {
ct.cm.writePacketRTPInQueue(byts)
})
ct.rtcpSender.ProcessPacket(pkt, ntp, ct.format.PTSEqualsDTS(pkt))
return nil
}
func (ct *clientFormat) readRTPUDP(pkt *rtp.Packet) {
packets, missing := ct.udpReorderer.Process(pkt)
if missing != 0 {
ct.c.Log(LogLevelWarn, "%d RTP packet(s) lost", missing)
// do not return
}
now := time.Now()
for _, pkt := range packets {
ct.udpRTCPReceiver.ProcessPacket(pkt, now, ct.format.PTSEqualsDTS(pkt))
ct.onPacketRTP(pkt)
}
}
func (ct *clientFormat) readRTPTCP(pkt *rtp.Packet) {
ct.onPacketRTP(pkt)
}