package webrtc
import (
"sync"
"time"
"github.com/pion/interceptor"
"github.com/pion/rtp"
)
type TrackRemote struct {
mu sync .RWMutex
id string
streamID string
payloadType PayloadType
kind RTPCodecType
ssrc SSRC
rtxSsrc SSRC
codec RTPCodecParameters
params RTPParameters
rid string
receiver *RTPReceiver
peeked []byte
peekedAttributes interceptor .Attributes
}
func newTrackRemote(kind RTPCodecType , ssrc , rtxSsrc SSRC , rid string , receiver *RTPReceiver ) *TrackRemote {
return &TrackRemote {
kind : kind ,
ssrc : ssrc ,
rtxSsrc : rtxSsrc ,
rid : rid ,
receiver : receiver ,
}
}
func (t *TrackRemote ) ID () string {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .id
}
func (t *TrackRemote ) RID () string {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .rid
}
func (t *TrackRemote ) PayloadType () PayloadType {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .payloadType
}
func (t *TrackRemote ) Kind () RTPCodecType {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .kind
}
func (t *TrackRemote ) StreamID () string {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .streamID
}
func (t *TrackRemote ) SSRC () SSRC {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .ssrc
}
func (t *TrackRemote ) Msid () string {
return t .StreamID () + " " + t .ID ()
}
func (t *TrackRemote ) Codec () RTPCodecParameters {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .codec
}
func (t *TrackRemote ) Read (b []byte ) (n int , attributes interceptor .Attributes , err error ) {
t .mu .RLock ()
receiver := t .receiver
peeked := t .peeked != nil
t .mu .RUnlock ()
if peeked {
t .mu .Lock ()
data := t .peeked
attributes = t .peekedAttributes
t .peeked = nil
t .peekedAttributes = nil
t .mu .Unlock ()
if data != nil {
n = copy (b , data )
err = t .checkAndUpdateTrack (b )
return n , attributes , err
}
}
if rtxPacketReceived := receiver .readRTX (t ); rtxPacketReceived != nil {
n = copy (b , rtxPacketReceived .pkt )
attributes = rtxPacketReceived .attributes
rtxPacketReceived .release ()
err = nil
} else {
n , attributes , err = receiver .readRTP (b , t )
if err != nil {
return n , attributes , err
}
err = t .checkAndUpdateTrack (b )
}
return n , attributes , err
}
func (t *TrackRemote ) checkAndUpdateTrack (b []byte ) error {
if len (b ) < 2 {
return errRTPTooShort
}
payloadType := PayloadType (b [1 ] & rtpPayloadTypeBitmask )
if payloadType != t .PayloadType () || len (t .params .Codecs ) == 0 {
t .mu .Lock ()
defer t .mu .Unlock ()
params , err := t .receiver .api .mediaEngine .getRTPParametersByPayloadType (payloadType )
if err != nil {
return err
}
t .kind = t .receiver .kind
t .payloadType = payloadType
t .codec = params .Codecs [0 ]
t .params = params
}
return nil
}
func (t *TrackRemote ) ReadRTP () (*rtp .Packet , interceptor .Attributes , error ) {
b := make ([]byte , t .receiver .api .settingEngine .getReceiveMTU ())
i , attributes , err := t .Read (b )
if err != nil {
return nil , nil , err
}
r := &rtp .Packet {}
if err := r .Unmarshal (b [:i ]); err != nil {
return nil , nil , err
}
return r , attributes , nil
}
func (t *TrackRemote ) peek (b []byte ) (n int , a interceptor .Attributes , err error ) {
n , a , err = t .Read (b )
if err != nil {
return
}
t .mu .Lock ()
data := make ([]byte , n )
n = copy (data , b [:n ])
t .peeked = data
t .peekedAttributes = a
t .mu .Unlock ()
return
}
func (t *TrackRemote ) SetReadDeadline (deadline time .Time ) error {
return t .receiver .setRTPReadDeadline (deadline , t )
}
func (t *TrackRemote ) RtxSSRC () SSRC {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .rtxSsrc
}
func (t *TrackRemote ) HasRTX () bool {
t .mu .RLock ()
defer t .mu .RUnlock ()
return t .rtxSsrc != 0
}
func (t *TrackRemote ) setRtxSSRC (ssrc SSRC ) {
t .mu .Lock ()
defer t .mu .Unlock ()
t .rtxSsrc = ssrc
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .