@@ -15,7 +15,6 @@ import (
15
15
16
16
"github.com/pion/interceptor"
17
17
"github.com/pion/rtcp"
18
- "github.com/pion/rtp"
19
18
"github.com/pion/srtp/v2"
20
19
"github.com/pion/webrtc/v3/internal/util"
21
20
)
@@ -42,7 +41,7 @@ type trackStreams struct {
42
41
}
43
42
44
43
type rtxPacketWithAttributes struct {
45
- rtxPacket rtp. Packet
44
+ pkt [] byte
46
45
attributes interceptor.Attributes
47
46
}
48
47
@@ -419,31 +418,40 @@ func (r *RTPReceiver) receiveForRtx(ssrc SSRC, rsid string, streamInfo *intercep
419
418
return
420
419
}
421
420
422
- pkt := & rtp.Packet {}
423
- if err := pkt .Unmarshal (b [:i ]); err != nil {
424
- return
421
+ // RTX packets have a different payload format. Move the OSN in the payload to the RTP header and rewrite the
422
+ // payload type and SSRC, so that we can return RTX packets to the caller 'transparently' i.e. in the same format
423
+ // as non-RTX RTP packets
424
+ hasExtension := b [0 ]& 0b10000 > 0
425
+ hasPadding := b [0 ]& 0b100000 > 0
426
+ csrcCount := b [0 ] & 0b1111
427
+ headerLength := uint16 (12 + (4 * csrcCount ))
428
+ paddingLength := 0
429
+ if hasExtension {
430
+ headerLength += 4 * (1 + binary .BigEndian .Uint16 (b [headerLength + 2 :headerLength + 4 ]))
431
+ }
432
+ if hasPadding {
433
+ paddingLength = int (b [i - 1 ])
425
434
}
426
435
427
- if len ( pkt . Payload ) < 2 {
436
+ if i - int ( headerLength ) - paddingLength < 2 {
428
437
// BWE probe packet, ignore
429
438
continue
430
439
}
431
440
432
- // RTX packets have a different payload format. Move the OSN in the payload to the RTP header and rewrite the
433
- // payload type and SSRC, so that we can return RTX packets to the caller 'transparently' i.e. in the same format
434
- // as non-RTX RTP packets
435
- attributes .Set (attributeRtxPayloadType , pkt .Header .PayloadType )
436
- attributes .Set (attributeRtxSsrc , pkt .Header .SSRC )
437
- attributes .Set (attributeRtxSequenceNumber , pkt .Header .SequenceNumber )
438
- pkt .Header .PayloadType = uint8 (track .track .PayloadType ())
439
- pkt .Header .SSRC = uint32 (track .track .SSRC ())
440
- pkt .Header .SequenceNumber = binary .BigEndian .Uint16 (pkt .Payload [:2 ])
441
- pkt .Payload = pkt .Payload [2 :]
441
+ attributes .Set (attributeRtxPayloadType , b [1 ]& 0x7F )
442
+ attributes .Set (attributeRtxSequenceNumber , binary .BigEndian .Uint16 (b [2 :4 ]))
443
+ attributes .Set (attributeRtxSsrc , binary .BigEndian .Uint32 (b [8 :12 ]))
444
+
445
+ b [1 ] = (b [1 ] & 0x80 ) | uint8 (track .track .PayloadType ())
446
+ b [2 ] = b [headerLength ]
447
+ b [3 ] = b [headerLength + 1 ]
448
+ binary .BigEndian .PutUint32 (b [8 :12 ], uint32 (track .track .SSRC ()))
449
+ copy (b [headerLength :i - 2 ], b [headerLength + 2 :i ])
442
450
443
451
select {
444
452
case <- r .closed :
445
453
return
446
- case track .repairStreamChannel <- rtxPacketWithAttributes {rtxPacket : * pkt , attributes : attributes }:
454
+ case track .repairStreamChannel <- rtxPacketWithAttributes {pkt : b [: i - 2 ] , attributes : attributes }:
447
455
}
448
456
}
449
457
}()
@@ -484,23 +492,23 @@ func (r *RTPReceiver) setRTPReadDeadline(deadline time.Time, reader *TrackRemote
484
492
}
485
493
486
494
// readRTX returns an RTX packet if one is available on the RTX track, otherwise returns nil
487
- func (r * RTPReceiver ) readRTX (reader * TrackRemote ) ( * rtp. Packet , interceptor. Attributes ) {
495
+ func (r * RTPReceiver ) readRTX (reader * TrackRemote ) * rtxPacketWithAttributes {
488
496
if ! reader .HasRTX () {
489
- return nil , interceptor. Attributes {}
497
+ return nil
490
498
}
491
499
492
500
select {
493
501
case <- r .received :
494
502
default :
495
- return nil , interceptor. Attributes {}
503
+ return nil
496
504
}
497
505
498
506
if t := r .streamsForTrack (reader ); t != nil {
499
507
select {
500
508
case rtxPacketReceived := <- t .repairStreamChannel :
501
- return & rtxPacketReceived . rtxPacket , rtxPacketReceived . attributes
509
+ return & rtxPacketReceived
502
510
default :
503
511
}
504
512
}
505
- return nil , interceptor. Attributes {}
513
+ return nil
506
514
}
0 commit comments