1 /* 2 * libjingle 3 * Copyright 2012, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 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 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/app/webrtc/mediastreamhandler.h" 29 30 #include "talk/app/webrtc/localaudiosource.h" 31 #include "talk/app/webrtc/videosource.h" 32 #include "talk/app/webrtc/videosourceinterface.h" 33 34 namespace webrtc { 35 36 TrackHandler::TrackHandler(MediaStreamTrackInterface* track, uint32 ssrc) 37 : track_(track), 38 ssrc_(ssrc), 39 state_(track->state()), 40 enabled_(track->enabled()) { 41 track_->RegisterObserver(this); 42 } 43 44 TrackHandler::~TrackHandler() { 45 track_->UnregisterObserver(this); 46 } 47 48 void TrackHandler::OnChanged() { 49 if (state_ != track_->state()) { 50 state_ = track_->state(); 51 OnStateChanged(); 52 } 53 if (enabled_ != track_->enabled()) { 54 enabled_ = track_->enabled(); 55 OnEnabledChanged(); 56 } 57 } 58 59 LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(NULL) {} 60 61 LocalAudioSinkAdapter::~LocalAudioSinkAdapter() { 62 rtc::CritScope lock(&lock_); 63 if (sink_) 64 sink_->OnClose(); 65 } 66 67 void LocalAudioSinkAdapter::OnData(const void* audio_data, 68 int bits_per_sample, 69 int sample_rate, 70 int number_of_channels, 71 int number_of_frames) { 72 rtc::CritScope lock(&lock_); 73 if (sink_) { 74 sink_->OnData(audio_data, bits_per_sample, sample_rate, 75 number_of_channels, number_of_frames); 76 } 77 } 78 79 void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) { 80 rtc::CritScope lock(&lock_); 81 ASSERT(!sink || !sink_); 82 sink_ = sink; 83 } 84 85 LocalAudioTrackHandler::LocalAudioTrackHandler( 86 AudioTrackInterface* track, 87 uint32 ssrc, 88 AudioProviderInterface* provider) 89 : TrackHandler(track, ssrc), 90 audio_track_(track), 91 provider_(provider), 92 sink_adapter_(new LocalAudioSinkAdapter()) { 93 OnEnabledChanged(); 94 track->AddSink(sink_adapter_.get()); 95 } 96 97 LocalAudioTrackHandler::~LocalAudioTrackHandler() { 98 } 99 100 void LocalAudioTrackHandler::OnStateChanged() { 101 // TODO(perkj): What should happen when the state change? 102 } 103 104 void LocalAudioTrackHandler::Stop() { 105 audio_track_->RemoveSink(sink_adapter_.get()); 106 cricket::AudioOptions options; 107 provider_->SetAudioSend(ssrc(), false, options, NULL); 108 } 109 110 void LocalAudioTrackHandler::OnEnabledChanged() { 111 cricket::AudioOptions options; 112 if (audio_track_->enabled() && audio_track_->GetSource()) { 113 // TODO(xians): Remove this static_cast since we should be able to connect 114 // a remote audio track to peer connection. 115 options = static_cast<LocalAudioSource*>( 116 audio_track_->GetSource())->options(); 117 } 118 119 // Use the renderer if the audio track has one, otherwise use the sink 120 // adapter owned by this class. 121 cricket::AudioRenderer* renderer = audio_track_->GetRenderer() ? 122 audio_track_->GetRenderer() : sink_adapter_.get(); 123 ASSERT(renderer != NULL); 124 provider_->SetAudioSend(ssrc(), audio_track_->enabled(), options, renderer); 125 } 126 127 RemoteAudioTrackHandler::RemoteAudioTrackHandler( 128 AudioTrackInterface* track, 129 uint32 ssrc, 130 AudioProviderInterface* provider) 131 : TrackHandler(track, ssrc), 132 audio_track_(track), 133 provider_(provider) { 134 track->GetSource()->RegisterAudioObserver(this); 135 OnEnabledChanged(); 136 } 137 138 RemoteAudioTrackHandler::~RemoteAudioTrackHandler() { 139 audio_track_->GetSource()->UnregisterAudioObserver(this); 140 } 141 142 void RemoteAudioTrackHandler::Stop() { 143 provider_->SetAudioPlayout(ssrc(), false, NULL); 144 } 145 146 void RemoteAudioTrackHandler::OnStateChanged() { 147 } 148 149 void RemoteAudioTrackHandler::OnEnabledChanged() { 150 provider_->SetAudioPlayout(ssrc(), audio_track_->enabled(), 151 audio_track_->GetRenderer()); 152 } 153 154 void RemoteAudioTrackHandler::OnSetVolume(double volume) { 155 // When the track is disabled, the volume of the source, which is the 156 // corresponding WebRtc Voice Engine channel will be 0. So we do not allow 157 // setting the volume to the source when the track is disabled. 158 if (audio_track_->enabled()) 159 provider_->SetAudioPlayoutVolume(ssrc(), volume); 160 } 161 162 LocalVideoTrackHandler::LocalVideoTrackHandler( 163 VideoTrackInterface* track, 164 uint32 ssrc, 165 VideoProviderInterface* provider) 166 : TrackHandler(track, ssrc), 167 local_video_track_(track), 168 provider_(provider) { 169 VideoSourceInterface* source = local_video_track_->GetSource(); 170 if (source) 171 provider_->SetCaptureDevice(ssrc, source->GetVideoCapturer()); 172 OnEnabledChanged(); 173 } 174 175 LocalVideoTrackHandler::~LocalVideoTrackHandler() { 176 } 177 178 void LocalVideoTrackHandler::OnStateChanged() { 179 } 180 181 void LocalVideoTrackHandler::Stop() { 182 provider_->SetCaptureDevice(ssrc(), NULL); 183 provider_->SetVideoSend(ssrc(), false, NULL); 184 } 185 186 void LocalVideoTrackHandler::OnEnabledChanged() { 187 const cricket::VideoOptions* options = NULL; 188 VideoSourceInterface* source = local_video_track_->GetSource(); 189 if (local_video_track_->enabled() && source) { 190 options = source->options(); 191 } 192 provider_->SetVideoSend(ssrc(), local_video_track_->enabled(), options); 193 } 194 195 RemoteVideoTrackHandler::RemoteVideoTrackHandler( 196 VideoTrackInterface* track, 197 uint32 ssrc, 198 VideoProviderInterface* provider) 199 : TrackHandler(track, ssrc), 200 remote_video_track_(track), 201 provider_(provider) { 202 OnEnabledChanged(); 203 provider_->SetVideoPlayout(ssrc, true, 204 remote_video_track_->GetSource()->FrameInput()); 205 } 206 207 RemoteVideoTrackHandler::~RemoteVideoTrackHandler() { 208 } 209 210 void RemoteVideoTrackHandler::Stop() { 211 // Since cricket::VideoRenderer is not reference counted 212 // we need to remove the renderer before we are deleted. 213 provider_->SetVideoPlayout(ssrc(), false, NULL); 214 } 215 216 void RemoteVideoTrackHandler::OnStateChanged() { 217 } 218 219 void RemoteVideoTrackHandler::OnEnabledChanged() { 220 } 221 222 MediaStreamHandler::MediaStreamHandler(MediaStreamInterface* stream, 223 AudioProviderInterface* audio_provider, 224 VideoProviderInterface* video_provider) 225 : stream_(stream), 226 audio_provider_(audio_provider), 227 video_provider_(video_provider) { 228 } 229 230 MediaStreamHandler::~MediaStreamHandler() { 231 for (TrackHandlers::iterator it = track_handlers_.begin(); 232 it != track_handlers_.end(); ++it) { 233 delete *it; 234 } 235 } 236 237 void MediaStreamHandler::RemoveTrack(MediaStreamTrackInterface* track) { 238 for (TrackHandlers::iterator it = track_handlers_.begin(); 239 it != track_handlers_.end(); ++it) { 240 if ((*it)->track() == track) { 241 TrackHandler* track = *it; 242 track->Stop(); 243 delete track; 244 track_handlers_.erase(it); 245 break; 246 } 247 } 248 } 249 250 TrackHandler* MediaStreamHandler::FindTrackHandler( 251 MediaStreamTrackInterface* track) { 252 TrackHandlers::iterator it = track_handlers_.begin(); 253 for (; it != track_handlers_.end(); ++it) { 254 if ((*it)->track() == track) { 255 return *it; 256 break; 257 } 258 } 259 return NULL; 260 } 261 262 MediaStreamInterface* MediaStreamHandler::stream() { 263 return stream_.get(); 264 } 265 266 void MediaStreamHandler::OnChanged() { 267 } 268 269 void MediaStreamHandler::Stop() { 270 for (TrackHandlers::const_iterator it = track_handlers_.begin(); 271 it != track_handlers_.end(); ++it) { 272 (*it)->Stop(); 273 } 274 } 275 276 LocalMediaStreamHandler::LocalMediaStreamHandler( 277 MediaStreamInterface* stream, 278 AudioProviderInterface* audio_provider, 279 VideoProviderInterface* video_provider) 280 : MediaStreamHandler(stream, audio_provider, video_provider) { 281 } 282 283 LocalMediaStreamHandler::~LocalMediaStreamHandler() { 284 } 285 286 void LocalMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track, 287 uint32 ssrc) { 288 ASSERT(!FindTrackHandler(audio_track)); 289 290 TrackHandler* handler(new LocalAudioTrackHandler(audio_track, ssrc, 291 audio_provider_)); 292 track_handlers_.push_back(handler); 293 } 294 295 void LocalMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track, 296 uint32 ssrc) { 297 ASSERT(!FindTrackHandler(video_track)); 298 299 TrackHandler* handler(new LocalVideoTrackHandler(video_track, ssrc, 300 video_provider_)); 301 track_handlers_.push_back(handler); 302 } 303 304 RemoteMediaStreamHandler::RemoteMediaStreamHandler( 305 MediaStreamInterface* stream, 306 AudioProviderInterface* audio_provider, 307 VideoProviderInterface* video_provider) 308 : MediaStreamHandler(stream, audio_provider, video_provider) { 309 } 310 311 RemoteMediaStreamHandler::~RemoteMediaStreamHandler() { 312 } 313 314 void RemoteMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track, 315 uint32 ssrc) { 316 ASSERT(!FindTrackHandler(audio_track)); 317 TrackHandler* handler( 318 new RemoteAudioTrackHandler(audio_track, ssrc, audio_provider_)); 319 track_handlers_.push_back(handler); 320 } 321 322 void RemoteMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track, 323 uint32 ssrc) { 324 ASSERT(!FindTrackHandler(video_track)); 325 TrackHandler* handler( 326 new RemoteVideoTrackHandler(video_track, ssrc, video_provider_)); 327 track_handlers_.push_back(handler); 328 } 329 330 MediaStreamHandlerContainer::MediaStreamHandlerContainer( 331 AudioProviderInterface* audio_provider, 332 VideoProviderInterface* video_provider) 333 : audio_provider_(audio_provider), 334 video_provider_(video_provider) { 335 } 336 337 MediaStreamHandlerContainer::~MediaStreamHandlerContainer() { 338 ASSERT(remote_streams_handlers_.empty()); 339 ASSERT(local_streams_handlers_.empty()); 340 } 341 342 void MediaStreamHandlerContainer::TearDown() { 343 for (StreamHandlerList::iterator it = remote_streams_handlers_.begin(); 344 it != remote_streams_handlers_.end(); ++it) { 345 (*it)->Stop(); 346 delete *it; 347 } 348 remote_streams_handlers_.clear(); 349 for (StreamHandlerList::iterator it = local_streams_handlers_.begin(); 350 it != local_streams_handlers_.end(); ++it) { 351 (*it)->Stop(); 352 delete *it; 353 } 354 local_streams_handlers_.clear(); 355 } 356 357 void MediaStreamHandlerContainer::RemoveRemoteStream( 358 MediaStreamInterface* stream) { 359 DeleteStreamHandler(&remote_streams_handlers_, stream); 360 } 361 362 void MediaStreamHandlerContainer::AddRemoteAudioTrack( 363 MediaStreamInterface* stream, 364 AudioTrackInterface* audio_track, 365 uint32 ssrc) { 366 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_, 367 stream); 368 if (handler == NULL) { 369 handler = CreateRemoteStreamHandler(stream); 370 } 371 handler->AddAudioTrack(audio_track, ssrc); 372 } 373 374 void MediaStreamHandlerContainer::AddRemoteVideoTrack( 375 MediaStreamInterface* stream, 376 VideoTrackInterface* video_track, 377 uint32 ssrc) { 378 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_, 379 stream); 380 if (handler == NULL) { 381 handler = CreateRemoteStreamHandler(stream); 382 } 383 handler->AddVideoTrack(video_track, ssrc); 384 } 385 386 void MediaStreamHandlerContainer::RemoveRemoteTrack( 387 MediaStreamInterface* stream, 388 MediaStreamTrackInterface* track) { 389 MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_, 390 stream); 391 if (!VERIFY(handler != NULL)) { 392 LOG(LS_WARNING) << "Local MediaStreamHandler for stream with id " 393 << stream->label() << "doesnt't exist."; 394 return; 395 } 396 handler->RemoveTrack(track); 397 } 398 399 void MediaStreamHandlerContainer::RemoveLocalStream( 400 MediaStreamInterface* stream) { 401 DeleteStreamHandler(&local_streams_handlers_, stream); 402 } 403 404 void MediaStreamHandlerContainer::AddLocalAudioTrack( 405 MediaStreamInterface* stream, 406 AudioTrackInterface* audio_track, 407 uint32 ssrc) { 408 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_, 409 stream); 410 if (handler == NULL) { 411 handler = CreateLocalStreamHandler(stream); 412 } 413 handler->AddAudioTrack(audio_track, ssrc); 414 } 415 416 void MediaStreamHandlerContainer::AddLocalVideoTrack( 417 MediaStreamInterface* stream, 418 VideoTrackInterface* video_track, 419 uint32 ssrc) { 420 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_, 421 stream); 422 if (handler == NULL) { 423 handler = CreateLocalStreamHandler(stream); 424 } 425 handler->AddVideoTrack(video_track, ssrc); 426 } 427 428 void MediaStreamHandlerContainer::RemoveLocalTrack( 429 MediaStreamInterface* stream, 430 MediaStreamTrackInterface* track) { 431 MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_, 432 stream); 433 if (!VERIFY(handler != NULL)) { 434 LOG(LS_WARNING) << "Remote MediaStreamHandler for stream with id " 435 << stream->label() << "doesnt't exist."; 436 return; 437 } 438 handler->RemoveTrack(track); 439 } 440 441 MediaStreamHandler* MediaStreamHandlerContainer::CreateRemoteStreamHandler( 442 MediaStreamInterface* stream) { 443 ASSERT(!FindStreamHandler(remote_streams_handlers_, stream)); 444 445 RemoteMediaStreamHandler* handler = 446 new RemoteMediaStreamHandler(stream, audio_provider_, video_provider_); 447 remote_streams_handlers_.push_back(handler); 448 return handler; 449 } 450 451 MediaStreamHandler* MediaStreamHandlerContainer::CreateLocalStreamHandler( 452 MediaStreamInterface* stream) { 453 ASSERT(!FindStreamHandler(local_streams_handlers_, stream)); 454 455 LocalMediaStreamHandler* handler = 456 new LocalMediaStreamHandler(stream, audio_provider_, video_provider_); 457 local_streams_handlers_.push_back(handler); 458 return handler; 459 } 460 461 MediaStreamHandler* MediaStreamHandlerContainer::FindStreamHandler( 462 const StreamHandlerList& handlers, 463 MediaStreamInterface* stream) { 464 StreamHandlerList::const_iterator it = handlers.begin(); 465 for (; it != handlers.end(); ++it) { 466 if ((*it)->stream() == stream) { 467 return *it; 468 } 469 } 470 return NULL; 471 } 472 473 void MediaStreamHandlerContainer::DeleteStreamHandler( 474 StreamHandlerList* streamhandlers, MediaStreamInterface* stream) { 475 StreamHandlerList::iterator it = streamhandlers->begin(); 476 for (; it != streamhandlers->end(); ++it) { 477 if ((*it)->stream() == stream) { 478 (*it)->Stop(); 479 delete *it; 480 streamhandlers->erase(it); 481 break; 482 } 483 } 484 } 485 486 } // namespace webrtc 487