Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Side by Side Diff: talk/app/webrtc/rtpsender.cc

Issue 1413983004: Reland of Adding the ability to create an RtpSender without a track. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing merge issue. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « talk/app/webrtc/rtpsender.h ('k') | talk/app/webrtc/rtpsenderinterface.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 11 matching lines...) Expand all
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 #include "talk/app/webrtc/rtpsender.h" 28 #include "talk/app/webrtc/rtpsender.h"
29 29
30 #include "talk/app/webrtc/localaudiosource.h" 30 #include "talk/app/webrtc/localaudiosource.h"
31 #include "talk/app/webrtc/videosourceinterface.h" 31 #include "talk/app/webrtc/videosourceinterface.h"
32 #include "webrtc/base/helpers.h"
32 33
33 namespace webrtc { 34 namespace webrtc {
34 35
35 LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {} 36 LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
36 37
37 LocalAudioSinkAdapter::~LocalAudioSinkAdapter() { 38 LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
38 rtc::CritScope lock(&lock_); 39 rtc::CritScope lock(&lock_);
39 if (sink_) 40 if (sink_)
40 sink_->OnClose(); 41 sink_->OnClose();
41 } 42 }
(...skipping 10 matching lines...) Expand all
52 } 53 }
53 } 54 }
54 55
55 void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) { 56 void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) {
56 rtc::CritScope lock(&lock_); 57 rtc::CritScope lock(&lock_);
57 ASSERT(!sink || !sink_); 58 ASSERT(!sink || !sink_);
58 sink_ = sink; 59 sink_ = sink;
59 } 60 }
60 61
61 AudioRtpSender::AudioRtpSender(AudioTrackInterface* track, 62 AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
62 uint32_t ssrc, 63 const std::string& stream_id,
63 AudioProviderInterface* provider) 64 AudioProviderInterface* provider,
65 StatsCollector* stats)
64 : id_(track->id()), 66 : id_(track->id()),
67 stream_id_(stream_id),
68 provider_(provider),
69 stats_(stats),
65 track_(track), 70 track_(track),
66 ssrc_(ssrc),
67 provider_(provider),
68 cached_track_enabled_(track->enabled()), 71 cached_track_enabled_(track->enabled()),
69 sink_adapter_(new LocalAudioSinkAdapter()) { 72 sink_adapter_(new LocalAudioSinkAdapter()) {
73 RTC_DCHECK(provider != nullptr);
70 track_->RegisterObserver(this); 74 track_->RegisterObserver(this);
71 track_->AddSink(sink_adapter_.get()); 75 track_->AddSink(sink_adapter_.get());
72 Reconfigure();
73 } 76 }
74 77
78 AudioRtpSender::AudioRtpSender(AudioProviderInterface* provider,
79 StatsCollector* stats)
80 : id_(rtc::CreateRandomUuid()),
81 stream_id_(rtc::CreateRandomUuid()),
82 provider_(provider),
83 stats_(stats),
84 sink_adapter_(new LocalAudioSinkAdapter()) {}
85
75 AudioRtpSender::~AudioRtpSender() { 86 AudioRtpSender::~AudioRtpSender() {
76 track_->RemoveSink(sink_adapter_.get());
77 track_->UnregisterObserver(this);
78 Stop(); 87 Stop();
79 } 88 }
80 89
81 void AudioRtpSender::OnChanged() { 90 void AudioRtpSender::OnChanged() {
91 RTC_DCHECK(!stopped_);
82 if (cached_track_enabled_ != track_->enabled()) { 92 if (cached_track_enabled_ != track_->enabled()) {
83 cached_track_enabled_ = track_->enabled(); 93 cached_track_enabled_ = track_->enabled();
84 Reconfigure(); 94 if (can_send_track()) {
95 SetAudioSend();
96 }
85 } 97 }
86 } 98 }
87 99
88 bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) { 100 bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
89 if (track->kind() != "audio") { 101 if (stopped_) {
102 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
103 return false;
104 }
105 if (track && track->kind() != MediaStreamTrackInterface::kAudioKind) {
90 LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind() 106 LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind()
91 << " track."; 107 << " track.";
92 return false; 108 return false;
93 } 109 }
94 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track); 110 AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
95 111
96 // Detach from old track. 112 // Detach from old track.
97 track_->RemoveSink(sink_adapter_.get()); 113 if (track_) {
98 track_->UnregisterObserver(this); 114 track_->RemoveSink(sink_adapter_.get());
115 track_->UnregisterObserver(this);
116 }
117
118 if (can_send_track() && stats_) {
119 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
120 }
99 121
100 // Attach to new track. 122 // Attach to new track.
123 bool prev_can_send_track = can_send_track();
101 track_ = audio_track; 124 track_ = audio_track;
102 cached_track_enabled_ = track_->enabled(); 125 if (track_) {
103 track_->RegisterObserver(this); 126 cached_track_enabled_ = track_->enabled();
104 track_->AddSink(sink_adapter_.get()); 127 track_->RegisterObserver(this);
105 Reconfigure(); 128 track_->AddSink(sink_adapter_.get());
129 }
130
131 // Update audio provider.
132 if (can_send_track()) {
133 SetAudioSend();
134 if (stats_) {
135 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
136 }
137 } else if (prev_can_send_track) {
138 cricket::AudioOptions options;
139 provider_->SetAudioSend(ssrc_, false, options, nullptr);
140 }
106 return true; 141 return true;
107 } 142 }
108 143
144 void AudioRtpSender::SetSsrc(uint32_t ssrc) {
145 if (stopped_ || ssrc == ssrc_) {
146 return;
147 }
148 // If we are already sending with a particular SSRC, stop sending.
149 if (can_send_track()) {
150 cricket::AudioOptions options;
151 provider_->SetAudioSend(ssrc_, false, options, nullptr);
152 if (stats_) {
153 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
154 }
155 }
156 ssrc_ = ssrc;
157 if (can_send_track()) {
158 SetAudioSend();
159 if (stats_) {
160 stats_->AddLocalAudioTrack(track_.get(), ssrc_);
161 }
162 }
163 }
164
109 void AudioRtpSender::Stop() { 165 void AudioRtpSender::Stop() {
110 // TODO(deadbeef): Need to do more here to fully stop sending packets. 166 // TODO(deadbeef): Need to do more here to fully stop sending packets.
111 if (!provider_) { 167 if (stopped_) {
112 return; 168 return;
113 } 169 }
114 cricket::AudioOptions options; 170 if (track_) {
115 provider_->SetAudioSend(ssrc_, false, options, nullptr); 171 track_->RemoveSink(sink_adapter_.get());
116 provider_ = nullptr; 172 track_->UnregisterObserver(this);
173 }
174 if (can_send_track()) {
175 cricket::AudioOptions options;
176 provider_->SetAudioSend(ssrc_, false, options, nullptr);
177 if (stats_) {
178 stats_->RemoveLocalAudioTrack(track_.get(), ssrc_);
179 }
180 }
181 stopped_ = true;
117 } 182 }
118 183
119 void AudioRtpSender::Reconfigure() { 184 void AudioRtpSender::SetAudioSend() {
120 if (!provider_) { 185 RTC_DCHECK(!stopped_ && can_send_track());
121 return;
122 }
123 cricket::AudioOptions options; 186 cricket::AudioOptions options;
124 if (track_->enabled() && track_->GetSource()) { 187 if (track_->enabled() && track_->GetSource()) {
125 // TODO(xians): Remove this static_cast since we should be able to connect 188 // TODO(xians): Remove this static_cast since we should be able to connect
126 // a remote audio track to peer connection. 189 // a remote audio track to a peer connection.
127 options = static_cast<LocalAudioSource*>(track_->GetSource())->options(); 190 options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
128 } 191 }
129 192
130 // Use the renderer if the audio track has one, otherwise use the sink 193 // Use the renderer if the audio track has one, otherwise use the sink
131 // adapter owned by this class. 194 // adapter owned by this class.
132 cricket::AudioRenderer* renderer = 195 cricket::AudioRenderer* renderer =
133 track_->GetRenderer() ? track_->GetRenderer() : sink_adapter_.get(); 196 track_->GetRenderer() ? track_->GetRenderer() : sink_adapter_.get();
134 ASSERT(renderer != nullptr); 197 ASSERT(renderer != nullptr);
135 provider_->SetAudioSend(ssrc_, track_->enabled(), options, renderer); 198 provider_->SetAudioSend(ssrc_, track_->enabled(), options, renderer);
136 } 199 }
137 200
138 VideoRtpSender::VideoRtpSender(VideoTrackInterface* track, 201 VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
139 uint32_t ssrc, 202 const std::string& stream_id,
140 VideoProviderInterface* provider) 203 VideoProviderInterface* provider)
141 : id_(track->id()), 204 : id_(track->id()),
205 stream_id_(stream_id),
206 provider_(provider),
142 track_(track), 207 track_(track),
143 ssrc_(ssrc),
144 provider_(provider),
145 cached_track_enabled_(track->enabled()) { 208 cached_track_enabled_(track->enabled()) {
209 RTC_DCHECK(provider != nullptr);
146 track_->RegisterObserver(this); 210 track_->RegisterObserver(this);
147 VideoSourceInterface* source = track_->GetSource();
148 if (source) {
149 provider_->SetCaptureDevice(ssrc_, source->GetVideoCapturer());
150 }
151 Reconfigure();
152 } 211 }
153 212
213 VideoRtpSender::VideoRtpSender(VideoProviderInterface* provider)
214 : id_(rtc::CreateRandomUuid()),
215 stream_id_(rtc::CreateRandomUuid()),
216 provider_(provider) {}
217
154 VideoRtpSender::~VideoRtpSender() { 218 VideoRtpSender::~VideoRtpSender() {
155 track_->UnregisterObserver(this);
156 Stop(); 219 Stop();
157 } 220 }
158 221
159 void VideoRtpSender::OnChanged() { 222 void VideoRtpSender::OnChanged() {
223 RTC_DCHECK(!stopped_);
160 if (cached_track_enabled_ != track_->enabled()) { 224 if (cached_track_enabled_ != track_->enabled()) {
161 cached_track_enabled_ = track_->enabled(); 225 cached_track_enabled_ = track_->enabled();
162 Reconfigure(); 226 if (can_send_track()) {
227 SetVideoSend();
228 }
163 } 229 }
164 } 230 }
165 231
166 bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) { 232 bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
167 if (track->kind() != "video") { 233 if (stopped_) {
234 LOG(LS_ERROR) << "SetTrack can't be called on a stopped RtpSender.";
235 return false;
236 }
237 if (track && track->kind() != MediaStreamTrackInterface::kVideoKind) {
168 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind() 238 LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
169 << " track."; 239 << " track.";
170 return false; 240 return false;
171 } 241 }
172 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track); 242 VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
173 243
174 // Detach from old track. 244 // Detach from old track.
175 track_->UnregisterObserver(this); 245 if (track_) {
246 track_->UnregisterObserver(this);
247 }
176 248
177 // Attach to new track. 249 // Attach to new track.
250 bool prev_can_send_track = can_send_track();
178 track_ = video_track; 251 track_ = video_track;
179 cached_track_enabled_ = track_->enabled(); 252 if (track_) {
180 track_->RegisterObserver(this); 253 cached_track_enabled_ = track_->enabled();
181 Reconfigure(); 254 track_->RegisterObserver(this);
255 }
256
257 // Update video provider.
258 if (can_send_track()) {
259 VideoSourceInterface* source = track_->GetSource();
260 // TODO(deadbeef): If SetTrack is called with a disabled track, and the
261 // previous track was enabled, this could cause a frame from the new track
262 // to slip out. Really, what we need is for SetCaptureDevice and
263 // SetVideoSend
264 // to be combined into one atomic operation, all the way down to
265 // WebRtcVideoSendStream.
266 provider_->SetCaptureDevice(ssrc_,
267 source ? source->GetVideoCapturer() : nullptr);
268 SetVideoSend();
269 } else if (prev_can_send_track) {
270 provider_->SetCaptureDevice(ssrc_, nullptr);
271 provider_->SetVideoSend(ssrc_, false, nullptr);
272 }
182 return true; 273 return true;
183 } 274 }
184 275
276 void VideoRtpSender::SetSsrc(uint32_t ssrc) {
277 if (stopped_ || ssrc == ssrc_) {
278 return;
279 }
280 // If we are already sending with a particular SSRC, stop sending.
281 if (can_send_track()) {
282 provider_->SetCaptureDevice(ssrc_, nullptr);
283 provider_->SetVideoSend(ssrc_, false, nullptr);
284 }
285 ssrc_ = ssrc;
286 if (can_send_track()) {
287 VideoSourceInterface* source = track_->GetSource();
288 provider_->SetCaptureDevice(ssrc_,
289 source ? source->GetVideoCapturer() : nullptr);
290 SetVideoSend();
291 }
292 }
293
185 void VideoRtpSender::Stop() { 294 void VideoRtpSender::Stop() {
186 // TODO(deadbeef): Need to do more here to fully stop sending packets. 295 // TODO(deadbeef): Need to do more here to fully stop sending packets.
187 if (!provider_) { 296 if (stopped_) {
188 return; 297 return;
189 } 298 }
190 provider_->SetCaptureDevice(ssrc_, nullptr); 299 if (track_) {
191 provider_->SetVideoSend(ssrc_, false, nullptr); 300 track_->UnregisterObserver(this);
192 provider_ = nullptr; 301 }
302 if (can_send_track()) {
303 provider_->SetCaptureDevice(ssrc_, nullptr);
304 provider_->SetVideoSend(ssrc_, false, nullptr);
305 }
306 stopped_ = true;
193 } 307 }
194 308
195 void VideoRtpSender::Reconfigure() { 309 void VideoRtpSender::SetVideoSend() {
196 if (!provider_) { 310 RTC_DCHECK(!stopped_ && can_send_track());
197 return;
198 }
199 const cricket::VideoOptions* options = nullptr; 311 const cricket::VideoOptions* options = nullptr;
200 VideoSourceInterface* source = track_->GetSource(); 312 VideoSourceInterface* source = track_->GetSource();
201 if (track_->enabled() && source) { 313 if (track_->enabled() && source) {
202 options = source->options(); 314 options = source->options();
203 } 315 }
204 provider_->SetVideoSend(ssrc_, track_->enabled(), options); 316 provider_->SetVideoSend(ssrc_, track_->enabled(), options);
205 } 317 }
206 318
207 } // namespace webrtc 319 } // namespace webrtc
OLDNEW
« no previous file with comments | « talk/app/webrtc/rtpsender.h ('k') | talk/app/webrtc/rtpsenderinterface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698