OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/ortc/rtpreceivershim.h" | |
12 | |
13 #include "webrtc/base/checks.h" | |
14 #include "webrtc/base/helpers.h" // For "CreateRandomX". | |
15 | |
16 namespace { | |
17 | |
18 static const int kDefaultVideoClockrate = 90000; | |
pthatcher1
2017/02/10 22:36:52
That's defined in mediaconstants.h as kVideoCodecC
| |
19 | |
20 void FillAudioReceiverParameters(webrtc::RtpParameters* parameters) { | |
21 for (webrtc::RtpCodecParameters& codec : parameters->codecs) { | |
22 if (!codec.num_channels) { | |
23 codec.num_channels = rtc::Optional<int>(1); | |
24 } | |
25 } | |
26 } | |
27 | |
28 void FillVideoReceiverParameters(webrtc::RtpParameters* parameters) { | |
29 for (webrtc::RtpCodecParameters& codec : parameters->codecs) { | |
30 if (!codec.clock_rate) { | |
31 codec.clock_rate = rtc::Optional<int>(kDefaultVideoClockrate); | |
32 } | |
33 } | |
34 } | |
35 | |
36 } // namespace | |
37 | |
38 namespace webrtc { | |
39 | |
40 BEGIN_OWNED_PROXY_MAP(OrtcRtpReceiver) | |
41 PROXY_SIGNALING_THREAD_DESTRUCTOR() | |
42 PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, GetTrack) | |
43 PROXY_METHOD1(RTCError, SetTransport, RtpTransportInterface*) | |
44 PROXY_CONSTMETHOD0(RtpTransportInterface*, GetTransport) | |
45 PROXY_METHOD1(RTCError, Receive, const RtpParameters&) | |
46 PROXY_CONSTMETHOD0(RtpParameters, GetParameters) | |
47 PROXY_CONSTMETHOD0(cricket::MediaType, GetKind) | |
48 END_PROXY_MAP() | |
49 | |
50 // static | |
51 RTCErrorOr<std::unique_ptr<OrtcRtpReceiverInterface>> | |
52 RtpReceiverShim::CreateProxied(cricket::MediaType kind, | |
53 RtpTransportShim* transport) { | |
54 RTC_DCHECK(transport); | |
55 RtpTransportControllerShim* rtp_transport_controller = | |
56 transport->rtp_transport_controller(); | |
57 // Call "attach" method to ensure more than one receiver of the same type | |
58 // isn't attached to the same transport. | |
59 RTCError err; | |
60 switch (kind) { | |
61 case cricket::MEDIA_TYPE_AUDIO: | |
62 err = rtp_transport_controller->AttachAudioReceiver(transport); | |
63 break; | |
64 case cricket::MEDIA_TYPE_VIDEO: | |
65 err = rtp_transport_controller->AttachVideoReceiver(transport); | |
66 break; | |
67 case cricket::MEDIA_TYPE_DATA: | |
68 RTC_NOTREACHED(); | |
pthatcher1
2017/02/10 22:36:52
Should this be an RTC_DCHECK()?
Taylor Brandstetter
2017/02/14 06:55:05
What would be in the RTC_DCHECK()?
| |
69 } | |
70 if (!err.ok()) { | |
71 return err; | |
72 } | |
73 | |
74 return OrtcRtpReceiverProxy::Create( | |
75 rtp_transport_controller->signaling_thread(), | |
76 rtp_transport_controller->worker_thread(), | |
77 new RtpReceiverShim(kind, transport, rtp_transport_controller)); | |
78 } | |
79 | |
80 RtpReceiverShim::~RtpReceiverShim() { | |
81 internal_receiver_ = nullptr; | |
82 // Need to detach from transport (was attached in Create method). | |
83 switch (kind_) { | |
84 case cricket::MEDIA_TYPE_AUDIO: | |
85 rtp_transport_controller_->DetachAudioReceiver(); | |
86 break; | |
87 case cricket::MEDIA_TYPE_VIDEO: | |
88 rtp_transport_controller_->DetachVideoReceiver(); | |
89 break; | |
90 case cricket::MEDIA_TYPE_DATA: | |
91 RTC_NOTREACHED(); | |
pthatcher1
2017/02/10 22:36:52
Should this be an RTC_DCHECK()?
Taylor Brandstetter
2017/02/14 06:55:05
What would be in the RTC_DCHECK()?
Taylor Brandstetter
2017/02/14 06:55:05
What would be in the RTC_DCHECK()?
| |
92 } | |
93 } | |
94 | |
95 rtc::scoped_refptr<MediaStreamTrackInterface> RtpReceiverShim::GetTrack() | |
96 const { | |
97 return internal_receiver_ ? internal_receiver_->track() : nullptr; | |
98 } | |
99 | |
100 RTCError RtpReceiverShim::SetTransport(RtpTransportInterface* transport) { | |
101 LOG(LS_ERROR) << "Changing the transport of an RtpReceiver is not yet " | |
102 << "supported."; | |
103 return RTCError(RTCErrorType::UNSUPPORTED_PARAMETER); | |
104 } | |
105 | |
106 RtpTransportInterface* RtpReceiverShim::GetTransport() const { | |
107 return transport_; | |
108 } | |
109 | |
110 RTCError RtpReceiverShim::Receive(const RtpParameters& parameters) { | |
111 RtpParameters filled_parameters = parameters; | |
112 RTCError err; | |
113 switch (kind_) { | |
114 case cricket::MEDIA_TYPE_AUDIO: | |
115 FillAudioReceiverParameters(&filled_parameters); | |
116 err = rtp_transport_controller_->ValidateAndApplyAudioReceiverParameters( | |
117 filled_parameters); | |
118 if (!err.ok()) { | |
119 return err; | |
120 } | |
121 break; | |
122 case cricket::MEDIA_TYPE_VIDEO: | |
123 FillVideoReceiverParameters(&filled_parameters); | |
124 err = rtp_transport_controller_->ValidateAndApplyVideoReceiverParameters( | |
125 filled_parameters); | |
126 if (!err.ok()) { | |
127 return err; | |
128 } | |
129 break; | |
130 case cricket::MEDIA_TYPE_DATA: | |
131 RTC_NOTREACHED(); | |
132 return webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR); | |
133 } | |
134 last_applied_parameters_ = filled_parameters; | |
135 | |
136 // Now that parameters were applied, can create (or recreate) the internal | |
137 // receiver. | |
138 // | |
139 // This is analogous to a PeerConnection creating a receiver after | |
140 // SetRemoteDescription is successful. | |
141 MaybeRecreateInternalReceiver(); | |
142 return RTCError(); | |
143 } | |
144 | |
145 RtpParameters RtpReceiverShim::GetParameters() const { | |
146 return last_applied_parameters_; | |
147 } | |
148 | |
149 cricket::MediaType RtpReceiverShim::GetKind() const { | |
150 return cricket::MediaTypeFromString(GetTrack()->kind()); | |
151 } | |
152 | |
153 RtpReceiverShim::RtpReceiverShim( | |
154 cricket::MediaType kind, | |
155 RtpTransportShim* transport, | |
156 RtpTransportControllerShim* rtp_transport_controller) | |
157 : kind_(kind), | |
158 transport_(transport), | |
159 rtp_transport_controller_(rtp_transport_controller) {} | |
160 | |
161 void RtpReceiverShim::MaybeRecreateInternalReceiver() { | |
162 if (last_applied_parameters_.encodings.empty()) { | |
163 internal_receiver_ = nullptr; | |
164 return; | |
165 } | |
166 // An SSRC of 0 is valid; this is used to identify "the default SSRC" (which | |
167 // is the first one seen by the underlying media engine). | |
168 uint32_t ssrc = 0; | |
169 if (last_applied_parameters_.encodings[0].ssrc) { | |
170 ssrc = *last_applied_parameters_.encodings[0].ssrc; | |
171 } | |
172 if (internal_receiver_ && ssrc == internal_receiver_->ssrc()) { | |
173 // SSRC not changing; nothing to do. | |
174 return; | |
175 } | |
176 internal_receiver_ = nullptr; | |
177 switch (kind_) { | |
178 case cricket::MEDIA_TYPE_AUDIO: | |
179 internal_receiver_ = | |
180 new AudioRtpReceiver(rtc::CreateRandomUuid(), ssrc, | |
181 rtp_transport_controller_->voice_channel()); | |
182 break; | |
183 case cricket::MEDIA_TYPE_VIDEO: | |
184 internal_receiver_ = new VideoRtpReceiver( | |
185 rtc::CreateRandomUuid(), rtp_transport_controller_->worker_thread(), | |
186 ssrc, rtp_transport_controller_->video_channel()); | |
187 break; | |
188 case cricket::MEDIA_TYPE_DATA: | |
189 RTC_NOTREACHED(); | |
190 } | |
191 } | |
192 | |
193 } // namespace webrtc | |
OLD | NEW |