// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/renderer/media/mock_media_stream_dependency_factory.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "content/renderer/media/mock_peer_connection_impl.h" #include "content/renderer/media/webaudio_capturer_source.h" #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" #include "content/renderer/media/webrtc_audio_capturer.h" #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" #include "third_party/libjingle/source/talk/base/scoped_ref_ptr.h" #include "third_party/libjingle/source/talk/media/base/videocapturer.h" using webrtc::AudioSourceInterface; using webrtc::AudioTrackInterface; using webrtc::AudioTrackVector; using webrtc::IceCandidateCollection; using webrtc::IceCandidateInterface; using webrtc::MediaStreamInterface; using webrtc::ObserverInterface; using webrtc::SessionDescriptionInterface; using webrtc::VideoRendererInterface; using webrtc::VideoSourceInterface; using webrtc::VideoTrackInterface; using webrtc::VideoTrackVector; namespace content { template static typename V::iterator FindTrack(V* vector, const std::string& track_id) { typename V::iterator it = vector->begin(); for (; it != vector->end(); ++it) { if ((*it)->id() == track_id) { break; } } return it; }; MockMediaStream::MockMediaStream(const std::string& label) : label_(label) {} bool MockMediaStream::AddTrack(AudioTrackInterface* track) { audio_track_vector_.push_back(track); NotifyObservers(); return true; } bool MockMediaStream::AddTrack(VideoTrackInterface* track) { video_track_vector_.push_back(track); NotifyObservers(); return true; } bool MockMediaStream::RemoveTrack(AudioTrackInterface* track) { AudioTrackVector::iterator it = FindTrack(&audio_track_vector_, track->id()); if (it == audio_track_vector_.end()) return false; audio_track_vector_.erase(it); NotifyObservers(); return true; } bool MockMediaStream::RemoveTrack(VideoTrackInterface* track) { VideoTrackVector::iterator it = FindTrack(&video_track_vector_, track->id()); if (it == video_track_vector_.end()) return false; video_track_vector_.erase(it); NotifyObservers(); return true; } std::string MockMediaStream::label() const { return label_; } AudioTrackVector MockMediaStream::GetAudioTracks() { return audio_track_vector_; } VideoTrackVector MockMediaStream::GetVideoTracks() { return video_track_vector_; } talk_base::scoped_refptr MockMediaStream::FindAudioTrack( const std::string& track_id) { AudioTrackVector::iterator it = FindTrack(&audio_track_vector_, track_id); return it == audio_track_vector_.end() ? NULL : *it; } talk_base::scoped_refptr MockMediaStream::FindVideoTrack( const std::string& track_id) { VideoTrackVector::iterator it = FindTrack(&video_track_vector_, track_id); return it == video_track_vector_.end() ? NULL : *it; } void MockMediaStream::RegisterObserver(ObserverInterface* observer) { DCHECK(observers_.find(observer) == observers_.end()); observers_.insert(observer); } void MockMediaStream::UnregisterObserver(ObserverInterface* observer) { ObserverSet::iterator it = observers_.find(observer); DCHECK(it != observers_.end()); observers_.erase(it); } void MockMediaStream::NotifyObservers() { for (ObserverSet::iterator it = observers_.begin(); it != observers_.end(); ++it) { (*it)->OnChanged(); } } MockMediaStream::~MockMediaStream() {} class MockRtcVideoCapturer : public WebRtcVideoCapturerAdapter { public: explicit MockRtcVideoCapturer(bool is_screencast) : WebRtcVideoCapturerAdapter(is_screencast), number_of_capturered_frames_(0), width_(0), height_(0) { } virtual void SetRequestedFormat( const media::VideoCaptureFormat& format) OVERRIDE { } virtual void OnFrameCaptured( const scoped_refptr& frame) OVERRIDE { ++number_of_capturered_frames_; width_ = frame->visible_rect().width(); height_ = frame->visible_rect().height(); } int GetLastFrameWidth() const { return width_; } int GetLastFrameHeight() const { return height_; } int GetFrameNum() const { return number_of_capturered_frames_; } private: int number_of_capturered_frames_; int width_; int height_; }; MockVideoRenderer::MockVideoRenderer() : width_(0), height_(0), num_(0) {} MockVideoRenderer::~MockVideoRenderer() {} bool MockVideoRenderer::SetSize(int width, int height, int reserved) { width_ = width; height_ = height; return true; } bool MockVideoRenderer::RenderFrame(const cricket::VideoFrame* frame) { ++num_; return true; } MockAudioSource::MockAudioSource( const webrtc::MediaConstraintsInterface* constraints) : observer_(NULL), state_(MediaSourceInterface::kLive), optional_constraints_(constraints->GetOptional()), mandatory_constraints_(constraints->GetMandatory()) { } MockAudioSource::~MockAudioSource() {} void MockAudioSource::RegisterObserver(webrtc::ObserverInterface* observer) { observer_ = observer; } void MockAudioSource::UnregisterObserver(webrtc::ObserverInterface* observer) { DCHECK(observer_ == observer); observer_ = NULL; } webrtc::MediaSourceInterface::SourceState MockAudioSource::state() const { return state_; } MockVideoSource::MockVideoSource() : state_(MediaSourceInterface::kInitializing) { } MockVideoSource::~MockVideoSource() {} void MockVideoSource::SetVideoCapturer(cricket::VideoCapturer* capturer) { capturer_.reset(capturer); } cricket::VideoCapturer* MockVideoSource::GetVideoCapturer() { return capturer_.get(); } void MockVideoSource::AddSink(cricket::VideoRenderer* output) { NOTIMPLEMENTED(); } void MockVideoSource::RemoveSink(cricket::VideoRenderer* output) { NOTIMPLEMENTED(); } cricket::VideoRenderer* MockVideoSource::FrameInput() { return &renderer_; } void MockVideoSource::RegisterObserver(webrtc::ObserverInterface* observer) { observers_.push_back(observer); } void MockVideoSource::UnregisterObserver(webrtc::ObserverInterface* observer) { for (std::vector::iterator it = observers_.begin(); it != observers_.end(); ++it) { if (*it == observer) { observers_.erase(it); break; } } } void MockVideoSource::FireOnChanged() { std::vector observers(observers_); for (std::vector::iterator it = observers.begin(); it != observers.end(); ++it) { (*it)->OnChanged(); } } void MockVideoSource::SetLive() { DCHECK(state_ == MediaSourceInterface::kInitializing || state_ == MediaSourceInterface::kLive); state_ = MediaSourceInterface::kLive; FireOnChanged(); } void MockVideoSource::SetEnded() { DCHECK_NE(MediaSourceInterface::kEnded, state_); state_ = MediaSourceInterface::kEnded; FireOnChanged(); } webrtc::MediaSourceInterface::SourceState MockVideoSource::state() const { return state_; } const cricket::VideoOptions* MockVideoSource::options() const { NOTIMPLEMENTED(); return NULL; } int MockVideoSource::GetLastFrameWidth() const { DCHECK(capturer_); return static_cast(capturer_.get())->GetLastFrameWidth(); } int MockVideoSource::GetLastFrameHeight() const { DCHECK(capturer_); return static_cast(capturer_.get())->GetLastFrameHeight(); } int MockVideoSource::GetFrameNum() const { DCHECK(capturer_); return static_cast(capturer_.get())->GetFrameNum(); } MockLocalVideoTrack::MockLocalVideoTrack(std::string id, webrtc::VideoSourceInterface* source) : enabled_(false), id_(id), state_(MediaStreamTrackInterface::kLive), source_(source), observer_(NULL) { } MockLocalVideoTrack::~MockLocalVideoTrack() {} void MockLocalVideoTrack::AddRenderer(VideoRendererInterface* renderer) { NOTIMPLEMENTED(); } void MockLocalVideoTrack::RemoveRenderer(VideoRendererInterface* renderer) { NOTIMPLEMENTED(); } std::string MockLocalVideoTrack::kind() const { NOTIMPLEMENTED(); return std::string(); } std::string MockLocalVideoTrack::id() const { return id_; } bool MockLocalVideoTrack::enabled() const { return enabled_; } MockLocalVideoTrack::TrackState MockLocalVideoTrack::state() const { return state_; } bool MockLocalVideoTrack::set_enabled(bool enable) { enabled_ = enable; return true; } bool MockLocalVideoTrack::set_state(TrackState new_state) { state_ = new_state; if (observer_) observer_->OnChanged(); return true; } void MockLocalVideoTrack::RegisterObserver(ObserverInterface* observer) { observer_ = observer; } void MockLocalVideoTrack::UnregisterObserver(ObserverInterface* observer) { DCHECK(observer_ == observer); observer_ = NULL; } VideoSourceInterface* MockLocalVideoTrack::GetSource() const { return source_.get(); } class MockSessionDescription : public SessionDescriptionInterface { public: MockSessionDescription(const std::string& type, const std::string& sdp) : type_(type), sdp_(sdp) { } virtual ~MockSessionDescription() {} virtual cricket::SessionDescription* description() OVERRIDE { NOTIMPLEMENTED(); return NULL; } virtual const cricket::SessionDescription* description() const OVERRIDE { NOTIMPLEMENTED(); return NULL; } virtual std::string session_id() const OVERRIDE { NOTIMPLEMENTED(); return std::string(); } virtual std::string session_version() const OVERRIDE { NOTIMPLEMENTED(); return std::string(); } virtual std::string type() const OVERRIDE { return type_; } virtual bool AddCandidate(const IceCandidateInterface* candidate) OVERRIDE { NOTIMPLEMENTED(); return false; } virtual size_t number_of_mediasections() const OVERRIDE { NOTIMPLEMENTED(); return 0; } virtual const IceCandidateCollection* candidates( size_t mediasection_index) const OVERRIDE { NOTIMPLEMENTED(); return NULL; } virtual bool ToString(std::string* out) const OVERRIDE { *out = sdp_; return true; } private: std::string type_; std::string sdp_; }; class MockIceCandidate : public IceCandidateInterface { public: MockIceCandidate(const std::string& sdp_mid, int sdp_mline_index, const std::string& sdp) : sdp_mid_(sdp_mid), sdp_mline_index_(sdp_mline_index), sdp_(sdp) { } virtual ~MockIceCandidate() {} virtual std::string sdp_mid() const OVERRIDE { return sdp_mid_; } virtual int sdp_mline_index() const OVERRIDE { return sdp_mline_index_; } virtual const cricket::Candidate& candidate() const OVERRIDE { // This function should never be called. It will intentionally crash. The // base class forces us to return a reference. NOTREACHED(); cricket::Candidate* candidate = NULL; return *candidate; } virtual bool ToString(std::string* out) const OVERRIDE { *out = sdp_; return true; } private: std::string sdp_mid_; int sdp_mline_index_; std::string sdp_; }; MockMediaStreamDependencyFactory::MockMediaStreamDependencyFactory() : MediaStreamDependencyFactory(NULL) { } MockMediaStreamDependencyFactory::~MockMediaStreamDependencyFactory() {} scoped_refptr MockMediaStreamDependencyFactory::CreatePeerConnection( const webrtc::PeerConnectionInterface::IceServers& ice_servers, const webrtc::MediaConstraintsInterface* constraints, blink::WebFrame* frame, webrtc::PeerConnectionObserver* observer) { return new talk_base::RefCountedObject(this); } scoped_refptr MockMediaStreamDependencyFactory::CreateLocalAudioSource( const webrtc::MediaConstraintsInterface* constraints) { last_audio_source_ = new talk_base::RefCountedObject(constraints); return last_audio_source_; } WebRtcVideoCapturerAdapter* MockMediaStreamDependencyFactory::CreateVideoCapturer( bool is_screen_capture) { return new MockRtcVideoCapturer(is_screen_capture); } scoped_refptr MockMediaStreamDependencyFactory::CreateVideoSource( cricket::VideoCapturer* capturer, const blink::WebMediaConstraints& constraints) { last_video_source_ = new talk_base::RefCountedObject(); last_video_source_->SetVideoCapturer(capturer); return last_video_source_; } scoped_refptr MockMediaStreamDependencyFactory::CreateWebAudioSource( blink::WebMediaStreamSource* source) { return NULL; } scoped_refptr MockMediaStreamDependencyFactory::CreateLocalMediaStream( const std::string& label) { return new talk_base::RefCountedObject(label); } scoped_refptr MockMediaStreamDependencyFactory::CreateLocalVideoTrack( const std::string& id, webrtc::VideoSourceInterface* source) { scoped_refptr track( new talk_base::RefCountedObject( id, source)); return track; } scoped_refptr MockMediaStreamDependencyFactory::CreateLocalVideoTrack( const std::string& id, cricket::VideoCapturer* capturer) { scoped_refptr source = new talk_base::RefCountedObject(); source->SetVideoCapturer(capturer); return new talk_base::RefCountedObject(id, source.get()); } SessionDescriptionInterface* MockMediaStreamDependencyFactory::CreateSessionDescription( const std::string& type, const std::string& sdp, webrtc::SdpParseError* error) { return new MockSessionDescription(type, sdp); } webrtc::IceCandidateInterface* MockMediaStreamDependencyFactory::CreateIceCandidate( const std::string& sdp_mid, int sdp_mline_index, const std::string& sdp) { return new MockIceCandidate(sdp_mid, sdp_mline_index, sdp); } scoped_refptr MockMediaStreamDependencyFactory::CreateAudioCapturer( int render_view_id, const StreamDeviceInfo& device_info, const blink::WebMediaConstraints& constraints) { return WebRtcAudioCapturer::CreateCapturer(-1, device_info, constraints, NULL); } void MockMediaStreamDependencyFactory::StartLocalAudioTrack( WebRtcLocalAudioTrack* audio_track) { return; } } // namespace content