Exposing RtpSenders and RtpReceivers from PeerConnection.
This CL essentially converts [Local|Remote]TrackHandler to
Rtp[Sender|Receiver], and adds a "SetTrack" method for RtpSender.
It also gets rid of MediaStreamHandler and MediaStreamHandlerContainer,
since these classes weren't really anything more than containers.
PeerConnection now manages the RtpSenders and RtpReceivers directly.
Review URL: https://codereview.webrtc.org/1351803002
Cr-Commit-Position: refs/heads/master@{#10100}
diff --git a/talk/app/webrtc/mediastreamhandler.cc b/talk/app/webrtc/mediastreamhandler.cc
index ded603b..be493f1 100644
--- a/talk/app/webrtc/mediastreamhandler.cc
+++ b/talk/app/webrtc/mediastreamhandler.cc
@@ -25,462 +25,5 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "talk/app/webrtc/mediastreamhandler.h"
-
-#include "talk/app/webrtc/localaudiosource.h"
-#include "talk/app/webrtc/videosource.h"
-#include "talk/app/webrtc/videosourceinterface.h"
-
-namespace webrtc {
-
-TrackHandler::TrackHandler(MediaStreamTrackInterface* track, uint32 ssrc)
- : track_(track),
- ssrc_(ssrc),
- state_(track->state()),
- enabled_(track->enabled()) {
- track_->RegisterObserver(this);
-}
-
-TrackHandler::~TrackHandler() {
- track_->UnregisterObserver(this);
-}
-
-void TrackHandler::OnChanged() {
- if (state_ != track_->state()) {
- state_ = track_->state();
- OnStateChanged();
- }
- if (enabled_ != track_->enabled()) {
- enabled_ = track_->enabled();
- OnEnabledChanged();
- }
-}
-
-LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(NULL) {}
-
-LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
- rtc::CritScope lock(&lock_);
- if (sink_)
- sink_->OnClose();
-}
-
-void LocalAudioSinkAdapter::OnData(const void* audio_data,
- int bits_per_sample,
- int sample_rate,
- int number_of_channels,
- size_t number_of_frames) {
- rtc::CritScope lock(&lock_);
- if (sink_) {
- sink_->OnData(audio_data, bits_per_sample, sample_rate,
- number_of_channels, number_of_frames);
- }
-}
-
-void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) {
- rtc::CritScope lock(&lock_);
- ASSERT(!sink || !sink_);
- sink_ = sink;
-}
-
-LocalAudioTrackHandler::LocalAudioTrackHandler(
- AudioTrackInterface* track,
- uint32 ssrc,
- AudioProviderInterface* provider)
- : TrackHandler(track, ssrc),
- audio_track_(track),
- provider_(provider),
- sink_adapter_(new LocalAudioSinkAdapter()) {
- OnEnabledChanged();
- track->AddSink(sink_adapter_.get());
-}
-
-LocalAudioTrackHandler::~LocalAudioTrackHandler() {
-}
-
-void LocalAudioTrackHandler::OnStateChanged() {
- // TODO(perkj): What should happen when the state change?
-}
-
-void LocalAudioTrackHandler::Stop() {
- audio_track_->RemoveSink(sink_adapter_.get());
- cricket::AudioOptions options;
- provider_->SetAudioSend(ssrc(), false, options, NULL);
-}
-
-void LocalAudioTrackHandler::OnEnabledChanged() {
- cricket::AudioOptions options;
- if (audio_track_->enabled() && audio_track_->GetSource()) {
- // TODO(xians): Remove this static_cast since we should be able to connect
- // a remote audio track to peer connection.
- options = static_cast<LocalAudioSource*>(
- audio_track_->GetSource())->options();
- }
-
- // Use the renderer if the audio track has one, otherwise use the sink
- // adapter owned by this class.
- cricket::AudioRenderer* renderer = audio_track_->GetRenderer() ?
- audio_track_->GetRenderer() : sink_adapter_.get();
- ASSERT(renderer != NULL);
- provider_->SetAudioSend(ssrc(), audio_track_->enabled(), options, renderer);
-}
-
-RemoteAudioTrackHandler::RemoteAudioTrackHandler(
- AudioTrackInterface* track,
- uint32 ssrc,
- AudioProviderInterface* provider)
- : TrackHandler(track, ssrc),
- audio_track_(track),
- provider_(provider) {
- track->GetSource()->RegisterAudioObserver(this);
- OnEnabledChanged();
-}
-
-RemoteAudioTrackHandler::~RemoteAudioTrackHandler() {
- audio_track_->GetSource()->UnregisterAudioObserver(this);
-}
-
-void RemoteAudioTrackHandler::Stop() {
- provider_->SetAudioPlayout(ssrc(), false, NULL);
-}
-
-void RemoteAudioTrackHandler::OnStateChanged() {
-}
-
-void RemoteAudioTrackHandler::OnEnabledChanged() {
- provider_->SetAudioPlayout(ssrc(), audio_track_->enabled(),
- audio_track_->GetRenderer());
-}
-
-void RemoteAudioTrackHandler::OnSetVolume(double volume) {
- // When the track is disabled, the volume of the source, which is the
- // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
- // setting the volume to the source when the track is disabled.
- if (audio_track_->enabled())
- provider_->SetAudioPlayoutVolume(ssrc(), volume);
-}
-
-LocalVideoTrackHandler::LocalVideoTrackHandler(
- VideoTrackInterface* track,
- uint32 ssrc,
- VideoProviderInterface* provider)
- : TrackHandler(track, ssrc),
- local_video_track_(track),
- provider_(provider) {
- VideoSourceInterface* source = local_video_track_->GetSource();
- if (source)
- provider_->SetCaptureDevice(ssrc, source->GetVideoCapturer());
- OnEnabledChanged();
-}
-
-LocalVideoTrackHandler::~LocalVideoTrackHandler() {
-}
-
-void LocalVideoTrackHandler::OnStateChanged() {
-}
-
-void LocalVideoTrackHandler::Stop() {
- provider_->SetCaptureDevice(ssrc(), NULL);
- provider_->SetVideoSend(ssrc(), false, NULL);
-}
-
-void LocalVideoTrackHandler::OnEnabledChanged() {
- const cricket::VideoOptions* options = NULL;
- VideoSourceInterface* source = local_video_track_->GetSource();
- if (local_video_track_->enabled() && source) {
- options = source->options();
- }
- provider_->SetVideoSend(ssrc(), local_video_track_->enabled(), options);
-}
-
-RemoteVideoTrackHandler::RemoteVideoTrackHandler(
- VideoTrackInterface* track,
- uint32 ssrc,
- VideoProviderInterface* provider)
- : TrackHandler(track, ssrc),
- remote_video_track_(track),
- provider_(provider) {
- OnEnabledChanged();
- provider_->SetVideoPlayout(ssrc, true,
- remote_video_track_->GetSource()->FrameInput());
-}
-
-RemoteVideoTrackHandler::~RemoteVideoTrackHandler() {
-}
-
-void RemoteVideoTrackHandler::Stop() {
- // Since cricket::VideoRenderer is not reference counted
- // we need to remove the renderer before we are deleted.
- provider_->SetVideoPlayout(ssrc(), false, NULL);
-}
-
-void RemoteVideoTrackHandler::OnStateChanged() {
-}
-
-void RemoteVideoTrackHandler::OnEnabledChanged() {
-}
-
-MediaStreamHandler::MediaStreamHandler(MediaStreamInterface* stream,
- AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider)
- : stream_(stream),
- audio_provider_(audio_provider),
- video_provider_(video_provider) {
-}
-
-MediaStreamHandler::~MediaStreamHandler() {
- for (TrackHandlers::iterator it = track_handlers_.begin();
- it != track_handlers_.end(); ++it) {
- delete *it;
- }
-}
-
-void MediaStreamHandler::RemoveTrack(MediaStreamTrackInterface* track) {
- for (TrackHandlers::iterator it = track_handlers_.begin();
- it != track_handlers_.end(); ++it) {
- if ((*it)->track() == track) {
- TrackHandler* track = *it;
- track->Stop();
- delete track;
- track_handlers_.erase(it);
- break;
- }
- }
-}
-
-TrackHandler* MediaStreamHandler::FindTrackHandler(
- MediaStreamTrackInterface* track) {
- TrackHandlers::iterator it = track_handlers_.begin();
- for (; it != track_handlers_.end(); ++it) {
- if ((*it)->track() == track) {
- return *it;
- break;
- }
- }
- return NULL;
-}
-
-MediaStreamInterface* MediaStreamHandler::stream() {
- return stream_.get();
-}
-
-void MediaStreamHandler::OnChanged() {
-}
-
-void MediaStreamHandler::Stop() {
- for (TrackHandlers::const_iterator it = track_handlers_.begin();
- it != track_handlers_.end(); ++it) {
- (*it)->Stop();
- }
-}
-
-LocalMediaStreamHandler::LocalMediaStreamHandler(
- MediaStreamInterface* stream,
- AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider)
- : MediaStreamHandler(stream, audio_provider, video_provider) {
-}
-
-LocalMediaStreamHandler::~LocalMediaStreamHandler() {
-}
-
-void LocalMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
- uint32 ssrc) {
- ASSERT(!FindTrackHandler(audio_track));
-
- TrackHandler* handler(new LocalAudioTrackHandler(audio_track, ssrc,
- audio_provider_));
- track_handlers_.push_back(handler);
-}
-
-void LocalMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
- uint32 ssrc) {
- ASSERT(!FindTrackHandler(video_track));
-
- TrackHandler* handler(new LocalVideoTrackHandler(video_track, ssrc,
- video_provider_));
- track_handlers_.push_back(handler);
-}
-
-RemoteMediaStreamHandler::RemoteMediaStreamHandler(
- MediaStreamInterface* stream,
- AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider)
- : MediaStreamHandler(stream, audio_provider, video_provider) {
-}
-
-RemoteMediaStreamHandler::~RemoteMediaStreamHandler() {
-}
-
-void RemoteMediaStreamHandler::AddAudioTrack(AudioTrackInterface* audio_track,
- uint32 ssrc) {
- ASSERT(!FindTrackHandler(audio_track));
- TrackHandler* handler(
- new RemoteAudioTrackHandler(audio_track, ssrc, audio_provider_));
- track_handlers_.push_back(handler);
-}
-
-void RemoteMediaStreamHandler::AddVideoTrack(VideoTrackInterface* video_track,
- uint32 ssrc) {
- ASSERT(!FindTrackHandler(video_track));
- TrackHandler* handler(
- new RemoteVideoTrackHandler(video_track, ssrc, video_provider_));
- track_handlers_.push_back(handler);
-}
-
-MediaStreamHandlerContainer::MediaStreamHandlerContainer(
- AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider)
- : audio_provider_(audio_provider),
- video_provider_(video_provider) {
-}
-
-MediaStreamHandlerContainer::~MediaStreamHandlerContainer() {
- ASSERT(remote_streams_handlers_.empty());
- ASSERT(local_streams_handlers_.empty());
-}
-
-void MediaStreamHandlerContainer::TearDown() {
- for (StreamHandlerList::iterator it = remote_streams_handlers_.begin();
- it != remote_streams_handlers_.end(); ++it) {
- (*it)->Stop();
- delete *it;
- }
- remote_streams_handlers_.clear();
- for (StreamHandlerList::iterator it = local_streams_handlers_.begin();
- it != local_streams_handlers_.end(); ++it) {
- (*it)->Stop();
- delete *it;
- }
- local_streams_handlers_.clear();
-}
-
-void MediaStreamHandlerContainer::RemoveRemoteStream(
- MediaStreamInterface* stream) {
- DeleteStreamHandler(&remote_streams_handlers_, stream);
-}
-
-void MediaStreamHandlerContainer::AddRemoteAudioTrack(
- MediaStreamInterface* stream,
- AudioTrackInterface* audio_track,
- uint32 ssrc) {
- MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
- stream);
- if (handler == NULL) {
- handler = CreateRemoteStreamHandler(stream);
- }
- handler->AddAudioTrack(audio_track, ssrc);
-}
-
-void MediaStreamHandlerContainer::AddRemoteVideoTrack(
- MediaStreamInterface* stream,
- VideoTrackInterface* video_track,
- uint32 ssrc) {
- MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
- stream);
- if (handler == NULL) {
- handler = CreateRemoteStreamHandler(stream);
- }
- handler->AddVideoTrack(video_track, ssrc);
-}
-
-void MediaStreamHandlerContainer::RemoveRemoteTrack(
- MediaStreamInterface* stream,
- MediaStreamTrackInterface* track) {
- MediaStreamHandler* handler = FindStreamHandler(remote_streams_handlers_,
- stream);
- if (!VERIFY(handler != NULL)) {
- LOG(LS_WARNING) << "Local MediaStreamHandler for stream with id "
- << stream->label() << "doesnt't exist.";
- return;
- }
- handler->RemoveTrack(track);
-}
-
-void MediaStreamHandlerContainer::RemoveLocalStream(
- MediaStreamInterface* stream) {
- DeleteStreamHandler(&local_streams_handlers_, stream);
-}
-
-void MediaStreamHandlerContainer::AddLocalAudioTrack(
- MediaStreamInterface* stream,
- AudioTrackInterface* audio_track,
- uint32 ssrc) {
- MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
- stream);
- if (handler == NULL) {
- handler = CreateLocalStreamHandler(stream);
- }
- handler->AddAudioTrack(audio_track, ssrc);
-}
-
-void MediaStreamHandlerContainer::AddLocalVideoTrack(
- MediaStreamInterface* stream,
- VideoTrackInterface* video_track,
- uint32 ssrc) {
- MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
- stream);
- if (handler == NULL) {
- handler = CreateLocalStreamHandler(stream);
- }
- handler->AddVideoTrack(video_track, ssrc);
-}
-
-void MediaStreamHandlerContainer::RemoveLocalTrack(
- MediaStreamInterface* stream,
- MediaStreamTrackInterface* track) {
- MediaStreamHandler* handler = FindStreamHandler(local_streams_handlers_,
- stream);
- if (!VERIFY(handler != NULL)) {
- LOG(LS_WARNING) << "Remote MediaStreamHandler for stream with id "
- << stream->label() << "doesnt't exist.";
- return;
- }
- handler->RemoveTrack(track);
-}
-
-MediaStreamHandler* MediaStreamHandlerContainer::CreateRemoteStreamHandler(
- MediaStreamInterface* stream) {
- ASSERT(!FindStreamHandler(remote_streams_handlers_, stream));
-
- RemoteMediaStreamHandler* handler =
- new RemoteMediaStreamHandler(stream, audio_provider_, video_provider_);
- remote_streams_handlers_.push_back(handler);
- return handler;
-}
-
-MediaStreamHandler* MediaStreamHandlerContainer::CreateLocalStreamHandler(
- MediaStreamInterface* stream) {
- ASSERT(!FindStreamHandler(local_streams_handlers_, stream));
-
- LocalMediaStreamHandler* handler =
- new LocalMediaStreamHandler(stream, audio_provider_, video_provider_);
- local_streams_handlers_.push_back(handler);
- return handler;
-}
-
-MediaStreamHandler* MediaStreamHandlerContainer::FindStreamHandler(
- const StreamHandlerList& handlers,
- MediaStreamInterface* stream) {
- StreamHandlerList::const_iterator it = handlers.begin();
- for (; it != handlers.end(); ++it) {
- if ((*it)->stream() == stream) {
- return *it;
- }
- }
- return NULL;
-}
-
-void MediaStreamHandlerContainer::DeleteStreamHandler(
- StreamHandlerList* streamhandlers, MediaStreamInterface* stream) {
- StreamHandlerList::iterator it = streamhandlers->begin();
- for (; it != streamhandlers->end(); ++it) {
- if ((*it)->stream() == stream) {
- (*it)->Stop();
- delete *it;
- streamhandlers->erase(it);
- break;
- }
- }
-}
-
-} // namespace webrtc
+// TODO(deadbeef): Remove this file once Chrome build files no longer reference
+// it.
diff --git a/talk/app/webrtc/mediastreamhandler.h b/talk/app/webrtc/mediastreamhandler.h
index 1782f26..be493f1 100644
--- a/talk/app/webrtc/mediastreamhandler.h
+++ b/talk/app/webrtc/mediastreamhandler.h
@@ -25,269 +25,5 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// This file contains classes for listening on changes on MediaStreams and
-// MediaTracks that are connected to a certain PeerConnection.
-// Example: If a user sets a rendererer on a remote video track the renderer is
-// connected to the appropriate remote video stream.
-
-#ifndef TALK_APP_WEBRTC_MEDIASTREAMHANDLER_H_
-#define TALK_APP_WEBRTC_MEDIASTREAMHANDLER_H_
-
-#include <list>
-#include <vector>
-
-#include "talk/app/webrtc/mediastreaminterface.h"
-#include "talk/app/webrtc/mediastreamprovider.h"
-#include "talk/app/webrtc/peerconnectioninterface.h"
-#include "talk/media/base/audiorenderer.h"
-#include "webrtc/base/thread.h"
-
-namespace webrtc {
-
-// TrackHandler listen to events on a MediaStreamTrackInterface that is
-// connected to a certain PeerConnection.
-class TrackHandler : public ObserverInterface {
- public:
- TrackHandler(MediaStreamTrackInterface* track, uint32 ssrc);
- virtual ~TrackHandler();
- virtual void OnChanged();
- // Stop using |track_| on this PeerConnection.
- virtual void Stop() = 0;
-
- MediaStreamTrackInterface* track() { return track_; }
- uint32 ssrc() const { return ssrc_; }
-
- protected:
- virtual void OnStateChanged() = 0;
- virtual void OnEnabledChanged() = 0;
-
- private:
- rtc::scoped_refptr<MediaStreamTrackInterface> track_;
- uint32 ssrc_;
- MediaStreamTrackInterface::TrackState state_;
- bool enabled_;
-};
-
-// LocalAudioSinkAdapter receives data callback as a sink to the local
-// AudioTrack, and passes the data to the sink of AudioRenderer.
-class LocalAudioSinkAdapter : public AudioTrackSinkInterface,
- public cricket::AudioRenderer {
- public:
- LocalAudioSinkAdapter();
- virtual ~LocalAudioSinkAdapter();
-
- private:
- // AudioSinkInterface implementation.
- void OnData(const void* audio_data,
- int bits_per_sample,
- int sample_rate,
- int number_of_channels,
- size_t number_of_frames) override;
-
- // cricket::AudioRenderer implementation.
- void SetSink(cricket::AudioRenderer::Sink* sink) override;
-
- cricket::AudioRenderer::Sink* sink_;
- // Critical section protecting |sink_|.
- rtc::CriticalSection lock_;
-};
-
-// LocalAudioTrackHandler listen to events on a local AudioTrack instance
-// connected to a PeerConnection and orders the |provider| to executes the
-// requested change.
-class LocalAudioTrackHandler : public TrackHandler {
- public:
- LocalAudioTrackHandler(AudioTrackInterface* track,
- uint32 ssrc,
- AudioProviderInterface* provider);
- virtual ~LocalAudioTrackHandler();
-
- void Stop() override;
-
- protected:
- void OnStateChanged() override;
- void OnEnabledChanged() override;
-
- private:
- AudioTrackInterface* audio_track_;
- AudioProviderInterface* provider_;
-
- // Used to pass the data callback from the |audio_track_| to the other
- // end of cricket::AudioRenderer.
- rtc::scoped_ptr<LocalAudioSinkAdapter> sink_adapter_;
-};
-
-// RemoteAudioTrackHandler listen to events on a remote AudioTrack instance
-// connected to a PeerConnection and orders the |provider| to executes the
-// requested change.
-class RemoteAudioTrackHandler : public AudioSourceInterface::AudioObserver,
- public TrackHandler {
- public:
- RemoteAudioTrackHandler(AudioTrackInterface* track,
- uint32 ssrc,
- AudioProviderInterface* provider);
- virtual ~RemoteAudioTrackHandler();
- void Stop() override;
-
- protected:
- void OnStateChanged() override;
- void OnEnabledChanged() override;
-
- private:
- // AudioSourceInterface::AudioObserver implementation.
- void OnSetVolume(double volume) override;
-
- AudioTrackInterface* audio_track_;
- AudioProviderInterface* provider_;
-};
-
-// LocalVideoTrackHandler listen to events on a local VideoTrack instance
-// connected to a PeerConnection and orders the |provider| to executes the
-// requested change.
-class LocalVideoTrackHandler : public TrackHandler {
- public:
- LocalVideoTrackHandler(VideoTrackInterface* track,
- uint32 ssrc,
- VideoProviderInterface* provider);
- virtual ~LocalVideoTrackHandler();
- void Stop() override;
-
- protected:
- void OnStateChanged() override;
- void OnEnabledChanged() override;
-
- private:
- VideoTrackInterface* local_video_track_;
- VideoProviderInterface* provider_;
-};
-
-// RemoteVideoTrackHandler listen to events on a remote VideoTrack instance
-// connected to a PeerConnection and orders the |provider| to execute
-// requested changes.
-class RemoteVideoTrackHandler : public TrackHandler {
- public:
- RemoteVideoTrackHandler(VideoTrackInterface* track,
- uint32 ssrc,
- VideoProviderInterface* provider);
- virtual ~RemoteVideoTrackHandler();
- void Stop() override;
-
- protected:
- void OnStateChanged() override;
- void OnEnabledChanged() override;
-
- private:
- VideoTrackInterface* remote_video_track_;
- VideoProviderInterface* provider_;
-};
-
-class MediaStreamHandler : public ObserverInterface {
- public:
- MediaStreamHandler(MediaStreamInterface* stream,
- AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider);
- ~MediaStreamHandler();
- MediaStreamInterface* stream();
- void Stop();
-
- virtual void AddAudioTrack(AudioTrackInterface* audio_track, uint32 ssrc) = 0;
- virtual void AddVideoTrack(VideoTrackInterface* video_track, uint32 ssrc) = 0;
-
- virtual void RemoveTrack(MediaStreamTrackInterface* track);
- void OnChanged() override;
-
- protected:
- TrackHandler* FindTrackHandler(MediaStreamTrackInterface* track);
- rtc::scoped_refptr<MediaStreamInterface> stream_;
- AudioProviderInterface* audio_provider_;
- VideoProviderInterface* video_provider_;
- typedef std::vector<TrackHandler*> TrackHandlers;
- TrackHandlers track_handlers_;
-};
-
-class LocalMediaStreamHandler : public MediaStreamHandler {
- public:
- LocalMediaStreamHandler(MediaStreamInterface* stream,
- AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider);
- ~LocalMediaStreamHandler();
-
- void AddAudioTrack(AudioTrackInterface* audio_track, uint32 ssrc) override;
- void AddVideoTrack(VideoTrackInterface* video_track, uint32 ssrc) override;
-};
-
-class RemoteMediaStreamHandler : public MediaStreamHandler {
- public:
- RemoteMediaStreamHandler(MediaStreamInterface* stream,
- AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider);
- ~RemoteMediaStreamHandler();
- void AddAudioTrack(AudioTrackInterface* audio_track, uint32 ssrc) override;
- void AddVideoTrack(VideoTrackInterface* video_track, uint32 ssrc) override;
-};
-
-// Container for MediaStreamHandlers of currently known local and remote
-// MediaStreams.
-class MediaStreamHandlerContainer {
- public:
- MediaStreamHandlerContainer(AudioProviderInterface* audio_provider,
- VideoProviderInterface* video_provider);
- ~MediaStreamHandlerContainer();
-
- // Notify all referenced objects that MediaStreamHandlerContainer will be
- // destroyed. This method must be called prior to the dtor and prior to the
- // |audio_provider| and |video_provider| is destroyed.
- void TearDown();
-
- // Remove all TrackHandlers for tracks in |stream| and make sure
- // the audio_provider and video_provider is notified that the tracks has been
- // removed.
- void RemoveRemoteStream(MediaStreamInterface* stream);
-
- // Create a RemoteAudioTrackHandler and associate |audio_track| with |ssrc|.
- void AddRemoteAudioTrack(MediaStreamInterface* stream,
- AudioTrackInterface* audio_track,
- uint32 ssrc);
- // Create a RemoteVideoTrackHandler and associate |video_track| with |ssrc|.
- void AddRemoteVideoTrack(MediaStreamInterface* stream,
- VideoTrackInterface* video_track,
- uint32 ssrc);
- // Remove the TrackHandler for |track|.
- void RemoveRemoteTrack(MediaStreamInterface* stream,
- MediaStreamTrackInterface* track);
-
- // Remove all TrackHandlers for tracks in |stream| and make sure
- // the audio_provider and video_provider is notified that the tracks has been
- // removed.
- void RemoveLocalStream(MediaStreamInterface* stream);
-
- // Create a LocalAudioTrackHandler and associate |audio_track| with |ssrc|.
- void AddLocalAudioTrack(MediaStreamInterface* stream,
- AudioTrackInterface* audio_track,
- uint32 ssrc);
- // Create a LocalVideoTrackHandler and associate |video_track| with |ssrc|.
- void AddLocalVideoTrack(MediaStreamInterface* stream,
- VideoTrackInterface* video_track,
- uint32 ssrc);
- // Remove the TrackHandler for |track|.
- void RemoveLocalTrack(MediaStreamInterface* stream,
- MediaStreamTrackInterface* track);
-
- private:
- typedef std::list<MediaStreamHandler*> StreamHandlerList;
- MediaStreamHandler* FindStreamHandler(const StreamHandlerList& handlers,
- MediaStreamInterface* stream);
- MediaStreamHandler* CreateRemoteStreamHandler(MediaStreamInterface* stream);
- MediaStreamHandler* CreateLocalStreamHandler(MediaStreamInterface* stream);
- void DeleteStreamHandler(StreamHandlerList* streamhandlers,
- MediaStreamInterface* stream);
-
- StreamHandlerList local_streams_handlers_;
- StreamHandlerList remote_streams_handlers_;
- AudioProviderInterface* audio_provider_;
- VideoProviderInterface* video_provider_;
-};
-
-} // namespace webrtc
-
-#endif // TALK_APP_WEBRTC_MEDIASTREAMHANDLER_H_
+// TODO(deadbeef): Remove this file once Chrome build files no longer reference
+// it.
diff --git a/talk/app/webrtc/mediastreamhandler_unittest.cc b/talk/app/webrtc/mediastreamhandler_unittest.cc
deleted file mode 100644
index 6246643..0000000
--- a/talk/app/webrtc/mediastreamhandler_unittest.cc
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * libjingle
- * Copyright 2012 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtc/mediastreamhandler.h"
-
-#include <string>
-
-#include "talk/app/webrtc/audiotrack.h"
-#include "talk/app/webrtc/mediastream.h"
-#include "talk/app/webrtc/remoteaudiosource.h"
-#include "talk/app/webrtc/streamcollection.h"
-#include "talk/app/webrtc/videosource.h"
-#include "talk/app/webrtc/videotrack.h"
-#include "talk/media/base/fakevideocapturer.h"
-#include "talk/media/base/mediachannel.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/base/gunit.h"
-
-using ::testing::_;
-using ::testing::Exactly;
-
-static const char kStreamLabel1[] = "local_stream_1";
-static const char kVideoTrackId[] = "video_1";
-static const char kAudioTrackId[] = "audio_1";
-static const uint32 kVideoSsrc = 98;
-static const uint32 kAudioSsrc = 99;
-
-namespace webrtc {
-
-// Helper class to test MediaStreamHandler.
-class MockAudioProvider : public AudioProviderInterface {
- public:
- virtual ~MockAudioProvider() {}
- MOCK_METHOD3(SetAudioPlayout, void(uint32 ssrc, bool enable,
- cricket::AudioRenderer* renderer));
- MOCK_METHOD4(SetAudioSend, void(uint32 ssrc, bool enable,
- const cricket::AudioOptions& options,
- cricket::AudioRenderer* renderer));
- MOCK_METHOD2(SetAudioPlayoutVolume, void(uint32 ssrc, double volume));
-};
-
-// Helper class to test MediaStreamHandler.
-class MockVideoProvider : public VideoProviderInterface {
- public:
- virtual ~MockVideoProvider() {}
- MOCK_METHOD2(SetCaptureDevice, bool(uint32 ssrc,
- cricket::VideoCapturer* camera));
- MOCK_METHOD3(SetVideoPlayout, void(uint32 ssrc,
- bool enable,
- cricket::VideoRenderer* renderer));
- MOCK_METHOD3(SetVideoSend, void(uint32 ssrc, bool enable,
- const cricket::VideoOptions* options));
-};
-
-class FakeVideoSource : public Notifier<VideoSourceInterface> {
- public:
- static rtc::scoped_refptr<FakeVideoSource> Create() {
- return new rtc::RefCountedObject<FakeVideoSource>();
- }
- virtual cricket::VideoCapturer* GetVideoCapturer() {
- return &fake_capturer_;
- }
- virtual void Stop() {}
- virtual void Restart() {}
- virtual void AddSink(cricket::VideoRenderer* output) {}
- virtual void RemoveSink(cricket::VideoRenderer* output) {}
- virtual SourceState state() const { return state_; }
- virtual const cricket::VideoOptions* options() const { return &options_; }
- virtual cricket::VideoRenderer* FrameInput() { return NULL; }
-
- protected:
- FakeVideoSource() : state_(kLive) {}
- ~FakeVideoSource() {}
-
- private:
- cricket::FakeVideoCapturer fake_capturer_;
- SourceState state_;
- cricket::VideoOptions options_;
-};
-
-class MediaStreamHandlerTest : public testing::Test {
- public:
- MediaStreamHandlerTest()
- : handlers_(&audio_provider_, &video_provider_) {
- }
-
- virtual void SetUp() {
- stream_ = MediaStream::Create(kStreamLabel1);
- rtc::scoped_refptr<VideoSourceInterface> source(
- FakeVideoSource::Create());
- video_track_ = VideoTrack::Create(kVideoTrackId, source);
- EXPECT_TRUE(stream_->AddTrack(video_track_));
- }
-
- void AddLocalAudioTrack() {
- audio_track_ = AudioTrack::Create(kAudioTrackId, NULL);
- EXPECT_TRUE(stream_->AddTrack(audio_track_));
- EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, true, _, _));
- handlers_.AddLocalAudioTrack(stream_, stream_->GetAudioTracks()[0],
- kAudioSsrc);
- }
-
- void AddLocalVideoTrack() {
- EXPECT_CALL(video_provider_, SetCaptureDevice(
- kVideoSsrc, video_track_->GetSource()->GetVideoCapturer()));
- EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, true, _));
- handlers_.AddLocalVideoTrack(stream_, stream_->GetVideoTracks()[0],
- kVideoSsrc);
- }
-
- void RemoveLocalAudioTrack() {
- EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, false, _, _))
- .Times(1);
- handlers_.RemoveLocalTrack(stream_, audio_track_);
- }
-
- void RemoveLocalVideoTrack() {
- EXPECT_CALL(video_provider_, SetCaptureDevice(kVideoSsrc, NULL))
- .Times(1);
- EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, false, _))
- .Times(1);
- handlers_.RemoveLocalTrack(stream_, video_track_);
- }
-
- void AddRemoteAudioTrack() {
- audio_track_ = AudioTrack::Create(kAudioTrackId,
- RemoteAudioSource::Create().get());
- EXPECT_TRUE(stream_->AddTrack(audio_track_));
- EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
- handlers_.AddRemoteAudioTrack(stream_, stream_->GetAudioTracks()[0],
- kAudioSsrc);
- }
-
- void AddRemoteVideoTrack() {
- EXPECT_CALL(video_provider_, SetVideoPlayout(
- kVideoSsrc, true, video_track_->GetSource()->FrameInput()));
- handlers_.AddRemoteVideoTrack(stream_, stream_->GetVideoTracks()[0],
- kVideoSsrc);
- }
-
- void RemoveRemoteAudioTrack() {
- EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _));
- handlers_.RemoveRemoteTrack(stream_, stream_->GetAudioTracks()[0]);
- }
-
- void RemoveRemoteVideoTrack() {
- EXPECT_CALL(video_provider_, SetVideoPlayout(kVideoSsrc, false, NULL));
- handlers_.RemoveRemoteTrack(stream_, stream_->GetVideoTracks()[0]);
- }
-
- protected:
- MockAudioProvider audio_provider_;
- MockVideoProvider video_provider_;
- MediaStreamHandlerContainer handlers_;
- rtc::scoped_refptr<MediaStreamInterface> stream_;
- rtc::scoped_refptr<VideoTrackInterface> video_track_;
- rtc::scoped_refptr<AudioTrackInterface> audio_track_;
-};
-
-// Test that |audio_provider_| is notified when an audio track is associated
-// and disassociated with a MediaStreamHandler.
-TEST_F(MediaStreamHandlerTest, AddAndRemoveLocalAudioTrack) {
- AddLocalAudioTrack();
- RemoveLocalAudioTrack();
-
- handlers_.RemoveLocalStream(stream_);
-}
-
-// Test that |video_provider_| is notified when a video track is associated and
-// disassociated with a MediaStreamHandler.
-TEST_F(MediaStreamHandlerTest, AddAndRemoveLocalVideoTrack) {
- AddLocalVideoTrack();
- RemoveLocalVideoTrack();
-
- handlers_.RemoveLocalStream(stream_);
-}
-
-// Test that |video_provider_| and |audio_provider_| is notified when an audio
-// and video track is disassociated with a MediaStreamHandler by calling
-// RemoveLocalStream.
-TEST_F(MediaStreamHandlerTest, RemoveLocalStream) {
- AddLocalAudioTrack();
- AddLocalVideoTrack();
-
- EXPECT_CALL(video_provider_, SetCaptureDevice(kVideoSsrc, NULL))
- .Times(1);
- EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, false, _))
- .Times(1);
- EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, false, _, _))
- .Times(1);
- handlers_.RemoveLocalStream(stream_);
-}
-
-
-// Test that |audio_provider_| is notified when a remote audio and track is
-// associated and disassociated with a MediaStreamHandler.
-TEST_F(MediaStreamHandlerTest, AddAndRemoveRemoteAudioTrack) {
- AddRemoteAudioTrack();
- RemoveRemoteAudioTrack();
-
- handlers_.RemoveRemoteStream(stream_);
-}
-
-// Test that |video_provider_| is notified when a remote
-// video track is associated and disassociated with a MediaStreamHandler.
-TEST_F(MediaStreamHandlerTest, AddAndRemoveRemoteVideoTrack) {
- AddRemoteVideoTrack();
- RemoveRemoteVideoTrack();
-
- handlers_.RemoveRemoteStream(stream_);
-}
-
-// Test that |audio_provider_| and |video_provider_| is notified when an audio
-// and video track is disassociated with a MediaStreamHandler by calling
-// RemoveRemoveStream.
-TEST_F(MediaStreamHandlerTest, RemoveRemoteStream) {
- AddRemoteAudioTrack();
- AddRemoteVideoTrack();
-
- EXPECT_CALL(video_provider_, SetVideoPlayout(kVideoSsrc, false, NULL))
- .Times(1);
- EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _))
- .Times(1);
- handlers_.RemoveRemoteStream(stream_);
-}
-
-TEST_F(MediaStreamHandlerTest, LocalAudioTrackDisable) {
- AddLocalAudioTrack();
-
- EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, false, _, _));
- audio_track_->set_enabled(false);
-
- EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, true, _, _));
- audio_track_->set_enabled(true);
-
- RemoveLocalAudioTrack();
- handlers_.TearDown();
-}
-
-TEST_F(MediaStreamHandlerTest, RemoteAudioTrackDisable) {
- AddRemoteAudioTrack();
-
- EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _));
- audio_track_->set_enabled(false);
-
- EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
- audio_track_->set_enabled(true);
-
- RemoveRemoteAudioTrack();
- handlers_.TearDown();
-}
-
-TEST_F(MediaStreamHandlerTest, LocalVideoTrackDisable) {
- AddLocalVideoTrack();
-
- EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, false, _));
- video_track_->set_enabled(false);
-
- EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, true, _));
- video_track_->set_enabled(true);
-
- RemoveLocalVideoTrack();
- handlers_.TearDown();
-}
-
-TEST_F(MediaStreamHandlerTest, RemoteVideoTrackDisable) {
- AddRemoteVideoTrack();
-
- video_track_->set_enabled(false);
-
- video_track_->set_enabled(true);
-
- RemoveRemoteVideoTrack();
- handlers_.TearDown();
-}
-
-TEST_F(MediaStreamHandlerTest, RemoteAudioTrackSetVolume) {
- AddRemoteAudioTrack();
-
- double volume = 0.5;
- EXPECT_CALL(audio_provider_, SetAudioPlayoutVolume(kAudioSsrc, volume));
- audio_track_->GetSource()->SetVolume(volume);
-
- // Disable the audio track, this should prevent setting the volume.
- EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _));
- audio_track_->set_enabled(false);
- audio_track_->GetSource()->SetVolume(1.0);
-
- EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
- audio_track_->set_enabled(true);
-
- double new_volume = 0.8;
- EXPECT_CALL(audio_provider_, SetAudioPlayoutVolume(kAudioSsrc, new_volume));
- audio_track_->GetSource()->SetVolume(new_volume);
-
- RemoveRemoteAudioTrack();
- handlers_.TearDown();
-}
-
-} // namespace webrtc
diff --git a/talk/app/webrtc/mediastreamprovider.h b/talk/app/webrtc/mediastreamprovider.h
index e903fda..7e25b66 100644
--- a/talk/app/webrtc/mediastreamprovider.h
+++ b/talk/app/webrtc/mediastreamprovider.h
@@ -28,6 +28,8 @@
#ifndef TALK_APP_WEBRTC_MEDIASTREAMPROVIDER_H_
#define TALK_APP_WEBRTC_MEDIASTREAMPROVIDER_H_
+#include "webrtc/base/basictypes.h"
+
namespace cricket {
class AudioRenderer;
@@ -40,6 +42,14 @@
namespace webrtc {
+// TODO(deadbeef): Change the key from an ssrc to a "sender_id" or
+// "receiver_id" string, which will be the MSID in the short term and MID in
+// the long term.
+
+// TODO(deadbeef): These interfaces are effectively just a way for the
+// RtpSenders/Receivers to get to the BaseChannels. These interfaces should be
+// refactored away eventually, as the classes converge.
+
// This interface is called by AudioTrackHandler classes in mediastreamhandler.h
// to change the settings of an audio track connected to certain PeerConnection.
class AudioProviderInterface {
diff --git a/talk/app/webrtc/mediastreamsignaling.cc b/talk/app/webrtc/mediastreamsignaling.cc
index 1f5f14f..4f2615f 100644
--- a/talk/app/webrtc/mediastreamsignaling.cc
+++ b/talk/app/webrtc/mediastreamsignaling.cc
@@ -739,14 +739,14 @@
kDefaultAudioTrackLabel, 0));
OnRemoteTrackSeen(kDefaultStreamLabel, kDefaultAudioTrackLabel, 0,
- cricket::MEDIA_TYPE_AUDIO);
+ cricket::MEDIA_TYPE_AUDIO);
}
if (remote_info_.default_video_track_needed &&
default_remote_stream->GetVideoTracks().size() == 0) {
remote_video_tracks_.push_back(TrackInfo(kDefaultStreamLabel,
kDefaultVideoTrackLabel, 0));
OnRemoteTrackSeen(kDefaultStreamLabel, kDefaultVideoTrackLabel, 0,
- cricket::MEDIA_TYPE_VIDEO);
+ cricket::MEDIA_TYPE_VIDEO);
}
if (default_created) {
stream_observer_->OnAddRemoteStream(default_remote_stream);
@@ -807,17 +807,15 @@
track_id);
if (!track_info) {
current_tracks->push_back(TrackInfo(stream_label, track_id, ssrc));
- OnLocalTrackSeen(stream_label, track_id, it->first_ssrc(),
- media_type);
+ OnLocalTrackSeen(stream_label, track_id, it->first_ssrc(), media_type);
}
}
}
-void MediaStreamSignaling::OnLocalTrackSeen(
- const std::string& stream_label,
- const std::string& track_id,
- uint32 ssrc,
- cricket::MediaType media_type) {
+void MediaStreamSignaling::OnLocalTrackSeen(const std::string& stream_label,
+ const std::string& track_id,
+ uint32 ssrc,
+ cricket::MediaType media_type) {
MediaStreamInterface* stream = local_streams_->find(stream_label);
if (!stream) {
LOG(LS_WARNING) << "An unknown local MediaStream with label "
diff --git a/talk/app/webrtc/mediastreamsignaling.h b/talk/app/webrtc/mediastreamsignaling.h
index 87eede6..08f9cba 100644
--- a/talk/app/webrtc/mediastreamsignaling.h
+++ b/talk/app/webrtc/mediastreamsignaling.h
@@ -287,10 +287,7 @@
TrackInfo(const std::string& stream_label,
const std::string track_id,
uint32 ssrc)
- : stream_label(stream_label),
- track_id(track_id),
- ssrc(ssrc) {
- }
+ : stream_label(stream_label), track_id(track_id), ssrc(ssrc) {}
std::string stream_label;
std::string track_id;
uint32 ssrc;
diff --git a/talk/app/webrtc/mediastreamsignaling_unittest.cc b/talk/app/webrtc/mediastreamsignaling_unittest.cc
index 9bbad10..4f54df4 100644
--- a/talk/app/webrtc/mediastreamsignaling_unittest.cc
+++ b/talk/app/webrtc/mediastreamsignaling_unittest.cc
@@ -367,55 +367,53 @@
size_t NumberOfRemoteAudioTracks() { return remote_audio_tracks_.size(); }
- void VerifyRemoteAudioTrack(const std::string& stream_label,
- const std::string& track_id,
- uint32 ssrc) {
+ void VerifyRemoteAudioTrack(const std::string& stream_label,
+ const std::string& track_id,
+ uint32 ssrc) {
VerifyTrack(remote_audio_tracks_, stream_label, track_id, ssrc);
}
size_t NumberOfRemoteVideoTracks() { return remote_video_tracks_.size(); }
- void VerifyRemoteVideoTrack(const std::string& stream_label,
- const std::string& track_id,
- uint32 ssrc) {
+ void VerifyRemoteVideoTrack(const std::string& stream_label,
+ const std::string& track_id,
+ uint32 ssrc) {
VerifyTrack(remote_video_tracks_, stream_label, track_id, ssrc);
}
size_t NumberOfLocalAudioTracks() { return local_audio_tracks_.size(); }
- void VerifyLocalAudioTrack(const std::string& stream_label,
- const std::string& track_id,
- uint32 ssrc) {
+ void VerifyLocalAudioTrack(const std::string& stream_label,
+ const std::string& track_id,
+ uint32 ssrc) {
VerifyTrack(local_audio_tracks_, stream_label, track_id, ssrc);
}
size_t NumberOfLocalVideoTracks() { return local_video_tracks_.size(); }
- void VerifyLocalVideoTrack(const std::string& stream_label,
- const std::string& track_id,
- uint32 ssrc) {
+ void VerifyLocalVideoTrack(const std::string& stream_label,
+ const std::string& track_id,
+ uint32 ssrc) {
VerifyTrack(local_video_tracks_, stream_label, track_id, ssrc);
}
private:
struct TrackInfo {
TrackInfo() {}
- TrackInfo(const std::string& stream_label, const std::string track_id,
+ TrackInfo(const std::string& stream_label,
+ const std::string track_id,
uint32 ssrc)
- : stream_label(stream_label),
- track_id(track_id),
- ssrc(ssrc) {
- }
+ : stream_label(stream_label), track_id(track_id), ssrc(ssrc) {}
std::string stream_label;
std::string track_id;
uint32 ssrc;
};
typedef std::vector<TrackInfo> TrackInfos;
- void AddTrack(TrackInfos* track_infos, MediaStreamInterface* stream,
+ void AddTrack(TrackInfos* track_infos,
+ MediaStreamInterface* stream,
MediaStreamTrackInterface* track,
uint32 ssrc) {
- (*track_infos).push_back(TrackInfo(stream->label(), track->id(),
- ssrc));
+ (*track_infos).push_back(TrackInfo(stream->label(), track->id(), ssrc));
}
void RemoveTrack(TrackInfos* track_infos, MediaStreamInterface* stream,
@@ -441,7 +439,6 @@
return NULL;
}
-
void VerifyTrack(const TrackInfos& track_infos,
const std::string& stream_label,
const std::string& track_id,
diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc
index f934b61..961ba26 100644
--- a/talk/app/webrtc/peerconnection.cc
+++ b/talk/app/webrtc/peerconnection.cc
@@ -33,7 +33,8 @@
#include "talk/app/webrtc/jsepicecandidate.h"
#include "talk/app/webrtc/jsepsessiondescription.h"
#include "talk/app/webrtc/mediaconstraintsinterface.h"
-#include "talk/app/webrtc/mediastreamhandler.h"
+#include "talk/app/webrtc/rtpreceiver.h"
+#include "talk/app/webrtc/rtpsender.h"
#include "talk/app/webrtc/streamcollection.h"
#include "webrtc/p2p/client/basicportallocator.h"
#include "talk/session/media/channelmanager.h"
@@ -339,10 +340,17 @@
PeerConnection::~PeerConnection() {
ASSERT(signaling_thread()->IsCurrent());
- if (mediastream_signaling_)
+ if (mediastream_signaling_) {
mediastream_signaling_->TearDown();
- if (stream_handler_container_)
- stream_handler_container_->TearDown();
+ }
+ // Need to detach RTP senders/receivers from WebRtcSession,
+ // since it's about to be destroyed.
+ for (const auto& sender : senders_) {
+ sender->Stop();
+ }
+ for (const auto& receiver : receivers_) {
+ receiver->Stop();
+ }
}
bool PeerConnection::Initialize(
@@ -398,8 +406,6 @@
factory_->worker_thread(),
port_allocator_.get(),
mediastream_signaling_.get()));
- stream_handler_container_.reset(new MediaStreamHandlerContainer(
- session_.get(), session_.get()));
stats_.reset(new StatsCollector(session_.get()));
// Initialize the WebRtcSession. It creates transport channels etc.
@@ -424,6 +430,8 @@
return mediastream_signaling_->remote_streams();
}
+// TODO(deadbeef): Create RtpSenders immediately here, even if local
+// description hasn't yet been set.
bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
if (IsClosed()) {
return false;
@@ -468,6 +476,25 @@
return DtmfSenderProxy::Create(signaling_thread(), sender.get());
}
+std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
+ const {
+ std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders;
+ for (const auto& sender : senders_) {
+ senders.push_back(RtpSenderProxy::Create(signaling_thread(), sender.get()));
+ }
+ return senders;
+}
+
+std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
+PeerConnection::GetReceivers() const {
+ std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
+ for (const auto& receiver : receivers_) {
+ receivers.push_back(
+ RtpReceiverProxy::Create(signaling_thread(), receiver.get()));
+ }
+ return receivers;
+}
+
bool PeerConnection::GetStats(StatsObserver* observer,
MediaStreamTrackInterface* track,
StatsOutputLevel level) {
@@ -808,7 +835,6 @@
}
void PeerConnection::OnRemoveRemoteStream(MediaStreamInterface* stream) {
- stream_handler_container_->RemoveRemoteStream(stream);
observer_->OnRemoveStream(stream);
}
@@ -820,52 +846,87 @@
void PeerConnection::OnAddRemoteAudioTrack(MediaStreamInterface* stream,
AudioTrackInterface* audio_track,
uint32 ssrc) {
- stream_handler_container_->AddRemoteAudioTrack(stream, audio_track, ssrc);
+ receivers_.push_back(new AudioRtpReceiver(audio_track, ssrc, session_.get()));
}
void PeerConnection::OnAddRemoteVideoTrack(MediaStreamInterface* stream,
VideoTrackInterface* video_track,
uint32 ssrc) {
- stream_handler_container_->AddRemoteVideoTrack(stream, video_track, ssrc);
+ receivers_.push_back(new VideoRtpReceiver(video_track, ssrc, session_.get()));
}
+// TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote
+// description.
void PeerConnection::OnRemoveRemoteAudioTrack(
MediaStreamInterface* stream,
AudioTrackInterface* audio_track) {
- stream_handler_container_->RemoveRemoteTrack(stream, audio_track);
+ auto it = FindReceiverForTrack(audio_track);
+ if (it == receivers_.end()) {
+ LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id()
+ << " doesn't exist.";
+ } else {
+ (*it)->Stop();
+ receivers_.erase(it);
+ }
}
void PeerConnection::OnRemoveRemoteVideoTrack(
MediaStreamInterface* stream,
VideoTrackInterface* video_track) {
- stream_handler_container_->RemoveRemoteTrack(stream, video_track);
+ auto it = FindReceiverForTrack(video_track);
+ if (it == receivers_.end()) {
+ LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id()
+ << " doesn't exist.";
+ } else {
+ (*it)->Stop();
+ receivers_.erase(it);
+ }
}
+
void PeerConnection::OnAddLocalAudioTrack(MediaStreamInterface* stream,
AudioTrackInterface* audio_track,
uint32 ssrc) {
- stream_handler_container_->AddLocalAudioTrack(stream, audio_track, ssrc);
+ senders_.push_back(new AudioRtpSender(audio_track, ssrc, session_.get()));
stats_->AddLocalAudioTrack(audio_track, ssrc);
}
+
void PeerConnection::OnAddLocalVideoTrack(MediaStreamInterface* stream,
VideoTrackInterface* video_track,
uint32 ssrc) {
- stream_handler_container_->AddLocalVideoTrack(stream, video_track, ssrc);
+ senders_.push_back(new VideoRtpSender(video_track, ssrc, session_.get()));
}
+// TODO(deadbeef): Keep RtpSenders around even if track goes away in local
+// description.
void PeerConnection::OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
AudioTrackInterface* audio_track,
uint32 ssrc) {
- stream_handler_container_->RemoveLocalTrack(stream, audio_track);
+ auto it = FindSenderForTrack(audio_track);
+ if (it == senders_.end()) {
+ LOG(LS_WARNING) << "RtpSender for track with id " << audio_track->id()
+ << " doesn't exist.";
+ return;
+ } else {
+ (*it)->Stop();
+ senders_.erase(it);
+ }
stats_->RemoveLocalAudioTrack(audio_track, ssrc);
}
void PeerConnection::OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
VideoTrackInterface* video_track) {
- stream_handler_container_->RemoveLocalTrack(stream, video_track);
+ auto it = FindSenderForTrack(video_track);
+ if (it == senders_.end()) {
+ LOG(LS_WARNING) << "RtpSender for track with id " << video_track->id()
+ << " doesn't exist.";
+ return;
+ } else {
+ (*it)->Stop();
+ senders_.erase(it);
+ }
}
void PeerConnection::OnRemoveLocalStream(MediaStreamInterface* stream) {
- stream_handler_container_->RemoveLocalStream(stream);
}
void PeerConnection::OnIceConnectionChange(
@@ -920,4 +981,22 @@
observer_->OnStateChange(PeerConnectionObserver::kSignalingState);
}
+std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator
+PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) {
+ return std::find_if(
+ senders_.begin(), senders_.end(),
+ [track](const rtc::scoped_refptr<RtpSenderInterface>& sender) {
+ return sender->track() == track;
+ });
+}
+
+std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator
+PeerConnection::FindReceiverForTrack(MediaStreamTrackInterface* track) {
+ return std::find_if(
+ receivers_.begin(), receivers_.end(),
+ [track](const rtc::scoped_refptr<RtpReceiverInterface>& receiver) {
+ return receiver->track() == track;
+ });
+}
+
} // namespace webrtc
diff --git a/talk/app/webrtc/peerconnection.h b/talk/app/webrtc/peerconnection.h
index 2160afb..8caa821 100644
--- a/talk/app/webrtc/peerconnection.h
+++ b/talk/app/webrtc/peerconnection.h
@@ -34,20 +34,21 @@
#include "talk/app/webrtc/mediastreamsignaling.h"
#include "talk/app/webrtc/peerconnectionfactory.h"
#include "talk/app/webrtc/peerconnectioninterface.h"
+#include "talk/app/webrtc/rtpreceiverinterface.h"
+#include "talk/app/webrtc/rtpsenderinterface.h"
#include "talk/app/webrtc/statscollector.h"
#include "talk/app/webrtc/streamcollection.h"
#include "talk/app/webrtc/webrtcsession.h"
#include "webrtc/base/scoped_ptr.h"
namespace webrtc {
-class MediaStreamHandlerContainer;
typedef std::vector<PortAllocatorFactoryInterface::StunConfiguration>
StunConfigurations;
typedef std::vector<PortAllocatorFactoryInterface::TurnConfiguration>
TurnConfigurations;
-// PeerConnectionImpl implements the PeerConnection interface.
+// PeerConnection implements the PeerConnectionInterface interface.
// It uses MediaStreamSignaling and WebRtcSession to implement
// the PeerConnection functionality.
class PeerConnection : public PeerConnectionInterface,
@@ -72,6 +73,11 @@
virtual rtc::scoped_refptr<DtmfSenderInterface> CreateDtmfSender(
AudioTrackInterface* track);
+ std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
+ const override;
+ std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
+ const override;
+
virtual rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
const std::string& label,
const DataChannelInit* config);
@@ -168,6 +174,11 @@
return signaling_state_ == PeerConnectionInterface::kClosed;
}
+ std::vector<rtc::scoped_refptr<RtpSenderInterface>>::iterator
+ FindSenderForTrack(MediaStreamTrackInterface* track);
+ std::vector<rtc::scoped_refptr<RtpReceiverInterface>>::iterator
+ FindReceiverForTrack(MediaStreamTrackInterface* track);
+
// Storing the factory as a scoped reference pointer ensures that the memory
// in the PeerConnectionFactoryImpl remains available as long as the
// PeerConnection is running. It is passed to PeerConnection as a raw pointer.
@@ -186,8 +197,10 @@
rtc::scoped_ptr<cricket::PortAllocator> port_allocator_;
rtc::scoped_ptr<WebRtcSession> session_;
rtc::scoped_ptr<MediaStreamSignaling> mediastream_signaling_;
- rtc::scoped_ptr<MediaStreamHandlerContainer> stream_handler_container_;
rtc::scoped_ptr<StatsCollector> stats_;
+
+ std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders_;
+ std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers_;
};
} // namespace webrtc
diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h
index 2f33b41..734c2d0 100644
--- a/talk/app/webrtc/peerconnectioninterface.h
+++ b/talk/app/webrtc/peerconnectioninterface.h
@@ -77,6 +77,8 @@
#include "talk/app/webrtc/dtlsidentitystore.h"
#include "talk/app/webrtc/jsep.h"
#include "talk/app/webrtc/mediastreaminterface.h"
+#include "talk/app/webrtc/rtpreceiverinterface.h"
+#include "talk/app/webrtc/rtpsenderinterface.h"
#include "talk/app/webrtc/statstypes.h"
#include "talk/app/webrtc/umametrics.h"
#include "webrtc/base/fileutils.h"
@@ -329,6 +331,17 @@
virtual rtc::scoped_refptr<DtmfSenderInterface> CreateDtmfSender(
AudioTrackInterface* track) = 0;
+ // TODO(deadbeef): Make these pure virtual once all subclasses implement them.
+ virtual std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
+ const {
+ return std::vector<rtc::scoped_refptr<RtpSenderInterface>>();
+ }
+
+ virtual std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
+ const {
+ return std::vector<rtc::scoped_refptr<RtpReceiverInterface>>();
+ }
+
virtual bool GetStats(StatsObserver* observer,
MediaStreamTrackInterface* track,
StatsOutputLevel level) = 0;
diff --git a/talk/app/webrtc/peerconnectionproxy.h b/talk/app/webrtc/peerconnectionproxy.h
index 2f015cdf..d9af8d9 100644
--- a/talk/app/webrtc/peerconnectionproxy.h
+++ b/talk/app/webrtc/peerconnectionproxy.h
@@ -43,6 +43,10 @@
PROXY_METHOD1(void, RemoveStream, MediaStreamInterface*)
PROXY_METHOD1(rtc::scoped_refptr<DtmfSenderInterface>,
CreateDtmfSender, AudioTrackInterface*)
+ PROXY_CONSTMETHOD0(std::vector<rtc::scoped_refptr<RtpSenderInterface>>,
+ GetSenders)
+ PROXY_CONSTMETHOD0(std::vector<rtc::scoped_refptr<RtpReceiverInterface>>,
+ GetReceivers)
PROXY_METHOD3(bool, GetStats, StatsObserver*,
MediaStreamTrackInterface*,
StatsOutputLevel)
diff --git a/talk/app/webrtc/rtpreceiver.cc b/talk/app/webrtc/rtpreceiver.cc
index 39b669f..b8eca30 100644
--- a/talk/app/webrtc/rtpreceiver.cc
+++ b/talk/app/webrtc/rtpreceiver.cc
@@ -27,4 +27,80 @@
#include "talk/app/webrtc/rtpreceiver.h"
-// This file is currently stubbed so that Chromium's build files can be updated.
+#include "talk/app/webrtc/videosourceinterface.h"
+
+namespace webrtc {
+
+AudioRtpReceiver::AudioRtpReceiver(AudioTrackInterface* track,
+ uint32 ssrc,
+ AudioProviderInterface* provider)
+ : id_(track->id()),
+ track_(track),
+ ssrc_(ssrc),
+ provider_(provider),
+ cached_track_enabled_(track->enabled()) {
+ track_->RegisterObserver(this);
+ track_->GetSource()->RegisterAudioObserver(this);
+ Reconfigure();
+}
+
+AudioRtpReceiver::~AudioRtpReceiver() {
+ track_->GetSource()->UnregisterAudioObserver(this);
+ track_->UnregisterObserver(this);
+ Stop();
+}
+
+void AudioRtpReceiver::OnChanged() {
+ if (cached_track_enabled_ != track_->enabled()) {
+ cached_track_enabled_ = track_->enabled();
+ Reconfigure();
+ }
+}
+
+void AudioRtpReceiver::OnSetVolume(double volume) {
+ // When the track is disabled, the volume of the source, which is the
+ // corresponding WebRtc Voice Engine channel will be 0. So we do not allow
+ // setting the volume to the source when the track is disabled.
+ if (provider_ && track_->enabled())
+ provider_->SetAudioPlayoutVolume(ssrc_, volume);
+}
+
+void AudioRtpReceiver::Stop() {
+ // TODO(deadbeef): Need to do more here to fully stop receiving packets.
+ if (!provider_) {
+ return;
+ }
+ provider_->SetAudioPlayout(ssrc_, false, nullptr);
+ provider_ = nullptr;
+}
+
+void AudioRtpReceiver::Reconfigure() {
+ if (!provider_) {
+ return;
+ }
+ provider_->SetAudioPlayout(ssrc_, track_->enabled(), track_->GetRenderer());
+}
+
+VideoRtpReceiver::VideoRtpReceiver(VideoTrackInterface* track,
+ uint32 ssrc,
+ VideoProviderInterface* provider)
+ : id_(track->id()), track_(track), ssrc_(ssrc), provider_(provider) {
+ provider_->SetVideoPlayout(ssrc_, true, track_->GetSource()->FrameInput());
+}
+
+VideoRtpReceiver::~VideoRtpReceiver() {
+ // Since cricket::VideoRenderer is not reference counted,
+ // we need to remove it from the provider before we are deleted.
+ Stop();
+}
+
+void VideoRtpReceiver::Stop() {
+ // TODO(deadbeef): Need to do more here to fully stop receiving packets.
+ if (!provider_) {
+ return;
+ }
+ provider_->SetVideoPlayout(ssrc_, false, nullptr);
+ provider_ = nullptr;
+}
+
+} // namespace webrtc
diff --git a/talk/app/webrtc/rtpreceiver.h b/talk/app/webrtc/rtpreceiver.h
index aee77e1..f5bcb2e 100644
--- a/talk/app/webrtc/rtpreceiver.h
+++ b/talk/app/webrtc/rtpreceiver.h
@@ -25,4 +25,80 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// This file is currently stubbed so that Chromium's build files can be updated.
+// This file contains classes that implement RtpReceiverInterface.
+// An RtpReceiver associates a MediaStreamTrackInterface with an underlying
+// transport (provided by AudioProviderInterface/VideoProviderInterface)
+
+#ifndef TALK_APP_WEBRTC_RTPRECEIVER_H_
+#define TALK_APP_WEBRTC_RTPRECEIVER_H_
+
+#include <string>
+
+#include "talk/app/webrtc/mediastreamprovider.h"
+#include "talk/app/webrtc/rtpreceiverinterface.h"
+#include "webrtc/base/basictypes.h"
+
+namespace webrtc {
+
+class AudioRtpReceiver : public ObserverInterface,
+ public AudioSourceInterface::AudioObserver,
+ public rtc::RefCountedObject<RtpReceiverInterface> {
+ public:
+ AudioRtpReceiver(AudioTrackInterface* track,
+ uint32 ssrc,
+ AudioProviderInterface* provider);
+
+ virtual ~AudioRtpReceiver();
+
+ // ObserverInterface implementation
+ void OnChanged() override;
+
+ // AudioSourceInterface::AudioObserver implementation
+ void OnSetVolume(double volume) override;
+
+ // RtpReceiverInterface implementation
+ rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
+ return track_.get();
+ }
+
+ std::string id() const override { return id_; }
+
+ void Stop() override;
+
+ private:
+ void Reconfigure();
+
+ std::string id_;
+ rtc::scoped_refptr<AudioTrackInterface> track_;
+ uint32 ssrc_;
+ AudioProviderInterface* provider_;
+ bool cached_track_enabled_;
+};
+
+class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInterface> {
+ public:
+ VideoRtpReceiver(VideoTrackInterface* track,
+ uint32 ssrc,
+ VideoProviderInterface* provider);
+
+ virtual ~VideoRtpReceiver();
+
+ // RtpReceiverInterface implementation
+ rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
+ return track_.get();
+ }
+
+ std::string id() const override { return id_; }
+
+ void Stop() override;
+
+ private:
+ std::string id_;
+ rtc::scoped_refptr<VideoTrackInterface> track_;
+ uint32 ssrc_;
+ VideoProviderInterface* provider_;
+};
+
+} // namespace webrtc
+
+#endif // TALK_APP_WEBRTC_RTPRECEIVER_H_
diff --git a/talk/app/webrtc/rtpreceiverinterface.h b/talk/app/webrtc/rtpreceiverinterface.h
index aee77e1..099699e 100644
--- a/talk/app/webrtc/rtpreceiverinterface.h
+++ b/talk/app/webrtc/rtpreceiverinterface.h
@@ -25,4 +25,42 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// This file is currently stubbed so that Chromium's build files can be updated.
+// This file contains interfaces for RtpReceivers
+// http://w3c.github.io/webrtc-pc/#rtcrtpreceiver-interface
+
+#ifndef TALK_APP_WEBRTC_RTPRECEIVERINTERFACE_H_
+#define TALK_APP_WEBRTC_RTPRECEIVERINTERFACE_H_
+
+#include <string>
+
+#include "talk/app/webrtc/proxy.h"
+#include "talk/app/webrtc/mediastreaminterface.h"
+#include "webrtc/base/refcount.h"
+#include "webrtc/base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+class RtpReceiverInterface : public rtc::RefCountInterface {
+ public:
+ virtual rtc::scoped_refptr<MediaStreamTrackInterface> track() const = 0;
+
+ // Not to be confused with "mid", this is a field we can temporarily use
+ // to uniquely identify a receiver until we implement Unified Plan SDP.
+ virtual std::string id() const = 0;
+
+ virtual void Stop() = 0;
+
+ protected:
+ virtual ~RtpReceiverInterface() {}
+};
+
+// Define proxy for RtpReceiverInterface.
+BEGIN_PROXY_MAP(RtpReceiver)
+PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, track)
+PROXY_CONSTMETHOD0(std::string, id)
+PROXY_METHOD0(void, Stop)
+END_PROXY()
+
+} // namespace webrtc
+
+#endif // TALK_APP_WEBRTC_RTPRECEIVERINTERFACE_H_
diff --git a/talk/app/webrtc/rtpsender.cc b/talk/app/webrtc/rtpsender.cc
index 3049222..28ba073 100644
--- a/talk/app/webrtc/rtpsender.cc
+++ b/talk/app/webrtc/rtpsender.cc
@@ -27,4 +27,181 @@
#include "talk/app/webrtc/rtpsender.h"
-// This file is currently stubbed so that Chromium's build files can be updated.
+#include "talk/app/webrtc/localaudiosource.h"
+#include "talk/app/webrtc/videosourceinterface.h"
+
+namespace webrtc {
+
+LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
+
+LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
+ rtc::CritScope lock(&lock_);
+ if (sink_)
+ sink_->OnClose();
+}
+
+void LocalAudioSinkAdapter::OnData(const void* audio_data,
+ int bits_per_sample,
+ int sample_rate,
+ int number_of_channels,
+ size_t number_of_frames) {
+ rtc::CritScope lock(&lock_);
+ if (sink_) {
+ sink_->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
+ number_of_frames);
+ }
+}
+
+void LocalAudioSinkAdapter::SetSink(cricket::AudioRenderer::Sink* sink) {
+ rtc::CritScope lock(&lock_);
+ ASSERT(!sink || !sink_);
+ sink_ = sink;
+}
+
+AudioRtpSender::AudioRtpSender(AudioTrackInterface* track,
+ uint32 ssrc,
+ AudioProviderInterface* provider)
+ : id_(track->id()),
+ track_(track),
+ ssrc_(ssrc),
+ provider_(provider),
+ cached_track_enabled_(track->enabled()),
+ sink_adapter_(new LocalAudioSinkAdapter()) {
+ track_->RegisterObserver(this);
+ track_->AddSink(sink_adapter_.get());
+ Reconfigure();
+}
+
+AudioRtpSender::~AudioRtpSender() {
+ track_->RemoveSink(sink_adapter_.get());
+ track_->UnregisterObserver(this);
+ Stop();
+}
+
+void AudioRtpSender::OnChanged() {
+ if (cached_track_enabled_ != track_->enabled()) {
+ cached_track_enabled_ = track_->enabled();
+ Reconfigure();
+ }
+}
+
+bool AudioRtpSender::SetTrack(MediaStreamTrackInterface* track) {
+ if (track->kind() != "audio") {
+ LOG(LS_ERROR) << "SetTrack called on audio RtpSender with " << track->kind()
+ << " track.";
+ return false;
+ }
+ AudioTrackInterface* audio_track = static_cast<AudioTrackInterface*>(track);
+
+ // Detach from old track.
+ track_->RemoveSink(sink_adapter_.get());
+ track_->UnregisterObserver(this);
+
+ // Attach to new track.
+ track_ = audio_track;
+ cached_track_enabled_ = track_->enabled();
+ track_->RegisterObserver(this);
+ track_->AddSink(sink_adapter_.get());
+ Reconfigure();
+ return true;
+}
+
+void AudioRtpSender::Stop() {
+ // TODO(deadbeef): Need to do more here to fully stop sending packets.
+ if (!provider_) {
+ return;
+ }
+ cricket::AudioOptions options;
+ provider_->SetAudioSend(ssrc_, false, options, nullptr);
+ provider_ = nullptr;
+}
+
+void AudioRtpSender::Reconfigure() {
+ if (!provider_) {
+ return;
+ }
+ cricket::AudioOptions options;
+ if (track_->enabled() && track_->GetSource()) {
+ // TODO(xians): Remove this static_cast since we should be able to connect
+ // a remote audio track to peer connection.
+ options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
+ }
+
+ // Use the renderer if the audio track has one, otherwise use the sink
+ // adapter owned by this class.
+ cricket::AudioRenderer* renderer =
+ track_->GetRenderer() ? track_->GetRenderer() : sink_adapter_.get();
+ ASSERT(renderer != nullptr);
+ provider_->SetAudioSend(ssrc_, track_->enabled(), options, renderer);
+}
+
+VideoRtpSender::VideoRtpSender(VideoTrackInterface* track,
+ uint32 ssrc,
+ VideoProviderInterface* provider)
+ : id_(track->id()),
+ track_(track),
+ ssrc_(ssrc),
+ provider_(provider),
+ cached_track_enabled_(track->enabled()) {
+ track_->RegisterObserver(this);
+ VideoSourceInterface* source = track_->GetSource();
+ if (source) {
+ provider_->SetCaptureDevice(ssrc_, source->GetVideoCapturer());
+ }
+ Reconfigure();
+}
+
+VideoRtpSender::~VideoRtpSender() {
+ track_->UnregisterObserver(this);
+ Stop();
+}
+
+void VideoRtpSender::OnChanged() {
+ if (cached_track_enabled_ != track_->enabled()) {
+ cached_track_enabled_ = track_->enabled();
+ Reconfigure();
+ }
+}
+
+bool VideoRtpSender::SetTrack(MediaStreamTrackInterface* track) {
+ if (track->kind() != "video") {
+ LOG(LS_ERROR) << "SetTrack called on video RtpSender with " << track->kind()
+ << " track.";
+ return false;
+ }
+ VideoTrackInterface* video_track = static_cast<VideoTrackInterface*>(track);
+
+ // Detach from old track.
+ track_->UnregisterObserver(this);
+
+ // Attach to new track.
+ track_ = video_track;
+ cached_track_enabled_ = track_->enabled();
+ track_->RegisterObserver(this);
+ Reconfigure();
+ return true;
+}
+
+void VideoRtpSender::Stop() {
+ // TODO(deadbeef): Need to do more here to fully stop sending packets.
+ if (!provider_) {
+ return;
+ }
+ provider_->SetCaptureDevice(ssrc_, nullptr);
+ provider_->SetVideoSend(ssrc_, false, nullptr);
+ provider_ = nullptr;
+}
+
+void VideoRtpSender::Reconfigure() {
+ if (!provider_) {
+ return;
+ }
+ const cricket::VideoOptions* options = nullptr;
+ VideoSourceInterface* source = track_->GetSource();
+ if (track_->enabled() && source) {
+ options = source->options();
+ }
+ provider_->SetVideoSend(ssrc_, track_->enabled(), options);
+}
+
+} // namespace webrtc
diff --git a/talk/app/webrtc/rtpsender.h b/talk/app/webrtc/rtpsender.h
index aee77e1..a0eae5d 100644
--- a/talk/app/webrtc/rtpsender.h
+++ b/talk/app/webrtc/rtpsender.h
@@ -25,4 +25,116 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// This file is currently stubbed so that Chromium's build files can be updated.
+// This file contains classes that implement RtpSenderInterface.
+// An RtpSender associates a MediaStreamTrackInterface with an underlying
+// transport (provided by AudioProviderInterface/VideoProviderInterface)
+
+#ifndef TALK_APP_WEBRTC_RTPSENDER_H_
+#define TALK_APP_WEBRTC_RTPSENDER_H_
+
+#include <string>
+
+#include "talk/app/webrtc/mediastreamprovider.h"
+#include "talk/app/webrtc/rtpsenderinterface.h"
+#include "talk/media/base/audiorenderer.h"
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/criticalsection.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace webrtc {
+
+// LocalAudioSinkAdapter receives data callback as a sink to the local
+// AudioTrack, and passes the data to the sink of AudioRenderer.
+class LocalAudioSinkAdapter : public AudioTrackSinkInterface,
+ public cricket::AudioRenderer {
+ public:
+ LocalAudioSinkAdapter();
+ virtual ~LocalAudioSinkAdapter();
+
+ private:
+ // AudioSinkInterface implementation.
+ void OnData(const void* audio_data,
+ int bits_per_sample,
+ int sample_rate,
+ int number_of_channels,
+ size_t number_of_frames) override;
+
+ // cricket::AudioRenderer implementation.
+ void SetSink(cricket::AudioRenderer::Sink* sink) override;
+
+ cricket::AudioRenderer::Sink* sink_;
+ // Critical section protecting |sink_|.
+ rtc::CriticalSection lock_;
+};
+
+class AudioRtpSender : public ObserverInterface,
+ public rtc::RefCountedObject<RtpSenderInterface> {
+ public:
+ AudioRtpSender(AudioTrackInterface* track,
+ uint32 ssrc,
+ AudioProviderInterface* provider);
+
+ virtual ~AudioRtpSender();
+
+ // ObserverInterface implementation
+ void OnChanged() override;
+
+ // RtpSenderInterface implementation
+ bool SetTrack(MediaStreamTrackInterface* track) override;
+ rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
+ return track_.get();
+ }
+
+ std::string id() const override { return id_; }
+
+ void Stop() override;
+
+ private:
+ void Reconfigure();
+
+ std::string id_;
+ rtc::scoped_refptr<AudioTrackInterface> track_;
+ uint32 ssrc_;
+ AudioProviderInterface* provider_;
+ bool cached_track_enabled_;
+
+ // Used to pass the data callback from the |track_| to the other end of
+ // cricket::AudioRenderer.
+ rtc::scoped_ptr<LocalAudioSinkAdapter> sink_adapter_;
+};
+
+class VideoRtpSender : public ObserverInterface,
+ public rtc::RefCountedObject<RtpSenderInterface> {
+ public:
+ VideoRtpSender(VideoTrackInterface* track,
+ uint32 ssrc,
+ VideoProviderInterface* provider);
+
+ virtual ~VideoRtpSender();
+
+ // ObserverInterface implementation
+ void OnChanged() override;
+
+ // RtpSenderInterface implementation
+ bool SetTrack(MediaStreamTrackInterface* track) override;
+ rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
+ return track_.get();
+ }
+
+ std::string id() const override { return id_; }
+
+ void Stop() override;
+
+ private:
+ void Reconfigure();
+
+ std::string id_;
+ rtc::scoped_refptr<VideoTrackInterface> track_;
+ uint32 ssrc_;
+ VideoProviderInterface* provider_;
+ bool cached_track_enabled_;
+};
+
+} // namespace webrtc
+
+#endif // TALK_APP_WEBRTC_RTPSENDER_H_
diff --git a/talk/app/webrtc/rtpsenderinterface.h b/talk/app/webrtc/rtpsenderinterface.h
index aee77e1..fca98f2 100644
--- a/talk/app/webrtc/rtpsenderinterface.h
+++ b/talk/app/webrtc/rtpsenderinterface.h
@@ -25,4 +25,46 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// This file is currently stubbed so that Chromium's build files can be updated.
+// This file contains interfaces for RtpSenders
+// http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface
+
+#ifndef TALK_APP_WEBRTC_RTPSENDERINTERFACE_H_
+#define TALK_APP_WEBRTC_RTPSENDERINTERFACE_H_
+
+#include <string>
+
+#include "talk/app/webrtc/proxy.h"
+#include "talk/app/webrtc/mediastreaminterface.h"
+#include "webrtc/base/refcount.h"
+#include "webrtc/base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+class RtpSenderInterface : public rtc::RefCountInterface {
+ public:
+ // Returns true if successful in setting the track.
+ // Fails if an audio track is set on a video RtpSender, or vice-versa.
+ virtual bool SetTrack(MediaStreamTrackInterface* track) = 0;
+ virtual rtc::scoped_refptr<MediaStreamTrackInterface> track() const = 0;
+
+ // Not to be confused with "mid", this is a field we can temporarily use
+ // to uniquely identify a receiver until we implement Unified Plan SDP.
+ virtual std::string id() const = 0;
+
+ virtual void Stop() = 0;
+
+ protected:
+ virtual ~RtpSenderInterface() {}
+};
+
+// Define proxy for RtpSenderInterface.
+BEGIN_PROXY_MAP(RtpSender)
+PROXY_METHOD1(bool, SetTrack, MediaStreamTrackInterface*)
+PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, track)
+PROXY_CONSTMETHOD0(std::string, id)
+PROXY_METHOD0(void, Stop)
+END_PROXY()
+
+} // namespace webrtc
+
+#endif // TALK_APP_WEBRTC_RTPSENDERINTERFACE_H_
diff --git a/talk/app/webrtc/rtpsenderreceiver_unittest.cc b/talk/app/webrtc/rtpsenderreceiver_unittest.cc
new file mode 100644
index 0000000..973b854
--- /dev/null
+++ b/talk/app/webrtc/rtpsenderreceiver_unittest.cc
@@ -0,0 +1,284 @@
+/*
+ * libjingle
+ * Copyright 2012 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+
+#include "talk/app/webrtc/audiotrack.h"
+#include "talk/app/webrtc/mediastream.h"
+#include "talk/app/webrtc/remoteaudiosource.h"
+#include "talk/app/webrtc/rtpreceiver.h"
+#include "talk/app/webrtc/rtpsender.h"
+#include "talk/app/webrtc/streamcollection.h"
+#include "talk/app/webrtc/videosource.h"
+#include "talk/app/webrtc/videotrack.h"
+#include "talk/media/base/fakevideocapturer.h"
+#include "talk/media/base/mediachannel.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/gunit.h"
+
+using ::testing::_;
+using ::testing::Exactly;
+
+static const char kStreamLabel1[] = "local_stream_1";
+static const char kVideoTrackId[] = "video_1";
+static const char kAudioTrackId[] = "audio_1";
+static const uint32 kVideoSsrc = 98;
+static const uint32 kAudioSsrc = 99;
+
+namespace webrtc {
+
+// Helper class to test RtpSender/RtpReceiver.
+class MockAudioProvider : public AudioProviderInterface {
+ public:
+ virtual ~MockAudioProvider() {}
+ MOCK_METHOD3(SetAudioPlayout,
+ void(uint32 ssrc,
+ bool enable,
+ cricket::AudioRenderer* renderer));
+ MOCK_METHOD4(SetAudioSend,
+ void(uint32 ssrc,
+ bool enable,
+ const cricket::AudioOptions& options,
+ cricket::AudioRenderer* renderer));
+ MOCK_METHOD2(SetAudioPlayoutVolume, void(uint32 ssrc, double volume));
+};
+
+// Helper class to test RtpSender/RtpReceiver.
+class MockVideoProvider : public VideoProviderInterface {
+ public:
+ virtual ~MockVideoProvider() {}
+ MOCK_METHOD2(SetCaptureDevice,
+ bool(uint32 ssrc, cricket::VideoCapturer* camera));
+ MOCK_METHOD3(SetVideoPlayout,
+ void(uint32 ssrc,
+ bool enable,
+ cricket::VideoRenderer* renderer));
+ MOCK_METHOD3(SetVideoSend,
+ void(uint32 ssrc,
+ bool enable,
+ const cricket::VideoOptions* options));
+};
+
+class FakeVideoSource : public Notifier<VideoSourceInterface> {
+ public:
+ static rtc::scoped_refptr<FakeVideoSource> Create() {
+ return new rtc::RefCountedObject<FakeVideoSource>();
+ }
+ virtual cricket::VideoCapturer* GetVideoCapturer() { return &fake_capturer_; }
+ virtual void Stop() {}
+ virtual void Restart() {}
+ virtual void AddSink(cricket::VideoRenderer* output) {}
+ virtual void RemoveSink(cricket::VideoRenderer* output) {}
+ virtual SourceState state() const { return state_; }
+ virtual const cricket::VideoOptions* options() const { return &options_; }
+ virtual cricket::VideoRenderer* FrameInput() { return NULL; }
+
+ protected:
+ FakeVideoSource() : state_(kLive) {}
+ ~FakeVideoSource() {}
+
+ private:
+ cricket::FakeVideoCapturer fake_capturer_;
+ SourceState state_;
+ cricket::VideoOptions options_;
+};
+
+class RtpSenderReceiverTest : public testing::Test {
+ public:
+ virtual void SetUp() {
+ stream_ = MediaStream::Create(kStreamLabel1);
+ rtc::scoped_refptr<VideoSourceInterface> source(FakeVideoSource::Create());
+ video_track_ = VideoTrack::Create(kVideoTrackId, source);
+ EXPECT_TRUE(stream_->AddTrack(video_track_));
+ }
+
+ void CreateAudioRtpSender() {
+ audio_track_ = AudioTrack::Create(kAudioTrackId, NULL);
+ EXPECT_TRUE(stream_->AddTrack(audio_track_));
+ EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, true, _, _));
+ audio_rtp_sender_ = new AudioRtpSender(stream_->GetAudioTracks()[0],
+ kAudioSsrc, &audio_provider_);
+ }
+
+ void CreateVideoRtpSender() {
+ EXPECT_CALL(video_provider_,
+ SetCaptureDevice(
+ kVideoSsrc, video_track_->GetSource()->GetVideoCapturer()));
+ EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, true, _));
+ video_rtp_sender_ = new VideoRtpSender(stream_->GetVideoTracks()[0],
+ kVideoSsrc, &video_provider_);
+ }
+
+ void DestroyAudioRtpSender() {
+ EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, false, _, _))
+ .Times(1);
+ audio_rtp_sender_ = nullptr;
+ }
+
+ void DestroyVideoRtpSender() {
+ EXPECT_CALL(video_provider_, SetCaptureDevice(kVideoSsrc, NULL)).Times(1);
+ EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, false, _)).Times(1);
+ video_rtp_sender_ = nullptr;
+ }
+
+ void CreateAudioRtpReceiver() {
+ audio_track_ =
+ AudioTrack::Create(kAudioTrackId, RemoteAudioSource::Create().get());
+ EXPECT_TRUE(stream_->AddTrack(audio_track_));
+ EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
+ audio_rtp_receiver_ = new AudioRtpReceiver(stream_->GetAudioTracks()[0],
+ kAudioSsrc, &audio_provider_);
+ }
+
+ void CreateVideoRtpReceiver() {
+ EXPECT_CALL(video_provider_,
+ SetVideoPlayout(kVideoSsrc, true,
+ video_track_->GetSource()->FrameInput()));
+ video_rtp_receiver_ = new VideoRtpReceiver(stream_->GetVideoTracks()[0],
+ kVideoSsrc, &video_provider_);
+ }
+
+ void DestroyAudioRtpReceiver() {
+ EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _));
+ audio_rtp_receiver_ = nullptr;
+ }
+
+ void DestroyVideoRtpReceiver() {
+ EXPECT_CALL(video_provider_, SetVideoPlayout(kVideoSsrc, false, NULL));
+ video_rtp_receiver_ = nullptr;
+ }
+
+ protected:
+ MockAudioProvider audio_provider_;
+ MockVideoProvider video_provider_;
+ rtc::scoped_refptr<AudioRtpSender> audio_rtp_sender_;
+ rtc::scoped_refptr<VideoRtpSender> video_rtp_sender_;
+ rtc::scoped_refptr<AudioRtpReceiver> audio_rtp_receiver_;
+ rtc::scoped_refptr<VideoRtpReceiver> video_rtp_receiver_;
+ rtc::scoped_refptr<MediaStreamInterface> stream_;
+ rtc::scoped_refptr<VideoTrackInterface> video_track_;
+ rtc::scoped_refptr<AudioTrackInterface> audio_track_;
+};
+
+// Test that |audio_provider_| is notified when an audio track is associated
+// and disassociated with an AudioRtpSender.
+TEST_F(RtpSenderReceiverTest, AddAndDestroyAudioRtpSender) {
+ CreateAudioRtpSender();
+ DestroyAudioRtpSender();
+}
+
+// Test that |video_provider_| is notified when a video track is associated and
+// disassociated with a VideoRtpSender.
+TEST_F(RtpSenderReceiverTest, AddAndDestroyVideoRtpSender) {
+ CreateVideoRtpSender();
+ DestroyVideoRtpSender();
+}
+
+// Test that |audio_provider_| is notified when a remote audio and track is
+// associated and disassociated with an AudioRtpReceiver.
+TEST_F(RtpSenderReceiverTest, AddAndDestroyAudioRtpReceiver) {
+ CreateAudioRtpReceiver();
+ DestroyAudioRtpReceiver();
+}
+
+// Test that |video_provider_| is notified when a remote
+// video track is associated and disassociated with a VideoRtpReceiver.
+TEST_F(RtpSenderReceiverTest, AddAndDestroyVideoRtpReceiver) {
+ CreateVideoRtpReceiver();
+ DestroyVideoRtpReceiver();
+}
+
+TEST_F(RtpSenderReceiverTest, LocalAudioTrackDisable) {
+ CreateAudioRtpSender();
+
+ EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, false, _, _));
+ audio_track_->set_enabled(false);
+
+ EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, true, _, _));
+ audio_track_->set_enabled(true);
+
+ DestroyAudioRtpSender();
+}
+
+TEST_F(RtpSenderReceiverTest, RemoteAudioTrackDisable) {
+ CreateAudioRtpReceiver();
+
+ EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _));
+ audio_track_->set_enabled(false);
+
+ EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
+ audio_track_->set_enabled(true);
+
+ DestroyAudioRtpReceiver();
+}
+
+TEST_F(RtpSenderReceiverTest, LocalVideoTrackDisable) {
+ CreateVideoRtpSender();
+
+ EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, false, _));
+ video_track_->set_enabled(false);
+
+ EXPECT_CALL(video_provider_, SetVideoSend(kVideoSsrc, true, _));
+ video_track_->set_enabled(true);
+
+ DestroyVideoRtpSender();
+}
+
+TEST_F(RtpSenderReceiverTest, RemoteVideoTrackDisable) {
+ CreateVideoRtpReceiver();
+
+ video_track_->set_enabled(false);
+
+ video_track_->set_enabled(true);
+
+ DestroyVideoRtpReceiver();
+}
+
+TEST_F(RtpSenderReceiverTest, RemoteAudioTrackSetVolume) {
+ CreateAudioRtpReceiver();
+
+ double volume = 0.5;
+ EXPECT_CALL(audio_provider_, SetAudioPlayoutVolume(kAudioSsrc, volume));
+ audio_track_->GetSource()->SetVolume(volume);
+
+ // Disable the audio track, this should prevent setting the volume.
+ EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, false, _));
+ audio_track_->set_enabled(false);
+ audio_track_->GetSource()->SetVolume(1.0);
+
+ EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true, _));
+ audio_track_->set_enabled(true);
+
+ double new_volume = 0.8;
+ EXPECT_CALL(audio_provider_, SetAudioPlayoutVolume(kAudioSsrc, new_volume));
+ audio_track_->GetSource()->SetVolume(new_volume);
+
+ DestroyAudioRtpReceiver();
+}
+
+} // namespace webrtc
diff --git a/talk/app/webrtc/test/fakemediastreamsignaling.h b/talk/app/webrtc/test/fakemediastreamsignaling.h
index 7e13d44..c98a24d 100644
--- a/talk/app/webrtc/test/fakemediastreamsignaling.h
+++ b/talk/app/webrtc/test/fakemediastreamsignaling.h
@@ -85,51 +85,34 @@
}
// Implements MediaStreamSignalingObserver.
- virtual void OnAddRemoteStream(webrtc::MediaStreamInterface* stream) {
- }
- virtual void OnRemoveRemoteStream(webrtc::MediaStreamInterface* stream) {
- }
- virtual void OnAddDataChannel(webrtc::DataChannelInterface* data_channel) {
- }
+ virtual void OnAddRemoteStream(webrtc::MediaStreamInterface* stream) {}
+ virtual void OnRemoveRemoteStream(webrtc::MediaStreamInterface* stream) {}
+ virtual void OnAddDataChannel(webrtc::DataChannelInterface* data_channel) {}
virtual void OnAddLocalAudioTrack(webrtc::MediaStreamInterface* stream,
webrtc::AudioTrackInterface* audio_track,
- uint32 ssrc) {
- }
+ uint32 ssrc) {}
virtual void OnAddLocalVideoTrack(webrtc::MediaStreamInterface* stream,
webrtc::VideoTrackInterface* video_track,
- uint32 ssrc) {
- }
+ uint32 ssrc) {}
virtual void OnAddRemoteAudioTrack(webrtc::MediaStreamInterface* stream,
webrtc::AudioTrackInterface* audio_track,
- uint32 ssrc) {
- }
-
+ uint32 ssrc) {}
virtual void OnAddRemoteVideoTrack(webrtc::MediaStreamInterface* stream,
webrtc::VideoTrackInterface* video_track,
- uint32 ssrc) {
- }
-
+ uint32 ssrc) {}
virtual void OnRemoveRemoteAudioTrack(
webrtc::MediaStreamInterface* stream,
- webrtc::AudioTrackInterface* audio_track) {
- }
-
+ webrtc::AudioTrackInterface* audio_track) {}
virtual void OnRemoveRemoteVideoTrack(
webrtc::MediaStreamInterface* stream,
- webrtc::VideoTrackInterface* video_track) {
- }
-
- virtual void OnRemoveLocalAudioTrack(
- webrtc::MediaStreamInterface* stream,
- webrtc::AudioTrackInterface* audio_track,
- uint32 ssrc) {
- }
+ webrtc::VideoTrackInterface* video_track) {}
+ virtual void OnRemoveLocalAudioTrack(webrtc::MediaStreamInterface* stream,
+ webrtc::AudioTrackInterface* audio_track,
+ uint32 ssrc) {}
virtual void OnRemoveLocalVideoTrack(
webrtc::MediaStreamInterface* stream,
- webrtc::VideoTrackInterface* video_track) {
- }
- virtual void OnRemoveLocalStream(webrtc::MediaStreamInterface* stream) {
- }
+ webrtc::VideoTrackInterface* video_track) {}
+ virtual void OnRemoveLocalStream(webrtc::MediaStreamInterface* stream) {}
private:
rtc::scoped_refptr<webrtc::MediaStreamInterface> CreateStream(