8
8
"math"
9
9
"time"
10
10
11
+ "github.com/pion/interceptor/pkg/jitterbuffer"
11
12
"github.com/pion/rtp"
12
13
"github.com/pion/webrtc/v4/pkg/media"
13
14
)
@@ -16,7 +17,7 @@ import (
16
17
type SampleBuilder struct {
17
18
maxLate uint16 // how many packets to wait until we get a valid Sample
18
19
maxLateTimestamp uint32 // max timestamp between old and new timestamps before dropping packets
19
- buffer [ math . MaxUint16 + 1 ] * rtp. Packet
20
+ buffer * jitterbuffer. JitterBuffer
20
21
preparedSamples [math .MaxUint16 + 1 ]* media.Sample
21
22
22
23
// Interface that allows us to take RTP packets to samples
@@ -60,7 +61,7 @@ type SampleBuilder struct {
60
61
// The depacketizer extracts media samples from RTP packets.
61
62
// Several depacketizers are available in package github.com/pion/rtp/codecs.
62
63
func New (maxLate uint16 , depacketizer rtp.Depacketizer , sampleRate uint32 , opts ... Option ) * SampleBuilder {
63
- s := & SampleBuilder {maxLate : maxLate , depacketizer : depacketizer , sampleRate : sampleRate }
64
+ s := & SampleBuilder {maxLate : maxLate , depacketizer : depacketizer , sampleRate : sampleRate , buffer : jitterbuffer . New ( jitterbuffer . WithMinimumPacketCount ( 1 )) }
64
65
for _ , o := range opts {
65
66
o (s )
66
67
}
@@ -77,7 +78,7 @@ func (s *SampleBuilder) tooOld(location sampleSequenceLocation) bool {
77
78
var foundTail * rtp.Packet
78
79
79
80
for i := location .head ; i != location .tail ; i ++ {
80
- if packet := s .buffer [ i ] ; packet != nil {
81
+ if packet , _ := s .buffer . PeekAtSequence ( i ) ; packet != nil {
81
82
foundHead = packet
82
83
83
84
break
@@ -89,7 +90,7 @@ func (s *SampleBuilder) tooOld(location sampleSequenceLocation) bool {
89
90
}
90
91
91
92
for i := location .tail - 1 ; i != location .head ; i -- {
92
- if packet := s .buffer [ i ] ; packet != nil {
93
+ if packet , _ := s .buffer . PeekAtSequence ( i ) ; packet != nil {
93
94
foundTail = packet
94
95
95
96
break
@@ -108,7 +109,7 @@ func (s *SampleBuilder) fetchTimestamp(location sampleSequenceLocation) (timesta
108
109
if location .empty () {
109
110
return 0 , false
110
111
}
111
- packet := s .buffer [ location .head ]
112
+ packet , _ := s .buffer . PeekAtSequence ( location .head )
112
113
if packet == nil {
113
114
return 0 , false
114
115
}
@@ -118,7 +119,7 @@ func (s *SampleBuilder) fetchTimestamp(location sampleSequenceLocation) (timesta
118
119
119
120
func (s * SampleBuilder ) releasePacket (i uint16 ) {
120
121
var p * rtp.Packet
121
- p , s . buffer [ i ] = s .buffer [ i ], nil
122
+ p , _ = s .buffer . PopAtSequence ( i )
122
123
if p != nil && s .packetReleaseHandler != nil {
123
124
s .packetReleaseHandler (p )
124
125
}
@@ -183,7 +184,7 @@ func (s *SampleBuilder) purgeBuffers(flush bool) {
183
184
// Push does not copy the input. If you wish to reuse
184
185
// this memory make sure to copy before calling Push.
185
186
func (s * SampleBuilder ) Push (packet * rtp.Packet ) {
186
- s .buffer [ packet . SequenceNumber ] = packet
187
+ s .buffer . Push ( packet )
187
188
188
189
switch s .filled .compare (packet .SequenceNumber ) {
189
190
case slCompareVoid :
@@ -226,15 +227,19 @@ func (s *SampleBuilder) buildSample(purgingBuffers bool) *media.Sample {
226
227
227
228
var consume sampleSequenceLocation
228
229
229
- for i := s .active .head ; s .buffer [i ] != nil && s .active .compare (i ) != slCompareAfter ; i ++ {
230
- if s .depacketizer .IsPartitionTail (s .buffer [i ].Marker , s .buffer [i ].Payload ) {
230
+ for i := s .active .head ; s .active .compare (i ) != slCompareAfter ; i ++ {
231
+ pkt , err := s .buffer .PeekAtSequence (i )
232
+ if pkt == nil || err != nil {
233
+ break
234
+ }
235
+ if s .depacketizer .IsPartitionTail (pkt .Marker , pkt .Payload ) {
231
236
consume .head = s .active .head
232
237
consume .tail = i + 1
233
238
234
239
break
235
240
}
236
241
headTimestamp , hasData := s .fetchTimestamp (s .active )
237
- if hasData && s . buffer [ i ] .Timestamp != headTimestamp {
242
+ if hasData && pkt .Timestamp != headTimestamp {
238
243
consume .head = s .active .head
239
244
consume .tail = i
240
245
@@ -245,8 +250,8 @@ func (s *SampleBuilder) buildSample(purgingBuffers bool) *media.Sample {
245
250
if consume .empty () {
246
251
return nil
247
252
}
248
-
249
- if ! purgingBuffers && s . buffer [ consume . tail ] == nil {
253
+ pkt , _ := s . buffer . PeekAtSequence ( consume . tail )
254
+ if ! purgingBuffers && pkt == nil {
250
255
// wait for the next packet after this set of packets to arrive
251
256
// to ensure at least one post sample timestamp is known
252
257
// (unless we have to release right now)
@@ -258,9 +263,9 @@ func (s *SampleBuilder) buildSample(purgingBuffers bool) *media.Sample {
258
263
259
264
// scan for any packet after the current and use that time stamp as the diff point
260
265
for i := consume .tail ; i < s .active .tail ; i ++ {
261
- if s .buffer [ i ] != nil {
262
- afterTimestamp = s . buffer [ i ]. Timestamp
263
-
266
+ pkt , _ := s .buffer . PeekAtSequence ( i )
267
+ if pkt != nil {
268
+ afterTimestamp = pkt . Timestamp
264
269
break
265
270
}
266
271
}
@@ -270,10 +275,12 @@ func (s *SampleBuilder) buildSample(purgingBuffers bool) *media.Sample {
270
275
271
276
// prior to decoding all the packets, check if this packet
272
277
// would end being disposed anyway
273
- if ! s .depacketizer .IsPartitionHead (s .buffer [consume .head ].Payload ) {
278
+ pkt , err := s .buffer .PeekAtSequence (consume .head )
279
+ if pkt != nil && err == nil && ! s .depacketizer .IsPartitionHead (pkt .Payload ) {
274
280
isPadding := false
275
281
for i := consume .head ; i != consume .tail ; i ++ {
276
- if s .lastSampleTimestamp != nil && * s .lastSampleTimestamp == s .buffer [i ].Timestamp && len (s .buffer [i ].Payload ) == 0 {
282
+ pkt , _ := s .buffer .PeekAtSequence (i )
283
+ if s .lastSampleTimestamp != nil && * s .lastSampleTimestamp == pkt .Timestamp && len (pkt .Payload ) == 0 {
277
284
isPadding = true
278
285
}
279
286
}
@@ -292,15 +299,23 @@ func (s *SampleBuilder) buildSample(purgingBuffers bool) *media.Sample {
292
299
var metadata interface {}
293
300
var rtpHeaders []* rtp.Header
294
301
for i := consume .head ; i != consume .tail ; i ++ {
295
- payload , err := s .depacketizer .Unmarshal (s .buffer [i ].Payload )
302
+ pkt , _ := s .buffer .PeekAtSequence (i )
303
+ if pkt == nil {
304
+ return nil
305
+ }
306
+ p , err := s .depacketizer .Unmarshal (pkt .Payload )
296
307
if err != nil {
297
308
return nil
298
309
}
299
310
if i == consume .head && s .packetHeadHandler != nil {
300
311
metadata = s .packetHeadHandler (s .depacketizer )
301
312
}
302
313
if s .returnRTPHeaders {
303
- h := s .buffer [i ].Header .Clone ()
314
+ pkt , err := s .buffer .PeekAtSequence (i )
315
+ if err != nil {
316
+ return nil
317
+ }
318
+ h := pkt .Header .Clone ()
304
319
rtpHeaders = append (rtpHeaders , & h )
305
320
}
306
321
0 commit comments