Add a 'remote' property to MediaSourceInterface. Also adding an implementation to the relevant sources we have (audio/video) and an extra check where we're casting a source into a local audio source :(
Additionally: * Moving all implementation inside RemoteAudioTrack into AudioTrack and remove RemoteAudioTrack. * AddSink/RemoveSink are now on all audio sources (like they are for video sources). While doing this I found that some of our tests are broken :) and fixed them. They were broken because AudioTrack didn't previously do much such as updating its state. BUG=chromium:569526 Review URL: https://codereview.webrtc.org/1522903002 Cr-Commit-Position: refs/heads/master@{#11026}
This commit is contained in:
@ -27,27 +27,82 @@
|
||||
|
||||
#include "talk/app/webrtc/audiotrack.h"
|
||||
|
||||
#include <string>
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
using rtc::scoped_refptr;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const char MediaStreamTrackInterface::kAudioKind[] = "audio";
|
||||
|
||||
// static
|
||||
scoped_refptr<AudioTrack> AudioTrack::Create(
|
||||
const std::string& id,
|
||||
const scoped_refptr<AudioSourceInterface>& source) {
|
||||
return new rtc::RefCountedObject<AudioTrack>(id, source);
|
||||
}
|
||||
|
||||
AudioTrack::AudioTrack(const std::string& label,
|
||||
AudioSourceInterface* audio_source)
|
||||
: MediaStreamTrack<AudioTrackInterface>(label),
|
||||
audio_source_(audio_source) {
|
||||
const scoped_refptr<AudioSourceInterface>& source)
|
||||
: MediaStreamTrack<AudioTrackInterface>(label), audio_source_(source) {
|
||||
if (audio_source_) {
|
||||
audio_source_->RegisterObserver(this);
|
||||
OnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
AudioTrack::~AudioTrack() {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
set_state(MediaStreamTrackInterface::kEnded);
|
||||
if (audio_source_)
|
||||
audio_source_->UnregisterObserver(this);
|
||||
}
|
||||
|
||||
std::string AudioTrack::kind() const {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
return kAudioKind;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<AudioTrack> AudioTrack::Create(
|
||||
const std::string& id, AudioSourceInterface* source) {
|
||||
rtc::RefCountedObject<AudioTrack>* track =
|
||||
new rtc::RefCountedObject<AudioTrack>(id, source);
|
||||
return track;
|
||||
AudioSourceInterface* AudioTrack::GetSource() const {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
return audio_source_.get();
|
||||
}
|
||||
|
||||
void AudioTrack::AddSink(AudioTrackSinkInterface* sink) {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
if (audio_source_)
|
||||
audio_source_->AddSink(sink);
|
||||
}
|
||||
|
||||
void AudioTrack::RemoveSink(AudioTrackSinkInterface* sink) {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
if (audio_source_)
|
||||
audio_source_->RemoveSink(sink);
|
||||
}
|
||||
|
||||
void AudioTrack::OnChanged() {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
if (state() == kFailed)
|
||||
return; // We can't recover from this state (do we ever set it?).
|
||||
|
||||
TrackState new_state = kInitializing;
|
||||
|
||||
// |audio_source_| must be non-null if we ever get here.
|
||||
switch (audio_source_->state()) {
|
||||
case MediaSourceInterface::kLive:
|
||||
case MediaSourceInterface::kMuted:
|
||||
new_state = kLive;
|
||||
break;
|
||||
case MediaSourceInterface::kEnded:
|
||||
new_state = kEnded;
|
||||
break;
|
||||
case MediaSourceInterface::kInitializing:
|
||||
default:
|
||||
// use kInitializing.
|
||||
break;
|
||||
}
|
||||
|
||||
set_state(new_state);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -28,40 +28,47 @@
|
||||
#ifndef TALK_APP_WEBRTC_AUDIOTRACK_H_
|
||||
#define TALK_APP_WEBRTC_AUDIOTRACK_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||
#include "talk/app/webrtc/mediastreamtrack.h"
|
||||
#include "talk/app/webrtc/notifier.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
#include "webrtc/base/thread_checker.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class AudioTrack : public MediaStreamTrack<AudioTrackInterface> {
|
||||
class AudioTrack : public MediaStreamTrack<AudioTrackInterface>,
|
||||
public ObserverInterface {
|
||||
protected:
|
||||
// Protected ctor to force use of factory method.
|
||||
AudioTrack(const std::string& label,
|
||||
const rtc::scoped_refptr<AudioSourceInterface>& source);
|
||||
~AudioTrack() override;
|
||||
|
||||
public:
|
||||
static rtc::scoped_refptr<AudioTrack> Create(
|
||||
const std::string& id, AudioSourceInterface* source);
|
||||
|
||||
// AudioTrackInterface implementation.
|
||||
AudioSourceInterface* GetSource() const override {
|
||||
return audio_source_.get();
|
||||
}
|
||||
// TODO(xians): Implement these methods.
|
||||
void AddSink(AudioTrackSinkInterface* sink) override {}
|
||||
void RemoveSink(AudioTrackSinkInterface* sink) override {}
|
||||
bool GetSignalLevel(int* level) override { return false; }
|
||||
rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
|
||||
return NULL;
|
||||
}
|
||||
cricket::AudioRenderer* GetRenderer() override { return NULL; }
|
||||
const std::string& id,
|
||||
const rtc::scoped_refptr<AudioSourceInterface>& source);
|
||||
|
||||
private:
|
||||
// MediaStreamTrack implementation.
|
||||
std::string kind() const override;
|
||||
|
||||
protected:
|
||||
AudioTrack(const std::string& label, AudioSourceInterface* audio_source);
|
||||
// AudioTrackInterface implementation.
|
||||
AudioSourceInterface* GetSource() const override;
|
||||
|
||||
void AddSink(AudioTrackSinkInterface* sink) override;
|
||||
void RemoveSink(AudioTrackSinkInterface* sink) override;
|
||||
|
||||
// ObserverInterface implementation.
|
||||
void OnChanged() override;
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<AudioSourceInterface> audio_source_;
|
||||
const rtc::scoped_refptr<AudioSourceInterface> audio_source_;
|
||||
rtc::ThreadChecker thread_checker_;
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTrack);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -48,16 +48,17 @@ class LocalAudioSource : public Notifier<AudioSourceInterface> {
|
||||
const PeerConnectionFactoryInterface::Options& options,
|
||||
const MediaConstraintsInterface* constraints);
|
||||
|
||||
virtual SourceState state() const { return source_state_; }
|
||||
SourceState state() const override { return source_state_; }
|
||||
bool remote() const override { return false; }
|
||||
|
||||
virtual const cricket::AudioOptions& options() const { return options_; }
|
||||
|
||||
protected:
|
||||
LocalAudioSource()
|
||||
: source_state_(kInitializing) {
|
||||
}
|
||||
void AddSink(AudioTrackSinkInterface* sink) override {}
|
||||
void RemoveSink(AudioTrackSinkInterface* sink) override {}
|
||||
|
||||
~LocalAudioSource() {
|
||||
}
|
||||
protected:
|
||||
LocalAudioSource() : source_state_(kInitializing) {}
|
||||
~LocalAudioSource() override {}
|
||||
|
||||
private:
|
||||
void Initialize(const PeerConnectionFactoryInterface::Options& options,
|
||||
|
||||
@ -48,9 +48,23 @@ namespace webrtc {
|
||||
// Helper class to test Observer.
|
||||
class MockObserver : public ObserverInterface {
|
||||
public:
|
||||
MockObserver() {}
|
||||
explicit MockObserver(NotifierInterface* notifier) : notifier_(notifier) {
|
||||
notifier_->RegisterObserver(this);
|
||||
}
|
||||
|
||||
~MockObserver() { Unregister(); }
|
||||
|
||||
void Unregister() {
|
||||
if (notifier_) {
|
||||
notifier_->UnregisterObserver(this);
|
||||
notifier_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
MOCK_METHOD0(OnChanged, void());
|
||||
|
||||
private:
|
||||
NotifierInterface* notifier_;
|
||||
};
|
||||
|
||||
class MediaStreamTest: public testing::Test {
|
||||
@ -75,8 +89,7 @@ class MediaStreamTest: public testing::Test {
|
||||
}
|
||||
|
||||
void ChangeTrack(MediaStreamTrackInterface* track) {
|
||||
MockObserver observer;
|
||||
track->RegisterObserver(&observer);
|
||||
MockObserver observer(track);
|
||||
|
||||
EXPECT_CALL(observer, OnChanged())
|
||||
.Times(Exactly(1));
|
||||
@ -127,8 +140,7 @@ TEST_F(MediaStreamTest, GetTrackInfo) {
|
||||
}
|
||||
|
||||
TEST_F(MediaStreamTest, RemoveTrack) {
|
||||
MockObserver observer;
|
||||
stream_->RegisterObserver(&observer);
|
||||
MockObserver observer(stream_);
|
||||
|
||||
EXPECT_CALL(observer, OnChanged())
|
||||
.Times(Exactly(2));
|
||||
|
||||
@ -71,8 +71,6 @@ class NotifierInterface {
|
||||
|
||||
// Base class for sources. A MediaStreamTrack have an underlying source that
|
||||
// provide media. A source can be shared with multiple tracks.
|
||||
// TODO(perkj): Implement sources for local and remote audio tracks and
|
||||
// remote video tracks.
|
||||
class MediaSourceInterface : public rtc::RefCountInterface,
|
||||
public NotifierInterface {
|
||||
public:
|
||||
@ -85,6 +83,8 @@ class MediaSourceInterface : public rtc::RefCountInterface,
|
||||
|
||||
virtual SourceState state() const = 0;
|
||||
|
||||
virtual bool remote() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~MediaSourceInterface() {}
|
||||
};
|
||||
@ -152,6 +152,19 @@ class VideoTrackInterface : public MediaStreamTrackInterface {
|
||||
virtual ~VideoTrackInterface() {}
|
||||
};
|
||||
|
||||
// Interface for receiving audio data from a AudioTrack.
|
||||
class AudioTrackSinkInterface {
|
||||
public:
|
||||
virtual void OnData(const void* audio_data,
|
||||
int bits_per_sample,
|
||||
int sample_rate,
|
||||
int number_of_channels,
|
||||
size_t number_of_frames) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~AudioTrackSinkInterface() {}
|
||||
};
|
||||
|
||||
// AudioSourceInterface is a reference counted source used for AudioTracks.
|
||||
// The same source can be used in multiple AudioTracks.
|
||||
class AudioSourceInterface : public MediaSourceInterface {
|
||||
@ -174,18 +187,10 @@ class AudioSourceInterface : public MediaSourceInterface {
|
||||
// Registers/unregisters observer to the audio source.
|
||||
virtual void RegisterAudioObserver(AudioObserver* observer) {}
|
||||
virtual void UnregisterAudioObserver(AudioObserver* observer) {}
|
||||
};
|
||||
|
||||
// Interface for receiving audio data from a AudioTrack.
|
||||
class AudioTrackSinkInterface {
|
||||
public:
|
||||
virtual void OnData(const void* audio_data,
|
||||
int bits_per_sample,
|
||||
int sample_rate,
|
||||
int number_of_channels,
|
||||
size_t number_of_frames) = 0;
|
||||
protected:
|
||||
virtual ~AudioTrackSinkInterface() {}
|
||||
// TODO(tommi): Make pure virtual.
|
||||
virtual void AddSink(AudioTrackSinkInterface* sink) {}
|
||||
virtual void RemoveSink(AudioTrackSinkInterface* sink) {}
|
||||
};
|
||||
|
||||
// Interface of the audio processor used by the audio track to collect
|
||||
|
||||
@ -39,7 +39,6 @@
|
||||
#include "talk/app/webrtc/mediastreamproxy.h"
|
||||
#include "talk/app/webrtc/mediastreamtrackproxy.h"
|
||||
#include "talk/app/webrtc/remoteaudiosource.h"
|
||||
#include "talk/app/webrtc/remoteaudiotrack.h"
|
||||
#include "talk/app/webrtc/remotevideocapturer.h"
|
||||
#include "talk/app/webrtc/rtpreceiver.h"
|
||||
#include "talk/app/webrtc/rtpsender.h"
|
||||
@ -454,7 +453,7 @@ class RemoteMediaStreamFactory {
|
||||
AudioProviderInterface* provider,
|
||||
webrtc::MediaStreamInterface* stream,
|
||||
const std::string& track_id) {
|
||||
return AddTrack<AudioTrackInterface, RemoteAudioTrack, AudioTrackProxy>(
|
||||
return AddTrack<AudioTrackInterface, AudioTrack, AudioTrackProxy>(
|
||||
stream, track_id, RemoteAudioSource::Create(ssrc, provider));
|
||||
}
|
||||
|
||||
@ -463,7 +462,7 @@ class RemoteMediaStreamFactory {
|
||||
return AddTrack<VideoTrackInterface, VideoTrack, VideoTrackProxy>(
|
||||
stream, track_id,
|
||||
VideoSource::Create(channel_manager_, new RemoteVideoCapturer(),
|
||||
nullptr)
|
||||
nullptr, true)
|
||||
.get());
|
||||
}
|
||||
|
||||
|
||||
@ -225,8 +225,8 @@ PeerConnectionFactory::CreateVideoSource(
|
||||
cricket::VideoCapturer* capturer,
|
||||
const MediaConstraintsInterface* constraints) {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
rtc::scoped_refptr<VideoSource> source(
|
||||
VideoSource::Create(channel_manager_.get(), capturer, constraints));
|
||||
rtc::scoped_refptr<VideoSource> source(VideoSource::Create(
|
||||
channel_manager_.get(), capturer, constraints, false));
|
||||
return VideoSourceProxy::Create(signaling_thread_, source);
|
||||
}
|
||||
|
||||
@ -339,8 +339,7 @@ rtc::scoped_refptr<AudioTrackInterface>
|
||||
PeerConnectionFactory::CreateAudioTrack(const std::string& id,
|
||||
AudioSourceInterface* source) {
|
||||
RTC_DCHECK(signaling_thread_->IsCurrent());
|
||||
rtc::scoped_refptr<AudioTrackInterface> track(
|
||||
AudioTrack::Create(id, source));
|
||||
rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source));
|
||||
return AudioTrackProxy::Create(signaling_thread_, track);
|
||||
}
|
||||
|
||||
|
||||
@ -106,6 +106,11 @@ MediaSourceInterface::SourceState RemoteAudioSource::state() const {
|
||||
return state_;
|
||||
}
|
||||
|
||||
bool RemoteAudioSource::remote() const {
|
||||
RTC_DCHECK(main_thread_->IsCurrent());
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteAudioSource::SetVolume(double volume) {
|
||||
RTC_DCHECK(volume >= 0 && volume <= 10);
|
||||
for (auto* observer : audio_observers_)
|
||||
|
||||
@ -56,9 +56,10 @@ class RemoteAudioSource : public Notifier<AudioSourceInterface> {
|
||||
|
||||
// MediaSourceInterface implementation.
|
||||
MediaSourceInterface::SourceState state() const override;
|
||||
bool remote() const override;
|
||||
|
||||
void AddSink(AudioTrackSinkInterface* sink);
|
||||
void RemoveSink(AudioTrackSinkInterface* sink);
|
||||
void AddSink(AudioTrackSinkInterface* sink) override;
|
||||
void RemoveSink(AudioTrackSinkInterface* sink) override;
|
||||
|
||||
protected:
|
||||
RemoteAudioSource();
|
||||
|
||||
@ -25,71 +25,4 @@
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "talk/app/webrtc/remoteaudiotrack.h"
|
||||
|
||||
#include "talk/app/webrtc/remoteaudiosource.h"
|
||||
|
||||
using rtc::scoped_refptr;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// static
|
||||
scoped_refptr<RemoteAudioTrack> RemoteAudioTrack::Create(
|
||||
const std::string& id,
|
||||
const scoped_refptr<RemoteAudioSource>& source) {
|
||||
return new rtc::RefCountedObject<RemoteAudioTrack>(id, source);
|
||||
}
|
||||
|
||||
RemoteAudioTrack::RemoteAudioTrack(
|
||||
const std::string& label,
|
||||
const scoped_refptr<RemoteAudioSource>& source)
|
||||
: MediaStreamTrack<AudioTrackInterface>(label), audio_source_(source) {
|
||||
audio_source_->RegisterObserver(this);
|
||||
TrackState new_state = kInitializing;
|
||||
switch (audio_source_->state()) {
|
||||
case MediaSourceInterface::kLive:
|
||||
case MediaSourceInterface::kMuted:
|
||||
new_state = kLive;
|
||||
break;
|
||||
case MediaSourceInterface::kEnded:
|
||||
new_state = kEnded;
|
||||
break;
|
||||
case MediaSourceInterface::kInitializing:
|
||||
default:
|
||||
// kInitializing;
|
||||
break;
|
||||
}
|
||||
set_state(new_state);
|
||||
}
|
||||
|
||||
RemoteAudioTrack::~RemoteAudioTrack() {
|
||||
set_state(MediaStreamTrackInterface::kEnded);
|
||||
audio_source_->UnregisterObserver(this);
|
||||
}
|
||||
|
||||
std::string RemoteAudioTrack::kind() const {
|
||||
return MediaStreamTrackInterface::kAudioKind;
|
||||
}
|
||||
|
||||
AudioSourceInterface* RemoteAudioTrack::GetSource() const {
|
||||
return audio_source_.get();
|
||||
}
|
||||
|
||||
void RemoteAudioTrack::AddSink(AudioTrackSinkInterface* sink) {
|
||||
audio_source_->AddSink(sink);
|
||||
}
|
||||
|
||||
void RemoteAudioTrack::RemoveSink(AudioTrackSinkInterface* sink) {
|
||||
audio_source_->RemoveSink(sink);
|
||||
}
|
||||
|
||||
bool RemoteAudioTrack::GetSignalLevel(int* level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoteAudioTrack::OnChanged() {
|
||||
if (audio_source_->state() == MediaSourceInterface::kEnded)
|
||||
set_state(MediaStreamTrackInterface::kEnded);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
// TODO(tommi): Delete this file when removed from build files in Chromium.
|
||||
|
||||
@ -25,53 +25,4 @@
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TALK_APP_WEBRTC_REMOTEAUDIOTRACK_H_
|
||||
#define TALK_APP_WEBRTC_REMOTEAUDIOTRACK_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||
#include "talk/app/webrtc/mediastreamtrack.h"
|
||||
#include "talk/app/webrtc/notifier.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RemoteAudioSource;
|
||||
|
||||
class RemoteAudioTrack : public MediaStreamTrack<AudioTrackInterface>,
|
||||
public ObserverInterface {
|
||||
protected:
|
||||
// Protected ctor to force use of factory method.
|
||||
RemoteAudioTrack(const std::string& label,
|
||||
const rtc::scoped_refptr<RemoteAudioSource>& source);
|
||||
~RemoteAudioTrack() override;
|
||||
|
||||
public:
|
||||
static rtc::scoped_refptr<RemoteAudioTrack> Create(
|
||||
const std::string& id,
|
||||
const rtc::scoped_refptr<RemoteAudioSource>& source);
|
||||
|
||||
private:
|
||||
// MediaStreamTrack implementation.
|
||||
std::string kind() const override;
|
||||
|
||||
// AudioTrackInterface implementation.
|
||||
AudioSourceInterface* GetSource() const override;
|
||||
|
||||
void AddSink(AudioTrackSinkInterface* sink) override;
|
||||
void RemoveSink(AudioTrackSinkInterface* sink) override;
|
||||
bool GetSignalLevel(int* level) override;
|
||||
|
||||
// ObserverInterface implementation.
|
||||
void OnChanged() override;
|
||||
|
||||
private:
|
||||
const rtc::scoped_refptr<RemoteAudioSource> audio_source_;
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteAudioTrack);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // TALK_APP_WEBRTC_REMOTEAUDIOTRACK_H_
|
||||
// TODO(tommi): Delete this file when removed from build files in Chromium.
|
||||
|
||||
@ -39,6 +39,7 @@ AudioRtpReceiver::AudioRtpReceiver(AudioTrackInterface* track,
|
||||
ssrc_(ssrc),
|
||||
provider_(provider),
|
||||
cached_track_enabled_(track->enabled()) {
|
||||
RTC_DCHECK(track_->GetSource()->remote());
|
||||
track_->RegisterObserver(this);
|
||||
track_->GetSource()->RegisterAudioObserver(this);
|
||||
Reconfigure();
|
||||
@ -85,6 +86,7 @@ VideoRtpReceiver::VideoRtpReceiver(VideoTrackInterface* track,
|
||||
uint32_t ssrc,
|
||||
VideoProviderInterface* provider)
|
||||
: id_(track->id()), track_(track), ssrc_(ssrc), provider_(provider) {
|
||||
RTC_DCHECK(track_->GetSource()->remote());
|
||||
provider_->SetVideoPlayout(ssrc_, true, track_->GetSource()->FrameInput());
|
||||
}
|
||||
|
||||
|
||||
@ -184,7 +184,8 @@ void AudioRtpSender::Stop() {
|
||||
void AudioRtpSender::SetAudioSend() {
|
||||
RTC_DCHECK(!stopped_ && can_send_track());
|
||||
cricket::AudioOptions options;
|
||||
if (track_->enabled() && track_->GetSource()) {
|
||||
if (track_->enabled() && track_->GetSource() &&
|
||||
!track_->GetSource()->remote()) {
|
||||
// TODO(xians): Remove this static_cast since we should be able to connect
|
||||
// a remote audio track to a peer connection.
|
||||
options = static_cast<LocalAudioSource*>(track_->GetSource())->options();
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "talk/app/webrtc/audiotrack.h"
|
||||
#include "talk/app/webrtc/mediastream.h"
|
||||
#include "talk/app/webrtc/remoteaudiosource.h"
|
||||
#include "talk/app/webrtc/remoteaudiotrack.h"
|
||||
#include "talk/app/webrtc/rtpreceiver.h"
|
||||
#include "talk/app/webrtc/rtpsender.h"
|
||||
#include "talk/app/webrtc/streamcollection.h"
|
||||
@ -98,8 +97,8 @@ class MockVideoProvider : public VideoProviderInterface {
|
||||
|
||||
class FakeVideoSource : public Notifier<VideoSourceInterface> {
|
||||
public:
|
||||
static rtc::scoped_refptr<FakeVideoSource> Create() {
|
||||
return new rtc::RefCountedObject<FakeVideoSource>();
|
||||
static rtc::scoped_refptr<FakeVideoSource> Create(bool remote) {
|
||||
return new rtc::RefCountedObject<FakeVideoSource>(remote);
|
||||
}
|
||||
virtual cricket::VideoCapturer* GetVideoCapturer() { return &fake_capturer_; }
|
||||
virtual void Stop() {}
|
||||
@ -107,16 +106,18 @@ class FakeVideoSource : public Notifier<VideoSourceInterface> {
|
||||
virtual void AddSink(cricket::VideoRenderer* output) {}
|
||||
virtual void RemoveSink(cricket::VideoRenderer* output) {}
|
||||
virtual SourceState state() const { return state_; }
|
||||
virtual bool remote() const { return remote_; }
|
||||
virtual const cricket::VideoOptions* options() const { return &options_; }
|
||||
virtual cricket::VideoRenderer* FrameInput() { return NULL; }
|
||||
|
||||
protected:
|
||||
FakeVideoSource() : state_(kLive) {}
|
||||
explicit FakeVideoSource(bool remote) : state_(kLive), remote_(remote) {}
|
||||
~FakeVideoSource() {}
|
||||
|
||||
private:
|
||||
cricket::FakeVideoCapturer fake_capturer_;
|
||||
SourceState state_;
|
||||
bool remote_;
|
||||
cricket::VideoOptions options_;
|
||||
};
|
||||
|
||||
@ -124,7 +125,11 @@ class RtpSenderReceiverTest : public testing::Test {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
stream_ = MediaStream::Create(kStreamLabel1);
|
||||
rtc::scoped_refptr<VideoSourceInterface> source(FakeVideoSource::Create());
|
||||
}
|
||||
|
||||
void AddVideoTrack(bool remote) {
|
||||
rtc::scoped_refptr<VideoSourceInterface> source(
|
||||
FakeVideoSource::Create(remote));
|
||||
video_track_ = VideoTrack::Create(kVideoTrackId, source);
|
||||
EXPECT_TRUE(stream_->AddTrack(video_track_));
|
||||
}
|
||||
@ -140,6 +145,7 @@ class RtpSenderReceiverTest : public testing::Test {
|
||||
}
|
||||
|
||||
void CreateVideoRtpSender() {
|
||||
AddVideoTrack(false);
|
||||
EXPECT_CALL(video_provider_,
|
||||
SetCaptureDevice(
|
||||
kVideoSsrc, video_track_->GetSource()->GetVideoCapturer()));
|
||||
@ -162,7 +168,7 @@ class RtpSenderReceiverTest : public testing::Test {
|
||||
}
|
||||
|
||||
void CreateAudioRtpReceiver() {
|
||||
audio_track_ = RemoteAudioTrack::Create(
|
||||
audio_track_ = AudioTrack::Create(
|
||||
kAudioTrackId, RemoteAudioSource::Create(kAudioSsrc, NULL));
|
||||
EXPECT_TRUE(stream_->AddTrack(audio_track_));
|
||||
EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true));
|
||||
@ -171,6 +177,7 @@ class RtpSenderReceiverTest : public testing::Test {
|
||||
}
|
||||
|
||||
void CreateVideoRtpReceiver() {
|
||||
AddVideoTrack(true);
|
||||
EXPECT_CALL(video_provider_,
|
||||
SetVideoPlayout(kVideoSsrc, true,
|
||||
video_track_->GetSource()->FrameInput()));
|
||||
@ -355,6 +362,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderEarlyWarmupTrackThenSsrc) {
|
||||
// Test that a video sender calls the expected methods on the provider once
|
||||
// it has a track and SSRC, when the SSRC is set first.
|
||||
TEST_F(RtpSenderReceiverTest, VideoSenderEarlyWarmupSsrcThenTrack) {
|
||||
AddVideoTrack(false);
|
||||
rtc::scoped_refptr<VideoRtpSender> sender =
|
||||
new VideoRtpSender(&video_provider_);
|
||||
sender->SetSsrc(kVideoSsrc);
|
||||
@ -372,6 +380,7 @@ TEST_F(RtpSenderReceiverTest, VideoSenderEarlyWarmupSsrcThenTrack) {
|
||||
// Test that a video sender calls the expected methods on the provider once
|
||||
// it has a track and SSRC, when the SSRC is set last.
|
||||
TEST_F(RtpSenderReceiverTest, VideoSenderEarlyWarmupTrackThenSsrc) {
|
||||
AddVideoTrack(false);
|
||||
rtc::scoped_refptr<VideoRtpSender> sender =
|
||||
new VideoRtpSender(&video_provider_);
|
||||
sender->SetTrack(video_track_);
|
||||
@ -407,6 +416,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderSsrcSetToZero) {
|
||||
// Test that the sender is disconnected from the provider when its SSRC is
|
||||
// set to 0.
|
||||
TEST_F(RtpSenderReceiverTest, VideoSenderSsrcSetToZero) {
|
||||
AddVideoTrack(false);
|
||||
EXPECT_CALL(video_provider_,
|
||||
SetCaptureDevice(kVideoSsrc,
|
||||
video_track_->GetSource()->GetVideoCapturer()));
|
||||
@ -442,6 +452,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderTrackSetToNull) {
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderReceiverTest, VideoSenderTrackSetToNull) {
|
||||
AddVideoTrack(false);
|
||||
EXPECT_CALL(video_provider_,
|
||||
SetCaptureDevice(kVideoSsrc,
|
||||
video_track_->GetSource()->GetVideoCapturer()));
|
||||
@ -461,6 +472,7 @@ TEST_F(RtpSenderReceiverTest, VideoSenderTrackSetToNull) {
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderReceiverTest, AudioSenderSsrcChanged) {
|
||||
AddVideoTrack(false);
|
||||
rtc::scoped_refptr<AudioTrackInterface> track =
|
||||
AudioTrack::Create(kAudioTrackId, nullptr);
|
||||
EXPECT_CALL(audio_provider_, SetAudioSend(kAudioSsrc, true, _, _));
|
||||
@ -477,6 +489,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderSsrcChanged) {
|
||||
}
|
||||
|
||||
TEST_F(RtpSenderReceiverTest, VideoSenderSsrcChanged) {
|
||||
AddVideoTrack(false);
|
||||
EXPECT_CALL(video_provider_,
|
||||
SetCaptureDevice(kVideoSsrc,
|
||||
video_track_->GetSource()->GetVideoCapturer()));
|
||||
|
||||
@ -331,21 +331,23 @@ namespace webrtc {
|
||||
rtc::scoped_refptr<VideoSource> VideoSource::Create(
|
||||
cricket::ChannelManager* channel_manager,
|
||||
cricket::VideoCapturer* capturer,
|
||||
const webrtc::MediaConstraintsInterface* constraints) {
|
||||
const webrtc::MediaConstraintsInterface* constraints,
|
||||
bool remote) {
|
||||
ASSERT(channel_manager != NULL);
|
||||
ASSERT(capturer != NULL);
|
||||
rtc::scoped_refptr<VideoSource> source(
|
||||
new rtc::RefCountedObject<VideoSource>(channel_manager,
|
||||
capturer));
|
||||
rtc::scoped_refptr<VideoSource> source(new rtc::RefCountedObject<VideoSource>(
|
||||
channel_manager, capturer, remote));
|
||||
source->Initialize(constraints);
|
||||
return source;
|
||||
}
|
||||
|
||||
VideoSource::VideoSource(cricket::ChannelManager* channel_manager,
|
||||
cricket::VideoCapturer* capturer)
|
||||
cricket::VideoCapturer* capturer,
|
||||
bool remote)
|
||||
: channel_manager_(channel_manager),
|
||||
video_capturer_(capturer),
|
||||
state_(kInitializing) {
|
||||
state_(kInitializing),
|
||||
remote_(remote) {
|
||||
channel_manager_->SignalVideoCaptureStateChange.connect(
|
||||
this, &VideoSource::OnStateChange);
|
||||
}
|
||||
|
||||
@ -66,9 +66,12 @@ class VideoSource : public Notifier<VideoSourceInterface>,
|
||||
static rtc::scoped_refptr<VideoSource> Create(
|
||||
cricket::ChannelManager* channel_manager,
|
||||
cricket::VideoCapturer* capturer,
|
||||
const webrtc::MediaConstraintsInterface* constraints);
|
||||
const webrtc::MediaConstraintsInterface* constraints,
|
||||
bool remote);
|
||||
|
||||
SourceState state() const override { return state_; }
|
||||
bool remote() const override { return remote_; }
|
||||
|
||||
virtual SourceState state() const { return state_; }
|
||||
virtual const cricket::VideoOptions* options() const { return &options_; }
|
||||
virtual cricket::VideoRenderer* FrameInput();
|
||||
|
||||
@ -86,7 +89,8 @@ class VideoSource : public Notifier<VideoSourceInterface>,
|
||||
|
||||
protected:
|
||||
VideoSource(cricket::ChannelManager* channel_manager,
|
||||
cricket::VideoCapturer* capturer);
|
||||
cricket::VideoCapturer* capturer,
|
||||
bool remote);
|
||||
virtual ~VideoSource();
|
||||
void Initialize(const webrtc::MediaConstraintsInterface* constraints);
|
||||
|
||||
@ -104,6 +108,7 @@ class VideoSource : public Notifier<VideoSourceInterface>,
|
||||
cricket::VideoFormat format_;
|
||||
cricket::VideoOptions options_;
|
||||
SourceState state_;
|
||||
const bool remote_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -144,9 +144,9 @@ class VideoSourceTest : public testing::Test {
|
||||
void CreateVideoSource(
|
||||
const webrtc::MediaConstraintsInterface* constraints) {
|
||||
// VideoSource take ownership of |capturer_|
|
||||
source_ = VideoSource::Create(channel_manager_.get(),
|
||||
capturer_cleanup_.release(),
|
||||
constraints);
|
||||
source_ =
|
||||
VideoSource::Create(channel_manager_.get(), capturer_cleanup_.release(),
|
||||
constraints, false);
|
||||
|
||||
ASSERT_TRUE(source_.get() != NULL);
|
||||
EXPECT_EQ(capturer_, source_->GetVideoCapturer());
|
||||
@ -210,8 +210,7 @@ TEST_F(VideoSourceTest, StopRestart) {
|
||||
// RemoteVideoCapturer and takes video frames from FrameInput.
|
||||
TEST_F(VideoSourceTest, StartStopRemote) {
|
||||
source_ = VideoSource::Create(channel_manager_.get(),
|
||||
new webrtc::RemoteVideoCapturer(),
|
||||
NULL);
|
||||
new webrtc::RemoteVideoCapturer(), NULL, true);
|
||||
|
||||
ASSERT_TRUE(source_.get() != NULL);
|
||||
EXPECT_TRUE(NULL != source_->GetVideoCapturer());
|
||||
|
||||
@ -38,6 +38,7 @@ namespace webrtc {
|
||||
// signaling thread.
|
||||
BEGIN_PROXY_MAP(VideoSource)
|
||||
PROXY_CONSTMETHOD0(SourceState, state)
|
||||
PROXY_CONSTMETHOD0(bool, remote)
|
||||
PROXY_METHOD0(cricket::VideoCapturer*, GetVideoCapturer)
|
||||
PROXY_METHOD0(void, Stop)
|
||||
PROXY_METHOD0(void, Restart)
|
||||
|
||||
@ -62,7 +62,7 @@ class VideoTrackTest : public testing::Test {
|
||||
video_track_ = VideoTrack::Create(
|
||||
kVideoTrackId,
|
||||
VideoSource::Create(channel_manager_.get(),
|
||||
new webrtc::RemoteVideoCapturer(), NULL));
|
||||
new webrtc::RemoteVideoCapturer(), NULL, true));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@ -763,8 +763,6 @@
|
||||
'app/webrtc/proxy.h',
|
||||
'app/webrtc/remoteaudiosource.cc',
|
||||
'app/webrtc/remoteaudiosource.h',
|
||||
'app/webrtc/remoteaudiotrack.cc',
|
||||
'app/webrtc/remoteaudiotrack.h',
|
||||
'app/webrtc/remotevideocapturer.cc',
|
||||
'app/webrtc/remotevideocapturer.h',
|
||||
'app/webrtc/rtpreceiver.cc',
|
||||
|
||||
Reference in New Issue
Block a user