Skip to content

Commit f30b304

Browse files
Improve memory efficiency
Refactored packet processing to avoid multiple make calls and eliminate append usage. This reduces garbage collection overhead and enhances overall memory management efficiency.
1 parent 96a23bb commit f30b304

File tree

4 files changed

+50
-19
lines changed

4 files changed

+50
-19
lines changed

pkg/nack/generator_interceptor.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ func (n *GeneratorInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
145145

146146
senderSSRC := rand.Uint32() // #nosec
147147

148+
missingPacketSeqNums := make([]uint16, n.size)
149+
filteredMissingPacket := make([]uint16, n.size)
150+
148151
ticker := time.NewTicker(n.interval)
149152
defer ticker.Stop()
150153
for {
@@ -155,7 +158,7 @@ func (n *GeneratorInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
155158
defer n.receiveLogsMu.Unlock()
156159

157160
for ssrc, receiveLog := range n.receiveLogs {
158-
missing := receiveLog.missingSeqNumbers(n.skipLastN)
161+
missing := receiveLog.missingSeqNumbers(n.skipLastN, missingPacketSeqNums)
159162

160163
if len(missing) == 0 || n.nackCountLogs[ssrc] == nil {
161164
n.nackCountLogs[ssrc] = map[uint16]uint16{}
@@ -164,22 +167,33 @@ func (n *GeneratorInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
164167
continue
165168
}
166169

167-
filteredMissing := []uint16{}
170+
nack := &rtcp.TransportLayerNack{} // nolint:ineffassign,wastedassign
171+
172+
c := 0 // nolint:varnamelen,
168173
if n.maxNacksPerPacket > 0 {
169174
for _, missingSeq := range missing {
170175
if n.nackCountLogs[ssrc][missingSeq] < n.maxNacksPerPacket {
171-
filteredMissing = append(filteredMissing, missingSeq)
176+
filteredMissingPacket[c] = missingSeq
177+
c++
172178
}
173179
n.nackCountLogs[ssrc][missingSeq]++
174180
}
175-
} else {
176-
filteredMissing = missing
177-
}
178181

179-
nack := &rtcp.TransportLayerNack{
180-
SenderSSRC: senderSSRC,
181-
MediaSSRC: ssrc,
182-
Nacks: rtcp.NackPairsFromSequenceNumbers(filteredMissing),
182+
if c == 0 {
183+
continue
184+
}
185+
186+
nack = &rtcp.TransportLayerNack{
187+
SenderSSRC: senderSSRC,
188+
MediaSSRC: ssrc,
189+
Nacks: rtcp.NackPairsFromSequenceNumbers(filteredMissingPacket[:c]),
190+
}
191+
} else {
192+
nack = &rtcp.TransportLayerNack{
193+
SenderSSRC: senderSSRC,
194+
MediaSSRC: ssrc,
195+
Nacks: rtcp.NackPairsFromSequenceNumbers(missing),
196+
}
183197
}
184198

185199
for nackSeq := range n.nackCountLogs[ssrc] {
@@ -196,10 +210,6 @@ func (n *GeneratorInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
196210
}
197211
}
198212

199-
if len(filteredMissing) == 0 {
200-
continue
201-
}
202-
203213
if _, err := rtcpWriter.Write([]rtcp.Packet{nack}, interceptor.Attributes{}); err != nil {
204214
n.log.Warnf("failed sending nack: %+v", err)
205215
}

pkg/nack/generator_interceptor_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func TestGeneratorInterceptor(t *testing.T) {
2020
f, err := NewGeneratorInterceptor(
2121
GeneratorSize(64),
2222
GeneratorSkipLastN(2),
23+
GeneratorMaxNacksPerPacket(10),
2324
GeneratorInterval(interval),
2425
GeneratorLog(logging.NewDefaultLoggerFactory().NewLogger("test")),
2526
)

pkg/nack/receive_log.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (s *receiveLog) get(seq uint16) bool {
9797
return s.getReceived(seq)
9898
}
9999

100-
func (s *receiveLog) missingSeqNumbers(skipLastN uint16) []uint16 {
100+
func (s *receiveLog) missingSeqNumbers(skipLastN uint16, missingPacketSeqNums []uint16) []uint16 {
101101
s.m.RLock()
102102
defer s.m.RUnlock()
103103

@@ -107,14 +107,15 @@ func (s *receiveLog) missingSeqNumbers(skipLastN uint16) []uint16 {
107107
return nil
108108
}
109109

110-
missingPacketSeqNums := make([]uint16, 0)
110+
c := 0
111111
for i := s.lastConsecutive + 1; i != until+1; i++ {
112112
if !s.getReceived(i) {
113-
missingPacketSeqNums = append(missingPacketSeqNums, i)
113+
missingPacketSeqNums[c] = i
114+
c++
114115
}
115116
}
116117

117-
return missingPacketSeqNums
118+
return missingPacketSeqNums[:c]
118119
}
119120

120121
func (s *receiveLog) setReceived(seq uint16) {

pkg/nack/receive_log_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ func TestReceivedBuffer(t *testing.T) {
6161
}
6262
assertMissing := func(skipLastN uint16, nums []uint16) {
6363
t.Helper()
64-
missing := rl.missingSeqNumbers(skipLastN)
64+
missingPacketSeqNums := make([]uint16, rl.size)
65+
missing := rl.missingSeqNumbers(skipLastN, missingPacketSeqNums)
6566
if missing == nil {
6667
missing = []uint16{}
6768
}
@@ -131,6 +132,24 @@ func TestReceivedBuffer(t *testing.T) {
131132
assertGet(321)
132133
assertMissing(0, all(330, 332))
133134
assertLastConsecutive(329) // after adding a single missing packet, lastConsecutive should jump forward
135+
136+
add(all(330, 332)...)
137+
assertMissing(0, []uint16{})
138+
assertLastConsecutive(334)
139+
140+
// Add a packet beyond the current missing range to trigger buffer overflow behavior.
141+
// Ensure that when the number of missing packets exceeds the buffer size,
142+
// only the latest (rl.size - 1) entries are considered for NACKs.
143+
add(466)
144+
assertGet(466)
145+
146+
missing := all(335, 465)
147+
if len(missing) > int(rl.size) {
148+
assertLastConsecutive(missing[len(missing)-int(rl.size)])
149+
assertMissing(0, missing[len(missing)-(int(rl.size-1)):])
150+
} else {
151+
assertMissing(0, all(335, 465))
152+
}
134153
})
135154
}
136155
}

0 commit comments

Comments
 (0)