track_remote.go 5.5 KB

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