track_remote.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //go:build !js
  2. // +build !js
  3. package webrtc
  4. import (
  5. "sync"
  6. "time"
  7. "github.com/pion/interceptor"
  8. "github.com/pion/rtp"
  9. )
  10. // TrackRemote represents a single inbound source of media
  11. type TrackRemote struct {
  12. mu sync.RWMutex
  13. id string
  14. streamID string
  15. payloadType PayloadType
  16. kind RTPCodecType
  17. ssrc SSRC
  18. codec RTPCodecParameters
  19. params RTPParameters
  20. rid string
  21. receiver *RTPReceiver
  22. peeked []byte
  23. peekedAttributes interceptor.Attributes
  24. }
  25. func newTrackRemote(kind RTPCodecType, ssrc SSRC, rid string, receiver *RTPReceiver) *TrackRemote {
  26. return &TrackRemote{
  27. kind: kind,
  28. ssrc: ssrc,
  29. rid: rid,
  30. receiver: receiver,
  31. }
  32. }
  33. // ID is the unique identifier for this Track. This should be unique for the
  34. // stream, but doesn't have to globally unique. A common example would be 'audio' or 'video'
  35. // and StreamID would be 'desktop' or 'webcam'
  36. func (t *TrackRemote) ID() string {
  37. t.mu.RLock()
  38. defer t.mu.RUnlock()
  39. return t.id
  40. }
  41. // RID gets the RTP Stream ID of this Track
  42. // With Simulcast you will have multiple tracks with the same ID, but different RID values.
  43. // In many cases a TrackRemote will not have an RID, so it is important to assert it is non-zero
  44. func (t *TrackRemote) RID() string {
  45. t.mu.RLock()
  46. defer t.mu.RUnlock()
  47. return t.rid
  48. }
  49. // PayloadType gets the PayloadType of the track
  50. func (t *TrackRemote) PayloadType() PayloadType {
  51. t.mu.RLock()
  52. defer t.mu.RUnlock()
  53. return t.payloadType
  54. }
  55. // Kind gets the Kind of the track
  56. func (t *TrackRemote) Kind() RTPCodecType {
  57. t.mu.RLock()
  58. defer t.mu.RUnlock()
  59. return t.kind
  60. }
  61. // StreamID is the group this track belongs too. This must be unique
  62. func (t *TrackRemote) StreamID() string {
  63. t.mu.RLock()
  64. defer t.mu.RUnlock()
  65. return t.streamID
  66. }
  67. // SSRC gets the SSRC of the track
  68. func (t *TrackRemote) SSRC() SSRC {
  69. t.mu.RLock()
  70. defer t.mu.RUnlock()
  71. return t.ssrc
  72. }
  73. // Msid gets the Msid of the track
  74. func (t *TrackRemote) Msid() string {
  75. return t.StreamID() + " " + t.ID()
  76. }
  77. // Codec gets the Codec of the track
  78. func (t *TrackRemote) Codec() RTPCodecParameters {
  79. t.mu.RLock()
  80. defer t.mu.RUnlock()
  81. return t.codec
  82. }
  83. // Read reads data from the track.
  84. func (t *TrackRemote) Read(b []byte) (n int, attributes interceptor.Attributes, err error) {
  85. t.mu.RLock()
  86. r := t.receiver
  87. peeked := t.peeked != nil
  88. t.mu.RUnlock()
  89. if peeked {
  90. t.mu.Lock()
  91. data := t.peeked
  92. attributes = t.peekedAttributes
  93. t.peeked = nil
  94. t.peekedAttributes = nil
  95. t.mu.Unlock()
  96. // someone else may have stolen our packet when we
  97. // released the lock. Deal with it.
  98. if data != nil {
  99. n = copy(b, data)
  100. err = t.checkAndUpdateTrack(b)
  101. return
  102. }
  103. }
  104. n, attributes, err = r.readRTP(b, t)
  105. if err != nil {
  106. return
  107. }
  108. err = t.checkAndUpdateTrack(b)
  109. return
  110. }
  111. // checkAndUpdateTrack checks payloadType for every incoming packet
  112. // once a different payloadType is detected the track will be updated
  113. func (t *TrackRemote) checkAndUpdateTrack(b []byte) error {
  114. if len(b) < 2 {
  115. return errRTPTooShort
  116. }
  117. if payloadType := PayloadType(b[1] & rtpPayloadTypeBitmask); payloadType != t.PayloadType() {
  118. t.mu.Lock()
  119. defer t.mu.Unlock()
  120. params, err := t.receiver.api.mediaEngine.getRTPParametersByPayloadType(payloadType)
  121. if err != nil {
  122. return err
  123. }
  124. t.kind = t.receiver.kind
  125. t.payloadType = payloadType
  126. t.codec = params.Codecs[0]
  127. t.params = params
  128. }
  129. return nil
  130. }
  131. // ReadRTP is a convenience method that wraps Read and unmarshals for you.
  132. func (t *TrackRemote) ReadRTP() (*rtp.Packet, interceptor.Attributes, error) {
  133. b := make([]byte, t.receiver.api.settingEngine.getReceiveMTU())
  134. i, attributes, err := t.Read(b)
  135. if err != nil {
  136. return nil, nil, err
  137. }
  138. r := &rtp.Packet{}
  139. if err := r.Unmarshal(b[:i]); err != nil {
  140. return nil, nil, err
  141. }
  142. return r, attributes, nil
  143. }
  144. // peek is like Read, but it doesn't discard the packet read
  145. func (t *TrackRemote) peek(b []byte) (n int, a interceptor.Attributes, err error) {
  146. n, a, err = t.Read(b)
  147. if err != nil {
  148. return
  149. }
  150. t.mu.Lock()
  151. // this might overwrite data if somebody peeked between the Read
  152. // and us getting the lock. Oh well, we'll just drop a packet in
  153. // that case.
  154. data := make([]byte, n)
  155. n = copy(data, b[:n])
  156. t.peeked = data
  157. t.peekedAttributes = a
  158. t.mu.Unlock()
  159. return
  160. }
  161. // SetReadDeadline sets the max amount of time the RTP stream will block before returning. 0 is forever.
  162. func (t *TrackRemote) SetReadDeadline(deadline time.Time) error {
  163. return t.receiver.setRTPReadDeadline(deadline, t)
  164. }