1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" 6 7 #include "base/logging.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "content/renderer/media/mock_peer_connection_impl.h" 10 #include "content/renderer/media/webaudio_capturer_source.h" 11 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 12 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" 13 #include "content/renderer/media/webrtc_audio_capturer.h" 14 #include "content/renderer/media/webrtc_local_audio_track.h" 15 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 16 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" 17 #include "third_party/libjingle/source/talk/base/scoped_ref_ptr.h" 18 #include "third_party/libjingle/source/talk/media/base/videocapturer.h" 19 20 using webrtc::AudioSourceInterface; 21 using webrtc::AudioTrackInterface; 22 using webrtc::AudioTrackVector; 23 using webrtc::IceCandidateCollection; 24 using webrtc::IceCandidateInterface; 25 using webrtc::MediaStreamInterface; 26 using webrtc::ObserverInterface; 27 using webrtc::SessionDescriptionInterface; 28 using webrtc::VideoRendererInterface; 29 using webrtc::VideoSourceInterface; 30 using webrtc::VideoTrackInterface; 31 using webrtc::VideoTrackVector; 32 33 namespace content { 34 35 template <class V> 36 static typename V::iterator FindTrack(V* vector, 37 const std::string& track_id) { 38 typename V::iterator it = vector->begin(); 39 for (; it != vector->end(); ++it) { 40 if ((*it)->id() == track_id) { 41 break; 42 } 43 } 44 return it; 45 }; 46 47 MockMediaStream::MockMediaStream(const std::string& label) : label_(label) {} 48 49 bool MockMediaStream::AddTrack(AudioTrackInterface* track) { 50 audio_track_vector_.push_back(track); 51 NotifyObservers(); 52 return true; 53 } 54 55 bool MockMediaStream::AddTrack(VideoTrackInterface* track) { 56 video_track_vector_.push_back(track); 57 NotifyObservers(); 58 return true; 59 } 60 61 bool MockMediaStream::RemoveTrack(AudioTrackInterface* track) { 62 AudioTrackVector::iterator it = FindTrack(&audio_track_vector_, 63 track->id()); 64 if (it == audio_track_vector_.end()) 65 return false; 66 audio_track_vector_.erase(it); 67 NotifyObservers(); 68 return true; 69 } 70 71 bool MockMediaStream::RemoveTrack(VideoTrackInterface* track) { 72 VideoTrackVector::iterator it = FindTrack(&video_track_vector_, 73 track->id()); 74 if (it == video_track_vector_.end()) 75 return false; 76 video_track_vector_.erase(it); 77 NotifyObservers(); 78 return true; 79 } 80 81 std::string MockMediaStream::label() const { 82 return label_; 83 } 84 85 AudioTrackVector MockMediaStream::GetAudioTracks() { 86 return audio_track_vector_; 87 } 88 89 VideoTrackVector MockMediaStream::GetVideoTracks() { 90 return video_track_vector_; 91 } 92 93 talk_base::scoped_refptr<AudioTrackInterface> MockMediaStream::FindAudioTrack( 94 const std::string& track_id) { 95 AudioTrackVector::iterator it = FindTrack(&audio_track_vector_, track_id); 96 return it == audio_track_vector_.end() ? NULL : *it; 97 } 98 99 talk_base::scoped_refptr<VideoTrackInterface> MockMediaStream::FindVideoTrack( 100 const std::string& track_id) { 101 VideoTrackVector::iterator it = FindTrack(&video_track_vector_, track_id); 102 return it == video_track_vector_.end() ? NULL : *it; 103 } 104 105 void MockMediaStream::RegisterObserver(ObserverInterface* observer) { 106 DCHECK(observers_.find(observer) == observers_.end()); 107 observers_.insert(observer); 108 } 109 110 void MockMediaStream::UnregisterObserver(ObserverInterface* observer) { 111 ObserverSet::iterator it = observers_.find(observer); 112 DCHECK(it != observers_.end()); 113 observers_.erase(it); 114 } 115 116 void MockMediaStream::NotifyObservers() { 117 for (ObserverSet::iterator it = observers_.begin(); it != observers_.end(); 118 ++it) { 119 (*it)->OnChanged(); 120 } 121 } 122 123 MockMediaStream::~MockMediaStream() {} 124 125 class MockRtcVideoCapturer : public WebRtcVideoCapturerAdapter { 126 public: 127 explicit MockRtcVideoCapturer(bool is_screencast) 128 : WebRtcVideoCapturerAdapter(is_screencast), 129 number_of_capturered_frames_(0), 130 width_(0), 131 height_(0) { 132 } 133 134 virtual void OnFrameCaptured( 135 const scoped_refptr<media::VideoFrame>& frame) OVERRIDE { 136 ++number_of_capturered_frames_; 137 width_ = frame->visible_rect().width(); 138 height_ = frame->visible_rect().height(); 139 } 140 141 int GetLastFrameWidth() const { 142 return width_; 143 } 144 145 int GetLastFrameHeight() const { 146 return height_; 147 } 148 149 int GetFrameNum() const { 150 return number_of_capturered_frames_; 151 } 152 153 private: 154 int number_of_capturered_frames_; 155 int width_; 156 int height_; 157 }; 158 159 MockVideoRenderer::MockVideoRenderer() 160 : width_(0), 161 height_(0), 162 num_(0) {} 163 164 MockVideoRenderer::~MockVideoRenderer() {} 165 166 bool MockVideoRenderer::SetSize(int width, int height, int reserved) { 167 width_ = width; 168 height_ = height; 169 return true; 170 } 171 172 bool MockVideoRenderer::RenderFrame(const cricket::VideoFrame* frame) { 173 ++num_; 174 return true; 175 } 176 177 MockAudioSource::MockAudioSource( 178 const webrtc::MediaConstraintsInterface* constraints) 179 : observer_(NULL), 180 state_(MediaSourceInterface::kLive), 181 optional_constraints_(constraints->GetOptional()), 182 mandatory_constraints_(constraints->GetMandatory()) { 183 } 184 185 MockAudioSource::~MockAudioSource() {} 186 187 void MockAudioSource::RegisterObserver(webrtc::ObserverInterface* observer) { 188 observer_ = observer; 189 } 190 191 void MockAudioSource::UnregisterObserver(webrtc::ObserverInterface* observer) { 192 DCHECK(observer_ == observer); 193 observer_ = NULL; 194 } 195 196 webrtc::MediaSourceInterface::SourceState MockAudioSource::state() const { 197 return state_; 198 } 199 200 MockVideoSource::MockVideoSource() 201 : state_(MediaSourceInterface::kInitializing) { 202 } 203 204 MockVideoSource::~MockVideoSource() {} 205 206 void MockVideoSource::SetVideoCapturer(cricket::VideoCapturer* capturer) { 207 capturer_.reset(capturer); 208 } 209 210 cricket::VideoCapturer* MockVideoSource::GetVideoCapturer() { 211 return capturer_.get(); 212 } 213 214 void MockVideoSource::AddSink(cricket::VideoRenderer* output) { 215 NOTIMPLEMENTED(); 216 } 217 218 void MockVideoSource::RemoveSink(cricket::VideoRenderer* output) { 219 NOTIMPLEMENTED(); 220 } 221 222 cricket::VideoRenderer* MockVideoSource::FrameInput() { 223 return &renderer_; 224 } 225 226 void MockVideoSource::RegisterObserver(webrtc::ObserverInterface* observer) { 227 observers_.push_back(observer); 228 } 229 230 void MockVideoSource::UnregisterObserver(webrtc::ObserverInterface* observer) { 231 for (std::vector<ObserverInterface*>::iterator it = observers_.begin(); 232 it != observers_.end(); ++it) { 233 if (*it == observer) { 234 observers_.erase(it); 235 break; 236 } 237 } 238 } 239 240 void MockVideoSource::FireOnChanged() { 241 std::vector<ObserverInterface*> observers(observers_); 242 for (std::vector<ObserverInterface*>::iterator it = observers.begin(); 243 it != observers.end(); ++it) { 244 (*it)->OnChanged(); 245 } 246 } 247 248 void MockVideoSource::SetLive() { 249 DCHECK(state_ == MediaSourceInterface::kInitializing || 250 state_ == MediaSourceInterface::kLive); 251 state_ = MediaSourceInterface::kLive; 252 FireOnChanged(); 253 } 254 255 void MockVideoSource::SetEnded() { 256 DCHECK_NE(MediaSourceInterface::kEnded, state_); 257 state_ = MediaSourceInterface::kEnded; 258 FireOnChanged(); 259 } 260 261 webrtc::MediaSourceInterface::SourceState MockVideoSource::state() const { 262 return state_; 263 } 264 265 const cricket::VideoOptions* MockVideoSource::options() const { 266 NOTIMPLEMENTED(); 267 return NULL; 268 } 269 270 int MockVideoSource::GetLastFrameWidth() const { 271 DCHECK(capturer_); 272 return 273 static_cast<MockRtcVideoCapturer*>(capturer_.get())->GetLastFrameWidth(); 274 } 275 276 int MockVideoSource::GetLastFrameHeight() const { 277 DCHECK(capturer_); 278 return 279 static_cast<MockRtcVideoCapturer*>(capturer_.get())->GetLastFrameHeight(); 280 } 281 282 int MockVideoSource::GetFrameNum() const { 283 DCHECK(capturer_); 284 return static_cast<MockRtcVideoCapturer*>(capturer_.get())->GetFrameNum(); 285 } 286 287 MockWebRtcVideoTrack::MockWebRtcVideoTrack( 288 const std::string& id, 289 webrtc::VideoSourceInterface* source) 290 : enabled_(false), 291 id_(id), 292 state_(MediaStreamTrackInterface::kLive), 293 source_(source), 294 observer_(NULL), 295 renderer_(NULL) { 296 } 297 298 MockWebRtcVideoTrack::~MockWebRtcVideoTrack() {} 299 300 void MockWebRtcVideoTrack::AddRenderer(VideoRendererInterface* renderer) { 301 DCHECK(!renderer_); 302 renderer_ = renderer; 303 } 304 305 void MockWebRtcVideoTrack::RemoveRenderer(VideoRendererInterface* renderer) { 306 DCHECK_EQ(renderer_, renderer); 307 renderer_ = NULL; 308 } 309 310 std::string MockWebRtcVideoTrack::kind() const { 311 NOTIMPLEMENTED(); 312 return std::string(); 313 } 314 315 std::string MockWebRtcVideoTrack::id() const { return id_; } 316 317 bool MockWebRtcVideoTrack::enabled() const { return enabled_; } 318 319 MockWebRtcVideoTrack::TrackState MockWebRtcVideoTrack::state() const { 320 return state_; 321 } 322 323 bool MockWebRtcVideoTrack::set_enabled(bool enable) { 324 enabled_ = enable; 325 return true; 326 } 327 328 bool MockWebRtcVideoTrack::set_state(TrackState new_state) { 329 state_ = new_state; 330 if (observer_) 331 observer_->OnChanged(); 332 return true; 333 } 334 335 void MockWebRtcVideoTrack::RegisterObserver(ObserverInterface* observer) { 336 observer_ = observer; 337 } 338 339 void MockWebRtcVideoTrack::UnregisterObserver(ObserverInterface* observer) { 340 DCHECK(observer_ == observer); 341 observer_ = NULL; 342 } 343 344 VideoSourceInterface* MockWebRtcVideoTrack::GetSource() const { 345 return source_.get(); 346 } 347 348 class MockSessionDescription : public SessionDescriptionInterface { 349 public: 350 MockSessionDescription(const std::string& type, 351 const std::string& sdp) 352 : type_(type), 353 sdp_(sdp) { 354 } 355 virtual ~MockSessionDescription() {} 356 virtual cricket::SessionDescription* description() OVERRIDE { 357 NOTIMPLEMENTED(); 358 return NULL; 359 } 360 virtual const cricket::SessionDescription* description() const OVERRIDE { 361 NOTIMPLEMENTED(); 362 return NULL; 363 } 364 virtual std::string session_id() const OVERRIDE { 365 NOTIMPLEMENTED(); 366 return std::string(); 367 } 368 virtual std::string session_version() const OVERRIDE { 369 NOTIMPLEMENTED(); 370 return std::string(); 371 } 372 virtual std::string type() const OVERRIDE { 373 return type_; 374 } 375 virtual bool AddCandidate(const IceCandidateInterface* candidate) OVERRIDE { 376 NOTIMPLEMENTED(); 377 return false; 378 } 379 virtual size_t number_of_mediasections() const OVERRIDE { 380 NOTIMPLEMENTED(); 381 return 0; 382 } 383 virtual const IceCandidateCollection* candidates( 384 size_t mediasection_index) const OVERRIDE { 385 NOTIMPLEMENTED(); 386 return NULL; 387 } 388 389 virtual bool ToString(std::string* out) const OVERRIDE { 390 *out = sdp_; 391 return true; 392 } 393 394 private: 395 std::string type_; 396 std::string sdp_; 397 }; 398 399 class MockIceCandidate : public IceCandidateInterface { 400 public: 401 MockIceCandidate(const std::string& sdp_mid, 402 int sdp_mline_index, 403 const std::string& sdp) 404 : sdp_mid_(sdp_mid), 405 sdp_mline_index_(sdp_mline_index), 406 sdp_(sdp) { 407 } 408 virtual ~MockIceCandidate() {} 409 virtual std::string sdp_mid() const OVERRIDE { 410 return sdp_mid_; 411 } 412 virtual int sdp_mline_index() const OVERRIDE { 413 return sdp_mline_index_; 414 } 415 virtual const cricket::Candidate& candidate() const OVERRIDE { 416 // This function should never be called. It will intentionally crash. The 417 // base class forces us to return a reference. 418 NOTREACHED(); 419 cricket::Candidate* candidate = NULL; 420 return *candidate; 421 } 422 virtual bool ToString(std::string* out) const OVERRIDE { 423 *out = sdp_; 424 return true; 425 } 426 427 private: 428 std::string sdp_mid_; 429 int sdp_mline_index_; 430 std::string sdp_; 431 }; 432 433 MockPeerConnectionDependencyFactory::MockPeerConnectionDependencyFactory() 434 : PeerConnectionDependencyFactory(NULL), 435 fail_to_create_next_audio_capturer_(false) { 436 } 437 438 MockPeerConnectionDependencyFactory::~MockPeerConnectionDependencyFactory() {} 439 440 scoped_refptr<webrtc::PeerConnectionInterface> 441 MockPeerConnectionDependencyFactory::CreatePeerConnection( 442 const webrtc::PeerConnectionInterface::IceServers& ice_servers, 443 const webrtc::MediaConstraintsInterface* constraints, 444 blink::WebFrame* frame, 445 webrtc::PeerConnectionObserver* observer) { 446 return new talk_base::RefCountedObject<MockPeerConnectionImpl>(this); 447 } 448 449 scoped_refptr<webrtc::AudioSourceInterface> 450 MockPeerConnectionDependencyFactory::CreateLocalAudioSource( 451 const webrtc::MediaConstraintsInterface* constraints) { 452 last_audio_source_ = 453 new talk_base::RefCountedObject<MockAudioSource>(constraints); 454 return last_audio_source_; 455 } 456 457 WebRtcVideoCapturerAdapter* 458 MockPeerConnectionDependencyFactory::CreateVideoCapturer( 459 bool is_screen_capture) { 460 return new MockRtcVideoCapturer(is_screen_capture); 461 } 462 463 scoped_refptr<webrtc::VideoSourceInterface> 464 MockPeerConnectionDependencyFactory::CreateVideoSource( 465 cricket::VideoCapturer* capturer, 466 const blink::WebMediaConstraints& constraints) { 467 last_video_source_ = new talk_base::RefCountedObject<MockVideoSource>(); 468 last_video_source_->SetVideoCapturer(capturer); 469 return last_video_source_; 470 } 471 472 scoped_refptr<WebAudioCapturerSource> 473 MockPeerConnectionDependencyFactory::CreateWebAudioSource( 474 blink::WebMediaStreamSource* source) { 475 return NULL; 476 } 477 478 scoped_refptr<webrtc::MediaStreamInterface> 479 MockPeerConnectionDependencyFactory::CreateLocalMediaStream( 480 const std::string& label) { 481 return new talk_base::RefCountedObject<MockMediaStream>(label); 482 } 483 484 scoped_refptr<webrtc::VideoTrackInterface> 485 MockPeerConnectionDependencyFactory::CreateLocalVideoTrack( 486 const std::string& id, 487 webrtc::VideoSourceInterface* source) { 488 scoped_refptr<webrtc::VideoTrackInterface> track( 489 new talk_base::RefCountedObject<MockWebRtcVideoTrack>( 490 id, source)); 491 return track; 492 } 493 494 scoped_refptr<webrtc::VideoTrackInterface> 495 MockPeerConnectionDependencyFactory::CreateLocalVideoTrack( 496 const std::string& id, 497 cricket::VideoCapturer* capturer) { 498 scoped_refptr<MockVideoSource> source = 499 new talk_base::RefCountedObject<MockVideoSource>(); 500 source->SetVideoCapturer(capturer); 501 502 return 503 new talk_base::RefCountedObject<MockWebRtcVideoTrack>(id, source.get()); 504 } 505 506 SessionDescriptionInterface* 507 MockPeerConnectionDependencyFactory::CreateSessionDescription( 508 const std::string& type, 509 const std::string& sdp, 510 webrtc::SdpParseError* error) { 511 return new MockSessionDescription(type, sdp); 512 } 513 514 webrtc::IceCandidateInterface* 515 MockPeerConnectionDependencyFactory::CreateIceCandidate( 516 const std::string& sdp_mid, 517 int sdp_mline_index, 518 const std::string& sdp) { 519 return new MockIceCandidate(sdp_mid, sdp_mline_index, sdp); 520 } 521 522 scoped_refptr<WebRtcAudioCapturer> 523 MockPeerConnectionDependencyFactory::CreateAudioCapturer( 524 int render_view_id, const StreamDeviceInfo& device_info, 525 const blink::WebMediaConstraints& constraints, 526 MediaStreamAudioSource* audio_source) { 527 if (fail_to_create_next_audio_capturer_) { 528 fail_to_create_next_audio_capturer_ = false; 529 return NULL; 530 } 531 DCHECK(audio_source); 532 return WebRtcAudioCapturer::CreateCapturer(-1, device_info, 533 constraints, NULL, audio_source); 534 } 535 536 void MockPeerConnectionDependencyFactory::StartLocalAudioTrack( 537 WebRtcLocalAudioTrack* audio_track) { 538 audio_track->Start(); 539 } 540 541 } // namespace content 542