Simplify passing video coded factories in media engine

We soon want to be able to pass in a new type of video codec factories,
see issue 7925 for more information. We currently plumb these video
codec factories in a clumsy way from the media engine to the video
engine, which will require us to update a lot of places when we add
new video codec factory types. This CL cleans up the way we pass in
video codec factories to make it easier to add the new factory types.

In particular, this CL:
 * Updates WebRtcVideoEngine to take the video codec factories as
   arguments in ctor instead of in SetExternalVideoCodec functions.
 * Remove the Init() function from the vidoe engines - this function is
   not used.
 * Update CompositeMediaEngine to take generic variadic arguments, so we
   can send different arguments for different engines, without having to
   update this class.
 * Simplify ownership of video codec factories in WebRtcVideoEngine.
   WebRtcVideoEngine outlives WebRtcVideoChannel,
   WebRtcVideoSendStream and WebRtcVideoReceiveStream, so it can
   keep ownership without having to share ownership with these classes.

BUG=webrtc:7925

Review-Url: https://codereview.webrtc.org/3008043002
Cr-Commit-Position: refs/heads/master@{#19794}
This commit is contained in:
magjed
2017-09-12 04:42:15 -07:00
committed by Commit Bot
parent 1e7dd31001
commit 2475ae2e4c
9 changed files with 209 additions and 381 deletions

View File

@ -774,13 +774,7 @@ class FakeBaseEngine {
class FakeVoiceEngine : public FakeBaseEngine { class FakeVoiceEngine : public FakeBaseEngine {
public: public:
FakeVoiceEngine(webrtc::AudioDeviceModule* adm, FakeVoiceEngine() {
const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
audio_encoder_factory,
const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
audio_decoder_factory,
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
rtc::scoped_refptr<webrtc::AudioProcessing> apm) {
// Add a fake audio codec. Note that the name must not be "" as there are // Add a fake audio codec. Note that the name must not be "" as there are
// sanity checks against that. // sanity checks against that.
codecs_.push_back(AudioCodec(101, "fake_audio_codec", 0, 0, 1)); codecs_.push_back(AudioCodec(101, "fake_audio_codec", 0, 0, 1));
@ -843,8 +837,6 @@ class FakeVideoEngine : public FakeBaseEngine {
codecs_.push_back(VideoCodec(0, "fake_video_codec")); codecs_.push_back(VideoCodec(0, "fake_video_codec"));
} }
void Init() {}
bool SetOptions(const VideoOptions& options) { bool SetOptions(const VideoOptions& options) {
options_ = options; options_ = options;
options_changed_ = true; options_changed_ = true;
@ -895,55 +887,50 @@ class FakeMediaEngine :
public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> { public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> {
public: public:
FakeMediaEngine() FakeMediaEngine()
: CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine>(nullptr, : CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine>(std::tuple<>(),
nullptr, std::tuple<>()) {
nullptr, }
nullptr,
nullptr) {}
virtual ~FakeMediaEngine() {} virtual ~FakeMediaEngine() {}
void SetAudioCodecs(const std::vector<AudioCodec>& codecs) { void SetAudioCodecs(const std::vector<AudioCodec>& codecs) {
voice_.SetCodecs(codecs); voice().SetCodecs(codecs);
} }
void SetVideoCodecs(const std::vector<VideoCodec>& codecs) { void SetVideoCodecs(const std::vector<VideoCodec>& codecs) {
video_.SetCodecs(codecs); video().SetCodecs(codecs);
} }
void SetAudioRtpHeaderExtensions( void SetAudioRtpHeaderExtensions(
const std::vector<RtpExtension>& extensions) { const std::vector<RtpExtension>& extensions) {
voice_.set_rtp_header_extensions(extensions); voice().set_rtp_header_extensions(extensions);
} }
void SetVideoRtpHeaderExtensions( void SetVideoRtpHeaderExtensions(
const std::vector<RtpExtension>& extensions) { const std::vector<RtpExtension>& extensions) {
video_.set_rtp_header_extensions(extensions); video().set_rtp_header_extensions(extensions);
} }
void SetAudioRtpHeaderExtensions( void SetAudioRtpHeaderExtensions(
const std::vector<cricket::RtpHeaderExtension>& extensions) { const std::vector<cricket::RtpHeaderExtension>& extensions) {
voice_.set_rtp_header_extensions(extensions); voice().set_rtp_header_extensions(extensions);
} }
void SetVideoRtpHeaderExtensions( void SetVideoRtpHeaderExtensions(
const std::vector<cricket::RtpHeaderExtension>& extensions) { const std::vector<cricket::RtpHeaderExtension>& extensions) {
video_.set_rtp_header_extensions(extensions); video().set_rtp_header_extensions(extensions);
} }
FakeVoiceMediaChannel* GetVoiceChannel(size_t index) { FakeVoiceMediaChannel* GetVoiceChannel(size_t index) {
return voice_.GetChannel(index); return voice().GetChannel(index);
} }
FakeVideoMediaChannel* GetVideoChannel(size_t index) { FakeVideoMediaChannel* GetVideoChannel(size_t index) {
return video_.GetChannel(index); return video().GetChannel(index);
} }
bool capture() const { return video_.capture_; } bool capture() const { return video().capture_; }
bool options_changed() const { bool options_changed() const { return video().options_changed_; }
return video_.options_changed_; void clear_options_changed() { video().options_changed_ = false; }
}
void clear_options_changed() {
video_.options_changed_ = false;
}
void set_fail_create_channel(bool fail) { void set_fail_create_channel(bool fail) {
voice_.set_fail_create_channel(fail); voice().set_fail_create_channel(fail);
video_.set_fail_create_channel(fail); video().set_fail_create_channel(fail);
} }
}; };

View File

@ -109,71 +109,65 @@ class MediaEngineFactory {
// CompositeMediaEngine constructs a MediaEngine from separate // CompositeMediaEngine constructs a MediaEngine from separate
// voice and video engine classes. // voice and video engine classes.
template<class VOICE, class VIDEO> template <class VOICE, class VIDEO>
class CompositeMediaEngine : public MediaEngineInterface { class CompositeMediaEngine : public MediaEngineInterface {
public: public:
CompositeMediaEngine( template <class... Args1, class... Args2>
webrtc::AudioDeviceModule* adm, CompositeMediaEngine(std::tuple<Args1...> first_args,
const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& std::tuple<Args2...> second_args)
audio_encoder_factory, : engines_(std::piecewise_construct,
const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& std::move(first_args),
audio_decoder_factory, std::move(second_args)) {}
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing)
: voice_(adm,
audio_encoder_factory,
audio_decoder_factory,
audio_mixer,
audio_processing) {}
virtual ~CompositeMediaEngine() {} virtual ~CompositeMediaEngine() {}
virtual bool Init() { virtual bool Init() {
voice_.Init(); voice().Init();
video_.Init();
return true; return true;
} }
virtual rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const { virtual rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const {
return voice_.GetAudioState(); return voice().GetAudioState();
} }
virtual VoiceMediaChannel* CreateChannel(webrtc::Call* call, virtual VoiceMediaChannel* CreateChannel(webrtc::Call* call,
const MediaConfig& config, const MediaConfig& config,
const AudioOptions& options) { const AudioOptions& options) {
return voice_.CreateChannel(call, config, options); return voice().CreateChannel(call, config, options);
} }
virtual VideoMediaChannel* CreateVideoChannel(webrtc::Call* call, virtual VideoMediaChannel* CreateVideoChannel(webrtc::Call* call,
const MediaConfig& config, const MediaConfig& config,
const VideoOptions& options) { const VideoOptions& options) {
return video_.CreateChannel(call, config, options); return video().CreateChannel(call, config, options);
} }
virtual int GetInputLevel() { virtual int GetInputLevel() { return voice().GetInputLevel(); }
return voice_.GetInputLevel();
}
virtual const std::vector<AudioCodec>& audio_send_codecs() { virtual const std::vector<AudioCodec>& audio_send_codecs() {
return voice_.send_codecs(); return voice().send_codecs();
} }
virtual const std::vector<AudioCodec>& audio_recv_codecs() { virtual const std::vector<AudioCodec>& audio_recv_codecs() {
return voice_.recv_codecs(); return voice().recv_codecs();
} }
virtual RtpCapabilities GetAudioCapabilities() { virtual RtpCapabilities GetAudioCapabilities() {
return voice_.GetCapabilities(); return voice().GetCapabilities();
} }
virtual std::vector<VideoCodec> video_codecs() { return video_.codecs(); } virtual std::vector<VideoCodec> video_codecs() { return video().codecs(); }
virtual RtpCapabilities GetVideoCapabilities() { virtual RtpCapabilities GetVideoCapabilities() {
return video_.GetCapabilities(); return video().GetCapabilities();
} }
virtual bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) { virtual bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) {
return voice_.StartAecDump(file, max_size_bytes); return voice().StartAecDump(file, max_size_bytes);
} }
virtual void StopAecDump() { virtual void StopAecDump() { voice().StopAecDump(); }
voice_.StopAecDump();
}
protected: protected:
VOICE voice_; VOICE& voice() { return engines_.first; }
VIDEO video_; VIDEO& video() { return engines_.second; }
const VOICE& voice() const { return engines_.first; }
const VIDEO& video() const { return engines_.second; }
private:
std::pair<VOICE, VIDEO> engines_;
}; };
enum DataChannelType { DCT_NONE = 0, DCT_RTP = 1, DCT_SCTP = 2, DCT_QUIC = 3 }; enum DataChannelType { DCT_NONE = 0, DCT_RTP = 1, DCT_SCTP = 2, DCT_QUIC = 3 };

View File

@ -64,7 +64,9 @@ class VideoMediaChannelTest : public testing::Test,
public sigslot::has_slots<> { public sigslot::has_slots<> {
protected: protected:
VideoMediaChannelTest<E, C>() VideoMediaChannelTest<E, C>()
: call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))) {} : call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
engine_(nullptr /* external_encoder_factory */,
nullptr /* external_decoder_factory */) {}
virtual cricket::VideoCodec DefaultCodec() = 0; virtual cricket::VideoCodec DefaultCodec() = 0;
@ -73,7 +75,6 @@ class VideoMediaChannelTest : public testing::Test,
} }
virtual void SetUp() { virtual void SetUp() {
engine_.Init();
cricket::MediaConfig media_config; cricket::MediaConfig media_config;
// Disabling cpu overuse detection actually disables quality scaling too; it // Disabling cpu overuse detection actually disables quality scaling too; it
// implies DegradationPreference kMaintainResolution. Automatic scaling // implies DegradationPreference kMaintainResolution. Automatic scaling

View File

@ -33,31 +33,15 @@ class WebRtcVideoEncoderFactory;
// CompositeMediaEngine. // CompositeMediaEngine.
class NullWebRtcVideoEngine { class NullWebRtcVideoEngine {
public: public:
NullWebRtcVideoEngine() {} std::vector<VideoCodec> codecs() const { return std::vector<VideoCodec>(); }
~NullWebRtcVideoEngine() {}
void SetExternalDecoderFactory(WebRtcVideoDecoderFactory* decoder_factory) {} RtpCapabilities GetCapabilities() const { return RtpCapabilities(); }
void SetExternalEncoderFactory(WebRtcVideoEncoderFactory* encoder_factory) {}
void Init() {}
const std::vector<VideoCodec>& codecs() {
return codecs_;
}
RtpCapabilities GetCapabilities() {
RtpCapabilities capabilities;
return capabilities;
}
VideoMediaChannel* CreateChannel(webrtc::Call* call, VideoMediaChannel* CreateChannel(webrtc::Call* call,
const MediaConfig& config, const MediaConfig& config,
const VideoOptions& options) { const VideoOptions& options) {
return nullptr; return nullptr;
} }
private:
std::vector<VideoCodec> codecs_;
}; };
} // namespace cricket } // namespace cricket

View File

@ -25,18 +25,14 @@ class WebRtcMediaEngineNullVideo
const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
audio_encoder_factory, audio_encoder_factory,
const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
audio_decoder_factory, audio_decoder_factory)
WebRtcVideoEncoderFactory* video_encoder_factory,
WebRtcVideoDecoderFactory* video_decoder_factory)
: CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>( : CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>(
adm, std::forward_as_tuple(adm,
audio_encoder_factory, audio_encoder_factory,
audio_decoder_factory, audio_decoder_factory,
nullptr, nullptr,
webrtc::AudioProcessing::Create()) { webrtc::AudioProcessing::Create()),
video_.SetExternalDecoderFactory(video_decoder_factory); std::forward_as_tuple()) {}
video_.SetExternalEncoderFactory(video_encoder_factory);
}
}; };
// Simple test to check if NullWebRtcVideoEngine implements the methods // Simple test to check if NullWebRtcVideoEngine implements the methods
@ -44,7 +40,7 @@ class WebRtcMediaEngineNullVideo
TEST(NullWebRtcVideoEngineTest, CheckInterface) { TEST(NullWebRtcVideoEngineTest, CheckInterface) {
WebRtcMediaEngineNullVideo engine( WebRtcMediaEngineNullVideo engine(
nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(), nullptr, webrtc::MockAudioEncoderFactory::CreateUnusedFactory(),
webrtc::MockAudioDecoderFactory::CreateUnusedFactory(), nullptr, nullptr); webrtc::MockAudioDecoderFactory::CreateUnusedFactory());
EXPECT_TRUE(engine.Init()); EXPECT_TRUE(engine.Init());
} }

View File

@ -24,65 +24,33 @@
namespace cricket { namespace cricket {
class WebRtcMediaEngine2 namespace {
#ifdef HAVE_WEBRTC_VIDEO
: public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine> {
#else
: public CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine> {
#endif
public:
WebRtcMediaEngine2(
webrtc::AudioDeviceModule* adm,
const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
audio_encoder_factory,
const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
audio_decoder_factory,
WebRtcVideoEncoderFactory* video_encoder_factory,
WebRtcVideoDecoderFactory* video_decoder_factory,
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing)
#ifdef HAVE_WEBRTC_VIDEO
: CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine>(
adm,
audio_encoder_factory,
audio_decoder_factory,
audio_mixer,
audio_processing){
#else
: CompositeMediaEngine<WebRtcVoiceEngine, NullWebRtcVideoEngine>(
adm,
audio_encoder_factory,
audio_decoder_factory,
audio_mixer,
audio_processing) {
#endif
video_.SetExternalDecoderFactory(video_decoder_factory);
video_.SetExternalEncoderFactory(video_encoder_factory);
}
};
} // namespace cricket MediaEngineInterface* CreateWebRtcMediaEngine(
cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
webrtc::AudioDeviceModule* adm, webrtc::AudioDeviceModule* adm,
const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& const rtc::scoped_refptr<webrtc::AudioEncoderFactory>&
audio_encoder_factory, audio_encoder_factory,
const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& const rtc::scoped_refptr<webrtc::AudioDecoderFactory>&
audio_decoder_factory, audio_decoder_factory,
cricket::WebRtcVideoEncoderFactory* video_encoder_factory, WebRtcVideoEncoderFactory* video_encoder_factory,
cricket::WebRtcVideoDecoderFactory* video_decoder_factory, WebRtcVideoDecoderFactory* video_decoder_factory,
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) { rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
return new cricket::WebRtcMediaEngine2( #ifdef HAVE_WEBRTC_VIDEO
adm, audio_encoder_factory, audio_decoder_factory, video_encoder_factory, typedef WebRtcVideoEngine VideoEngine;
video_decoder_factory, audio_mixer, audio_processing); std::tuple<WebRtcVideoEncoderFactory*, WebRtcVideoDecoderFactory*> video_args(
video_encoder_factory, video_decoder_factory);
#else
typedef NullWebRtcVideoEngine VideoEngine;
std::tuple<> video_args;
#endif
return new CompositeMediaEngine<WebRtcVoiceEngine, VideoEngine>(
std::forward_as_tuple(adm, audio_encoder_factory, audio_decoder_factory,
audio_mixer, audio_processing),
std::move(video_args));
} }
void DestroyWebRtcMediaEngine(cricket::MediaEngineInterface* media_engine) { } // namespace
delete media_engine;
}
namespace cricket {
// TODO(ossu): Backwards-compatible interface. Will be deprecated once the // TODO(ossu): Backwards-compatible interface. Will be deprecated once the
// audio decoder factory is fully plumbed and used throughout WebRTC. // audio decoder factory is fully plumbed and used throughout WebRTC.

View File

@ -68,8 +68,6 @@ class EncoderFactoryAdapter {
bool is_conference_mode_screenshare) const = 0; bool is_conference_mode_screenshare) const = 0;
virtual std::vector<VideoCodec> GetSupportedCodecs() const = 0; virtual std::vector<VideoCodec> GetSupportedCodecs() const = 0;
virtual std::unique_ptr<EncoderFactoryAdapter> clone() const = 0;
}; };
class DecoderFactoryAdapter { class DecoderFactoryAdapter {
@ -79,12 +77,13 @@ class DecoderFactoryAdapter {
virtual std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder( virtual std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const VideoCodec& codec, const VideoCodec& codec,
const VideoDecoderParams& decoder_params) const = 0; const VideoDecoderParams& decoder_params) const = 0;
virtual std::unique_ptr<DecoderFactoryAdapter> clone() const = 0;
}; };
namespace { namespace {
std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
const std::vector<VideoCodec>& input_codecs);
// Wraps cricket::WebRtcVideoEncoderFactory* into common EncoderFactoryAdapter // Wraps cricket::WebRtcVideoEncoderFactory* into common EncoderFactoryAdapter
// interface. // interface.
// TODO(magjed): Add wrapper class for future webrtc::VideoEncoderFactory // TODO(magjed): Add wrapper class for future webrtc::VideoEncoderFactory
@ -107,11 +106,6 @@ class CricketEncoderFactoryAdapter : public EncoderFactoryAdapter {
std::vector<VideoCodec> GetSupportedCodecs() const override; std::vector<VideoCodec> GetSupportedCodecs() const override;
std::unique_ptr<EncoderFactoryAdapter> clone() const override {
return std::unique_ptr<EncoderFactoryAdapter>(
new CricketEncoderFactoryAdapter(*this));
}
const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_; const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_;
WebRtcVideoEncoderFactory* const external_encoder_factory_; WebRtcVideoEncoderFactory* const external_encoder_factory_;
}; };
@ -132,11 +126,6 @@ class CricketDecoderFactoryAdapter : public DecoderFactoryAdapter {
const VideoCodec& codec, const VideoCodec& codec,
const VideoDecoderParams& decoder_params) const override; const VideoDecoderParams& decoder_params) const override;
std::unique_ptr<DecoderFactoryAdapter> clone() const override {
return std::unique_ptr<DecoderFactoryAdapter>(
new CricketDecoderFactoryAdapter(*this));
}
const std::unique_ptr<WebRtcVideoDecoderFactory> internal_decoder_factory_; const std::unique_ptr<WebRtcVideoDecoderFactory> internal_decoder_factory_;
WebRtcVideoDecoderFactory* const external_decoder_factory_; WebRtcVideoDecoderFactory* const external_decoder_factory_;
}; };
@ -402,12 +391,13 @@ void DefaultUnsignalledSsrcHandler::SetDefaultSink(
} }
} }
WebRtcVideoEngine::WebRtcVideoEngine() WebRtcVideoEngine::WebRtcVideoEngine(
: initialized_(false), WebRtcVideoEncoderFactory* external_video_encoder_factory,
decoder_factory_(new CricketDecoderFactoryAdapter( WebRtcVideoDecoderFactory* external_video_decoder_factory)
nullptr /* external_decoder_factory */)), : decoder_factory_(
encoder_factory_(new CricketEncoderFactoryAdapter( new CricketDecoderFactoryAdapter(external_video_decoder_factory)),
nullptr /* external_encoder_factory */)) { encoder_factory_(
new CricketEncoderFactoryAdapter(external_video_encoder_factory)) {
LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()"; LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()";
} }
@ -415,19 +405,13 @@ WebRtcVideoEngine::~WebRtcVideoEngine() {
LOG(LS_INFO) << "WebRtcVideoEngine::~WebRtcVideoEngine"; LOG(LS_INFO) << "WebRtcVideoEngine::~WebRtcVideoEngine";
} }
void WebRtcVideoEngine::Init() {
LOG(LS_INFO) << "WebRtcVideoEngine::Init";
initialized_ = true;
}
WebRtcVideoChannel* WebRtcVideoEngine::CreateChannel( WebRtcVideoChannel* WebRtcVideoEngine::CreateChannel(
webrtc::Call* call, webrtc::Call* call,
const MediaConfig& config, const MediaConfig& config,
const VideoOptions& options) { const VideoOptions& options) {
RTC_DCHECK(initialized_);
LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString(); LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString();
return new WebRtcVideoChannel(call, config, options, *encoder_factory_, return new WebRtcVideoChannel(call, config, options, encoder_factory_.get(),
*decoder_factory_); decoder_factory_.get());
} }
std::vector<VideoCodec> WebRtcVideoEngine::codecs() const { std::vector<VideoCodec> WebRtcVideoEngine::codecs() const {
@ -460,23 +444,12 @@ RtpCapabilities WebRtcVideoEngine::GetCapabilities() const {
return capabilities; return capabilities;
} }
void WebRtcVideoEngine::SetExternalDecoderFactory( namespace {
WebRtcVideoDecoderFactory* decoder_factory) {
RTC_DCHECK(!initialized_);
decoder_factory_.reset(new CricketDecoderFactoryAdapter(decoder_factory));
}
void WebRtcVideoEngine::SetExternalEncoderFactory(
WebRtcVideoEncoderFactory* encoder_factory) {
RTC_DCHECK(!initialized_);
encoder_factory_.reset(new CricketEncoderFactoryAdapter(encoder_factory));
}
// This function will assign dynamic payload types (in the range [96, 127]) to // This function will assign dynamic payload types (in the range [96, 127]) to
// the input codecs, and also add associated RTX codecs for recognized codecs // the input codecs, and also add associated RTX codecs for recognized codecs
// (VP8, VP9, H264, and RED). It will also add default feedback params to the // (VP8, VP9, H264, and RED). It will also add default feedback params to the
// codecs. // codecs.
static std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs( std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
const std::vector<VideoCodec>& input_codecs) { const std::vector<VideoCodec>& input_codecs) {
static const int kFirstDynamicPayloadType = 96; static const int kFirstDynamicPayloadType = 96;
static const int kLastDynamicPayloadType = 127; static const int kLastDynamicPayloadType = 127;
@ -513,6 +486,7 @@ static std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
} }
return output_codecs; return output_codecs;
} }
} // namespace
std::vector<VideoCodec> CricketEncoderFactoryAdapter::GetSupportedCodecs() std::vector<VideoCodec> CricketEncoderFactoryAdapter::GetSupportedCodecs()
const { const {
@ -540,14 +514,14 @@ WebRtcVideoChannel::WebRtcVideoChannel(
webrtc::Call* call, webrtc::Call* call,
const MediaConfig& config, const MediaConfig& config,
const VideoOptions& options, const VideoOptions& options,
const EncoderFactoryAdapter& encoder_factory, const EncoderFactoryAdapter* encoder_factory,
const DecoderFactoryAdapter& decoder_factory) const DecoderFactoryAdapter* decoder_factory)
: VideoMediaChannel(config), : VideoMediaChannel(config),
call_(call), call_(call),
unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
video_config_(config.video), video_config_(config.video),
encoder_factory_(encoder_factory.clone()), encoder_factory_(encoder_factory),
decoder_factory_(decoder_factory.clone()), decoder_factory_(decoder_factory),
default_send_options_(options), default_send_options_(options),
last_stats_log_ms_(-1) { last_stats_log_ms_(-1) {
RTC_DCHECK(thread_checker_.CalledOnValidThread()); RTC_DCHECK(thread_checker_.CalledOnValidThread());
@ -1052,7 +1026,7 @@ bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) {
config.periodic_alr_bandwidth_probing = config.periodic_alr_bandwidth_probing =
video_config_.periodic_alr_bandwidth_probing; video_config_.periodic_alr_bandwidth_probing;
WebRtcVideoSendStream* stream = new WebRtcVideoSendStream( WebRtcVideoSendStream* stream = new WebRtcVideoSendStream(
call_, sp, std::move(config), default_send_options_, *encoder_factory_, call_, sp, std::move(config), default_send_options_, encoder_factory_,
video_config_.enable_cpu_overuse_detection, video_config_.enable_cpu_overuse_detection,
bitrate_config_.max_bitrate_bps, send_codec_, send_rtp_extensions_, bitrate_config_.max_bitrate_bps, send_codec_, send_rtp_extensions_,
send_params_); send_params_);
@ -1163,7 +1137,7 @@ bool WebRtcVideoChannel::AddRecvStream(const StreamParams& sp,
config.sync_group = sp.sync_label; config.sync_group = sp.sync_label;
receive_streams_[ssrc] = new WebRtcVideoReceiveStream( receive_streams_[ssrc] = new WebRtcVideoReceiveStream(
call_, sp, std::move(config), *decoder_factory_, default_stream, call_, sp, std::move(config), decoder_factory_, default_stream,
recv_codecs_, flexfec_config); recv_codecs_, flexfec_config);
return true; return true;
@ -1502,7 +1476,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream(
const StreamParams& sp, const StreamParams& sp,
webrtc::VideoSendStream::Config config, webrtc::VideoSendStream::Config config,
const VideoOptions& options, const VideoOptions& options,
const EncoderFactoryAdapter& encoder_factory, const EncoderFactoryAdapter* encoder_factory,
bool enable_cpu_overuse_detection, bool enable_cpu_overuse_detection,
int max_bitrate_bps, int max_bitrate_bps,
const rtc::Optional<VideoCodecSettings>& codec_settings, const rtc::Optional<VideoCodecSettings>& codec_settings,
@ -1516,7 +1490,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream(
call_(call), call_(call),
enable_cpu_overuse_detection_(enable_cpu_overuse_detection), enable_cpu_overuse_detection_(enable_cpu_overuse_detection),
source_(nullptr), source_(nullptr),
encoder_factory_(encoder_factory.clone()), encoder_factory_(encoder_factory),
stream_(nullptr), stream_(nullptr),
encoder_sink_(nullptr), encoder_sink_(nullptr),
parameters_(std::move(config), options, max_bitrate_bps, codec_settings), parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
@ -2103,7 +2077,7 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
webrtc::Call* call, webrtc::Call* call,
const StreamParams& sp, const StreamParams& sp,
webrtc::VideoReceiveStream::Config config, webrtc::VideoReceiveStream::Config config,
const DecoderFactoryAdapter& decoder_factory, const DecoderFactoryAdapter* decoder_factory,
bool default_stream, bool default_stream,
const std::vector<VideoCodecSettings>& recv_codecs, const std::vector<VideoCodecSettings>& recv_codecs,
const webrtc::FlexfecReceiveStream::Config& flexfec_config) const webrtc::FlexfecReceiveStream::Config& flexfec_config)
@ -2114,7 +2088,7 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
config_(std::move(config)), config_(std::move(config)),
flexfec_config_(flexfec_config), flexfec_config_(flexfec_config),
flexfec_stream_(nullptr), flexfec_stream_(nullptr),
decoder_factory_(decoder_factory.clone()), decoder_factory_(decoder_factory),
sink_(NULL), sink_(NULL),
first_frame_timestamp_(-1), first_frame_timestamp_(-1),
estimated_remote_start_ntp_time_ms_(0) { estimated_remote_start_ntp_time_ms_(0) {

View File

@ -97,12 +97,13 @@ class DefaultUnsignalledSsrcHandler : public UnsignalledSsrcHandler {
// WebRtcVideoEngine is used for the new native WebRTC Video API (webrtc:1667). // WebRtcVideoEngine is used for the new native WebRTC Video API (webrtc:1667).
class WebRtcVideoEngine { class WebRtcVideoEngine {
public: public:
WebRtcVideoEngine(); // Video engine does not take ownership of the video codec factories and the
// caller needs to make sure they outlive the video engine. Internal SW video
// codecs will be added on top of the external codecs.
WebRtcVideoEngine(WebRtcVideoEncoderFactory* external_video_encoder_factory,
WebRtcVideoDecoderFactory* external_video_decoder_factory);
virtual ~WebRtcVideoEngine(); virtual ~WebRtcVideoEngine();
// Basic video engine implementation.
void Init();
WebRtcVideoChannel* CreateChannel(webrtc::Call* call, WebRtcVideoChannel* CreateChannel(webrtc::Call* call,
const MediaConfig& config, const MediaConfig& config,
const VideoOptions& options); const VideoOptions& options);
@ -110,21 +111,9 @@ class WebRtcVideoEngine {
std::vector<VideoCodec> codecs() const; std::vector<VideoCodec> codecs() const;
RtpCapabilities GetCapabilities() const; RtpCapabilities GetCapabilities() const;
// Set a WebRtcVideoDecoderFactory for external decoding. Video engine does
// not take the ownership of |decoder_factory|. The caller needs to make sure
// that |decoder_factory| outlives the video engine.
void SetExternalDecoderFactory(WebRtcVideoDecoderFactory* decoder_factory);
// Set a WebRtcVideoEncoderFactory for external encoding. Video engine does
// not take the ownership of |encoder_factory|. The caller needs to make sure
// that |encoder_factory| outlives the video engine.
virtual void SetExternalEncoderFactory(
WebRtcVideoEncoderFactory* encoder_factory);
private: private:
bool initialized_; const std::unique_ptr<DecoderFactoryAdapter> decoder_factory_;
const std::unique_ptr<EncoderFactoryAdapter> encoder_factory_;
std::unique_ptr<DecoderFactoryAdapter> decoder_factory_;
std::unique_ptr<EncoderFactoryAdapter> encoder_factory_;
}; };
class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
@ -132,8 +121,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
WebRtcVideoChannel(webrtc::Call* call, WebRtcVideoChannel(webrtc::Call* call,
const MediaConfig& config, const MediaConfig& config,
const VideoOptions& options, const VideoOptions& options,
const EncoderFactoryAdapter& encoder_factory, const EncoderFactoryAdapter* encoder_factory,
const DecoderFactoryAdapter& decoder_factory); const DecoderFactoryAdapter* decoder_factory);
~WebRtcVideoChannel() override; ~WebRtcVideoChannel() override;
// VideoMediaChannel implementation // VideoMediaChannel implementation
@ -261,7 +250,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
const StreamParams& sp, const StreamParams& sp,
webrtc::VideoSendStream::Config config, webrtc::VideoSendStream::Config config,
const VideoOptions& options, const VideoOptions& options,
const EncoderFactoryAdapter& encoder_factory, const EncoderFactoryAdapter* encoder_factory,
bool enable_cpu_overuse_detection, bool enable_cpu_overuse_detection,
int max_bitrate_bps, int max_bitrate_bps,
const rtc::Optional<VideoCodecSettings>& codec_settings, const rtc::Optional<VideoCodecSettings>& codec_settings,
@ -338,9 +327,9 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
webrtc::Call* const call_; webrtc::Call* const call_;
const bool enable_cpu_overuse_detection_; const bool enable_cpu_overuse_detection_;
rtc::VideoSourceInterface<webrtc::VideoFrame>* source_ rtc::VideoSourceInterface<webrtc::VideoFrame>* source_
RTC_ACCESS_ON(&thread_checker_); ACCESS_ON(&thread_checker_);
std::unique_ptr<EncoderFactoryAdapter> encoder_factory_ const EncoderFactoryAdapter* const encoder_factory_
RTC_ACCESS_ON(&thread_checker_); ACCESS_ON(&thread_checker_);
webrtc::VideoSendStream* stream_ RTC_ACCESS_ON(&thread_checker_); webrtc::VideoSendStream* stream_ RTC_ACCESS_ON(&thread_checker_);
rtc::VideoSinkInterface<webrtc::VideoFrame>* encoder_sink_ rtc::VideoSinkInterface<webrtc::VideoFrame>* encoder_sink_
@ -371,7 +360,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
webrtc::Call* call, webrtc::Call* call,
const StreamParams& sp, const StreamParams& sp,
webrtc::VideoReceiveStream::Config config, webrtc::VideoReceiveStream::Config config,
const DecoderFactoryAdapter& decoder_factory, const DecoderFactoryAdapter* decoder_factory,
bool default_stream, bool default_stream,
const std::vector<VideoCodecSettings>& recv_codecs, const std::vector<VideoCodecSettings>& recv_codecs,
const webrtc::FlexfecReceiveStream::Config& flexfec_config); const webrtc::FlexfecReceiveStream::Config& flexfec_config);
@ -432,7 +421,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
webrtc::FlexfecReceiveStream::Config flexfec_config_; webrtc::FlexfecReceiveStream::Config flexfec_config_;
webrtc::FlexfecReceiveStream* flexfec_stream_; webrtc::FlexfecReceiveStream* flexfec_stream_;
std::unique_ptr<DecoderFactoryAdapter> decoder_factory_; const DecoderFactoryAdapter* decoder_factory_;
DecoderMap allocated_decoders_; DecoderMap allocated_decoders_;
rtc::CriticalSection sink_lock_; rtc::CriticalSection sink_lock_;
@ -496,8 +485,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
rtc::Optional<VideoCodecSettings> send_codec_; rtc::Optional<VideoCodecSettings> send_codec_;
rtc::Optional<std::vector<webrtc::RtpExtension>> send_rtp_extensions_; rtc::Optional<std::vector<webrtc::RtpExtension>> send_rtp_extensions_;
std::unique_ptr<EncoderFactoryAdapter> encoder_factory_; const EncoderFactoryAdapter* const encoder_factory_;
std::unique_ptr<DecoderFactoryAdapter> decoder_factory_; const DecoderFactoryAdapter* const decoder_factory_;
std::vector<VideoCodecSettings> recv_codecs_; std::vector<VideoCodecSettings> recv_codecs_;
std::vector<webrtc::RtpExtension> recv_rtp_extensions_; std::vector<webrtc::RtpExtension> recv_rtp_extensions_;
// See reason for keeping track of the FlexFEC payload type separately in // See reason for keeping track of the FlexFEC payload type separately in

View File

@ -147,7 +147,7 @@ class WebRtcVideoEngineTest : public ::testing::Test {
explicit WebRtcVideoEngineTest(const char* field_trials) explicit WebRtcVideoEngineTest(const char* field_trials)
: override_field_trials_(field_trials), : override_field_trials_(field_trials),
call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))), call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
engine_() { engine_(&encoder_factory_, &decoder_factory_) {
std::vector<VideoCodec> engine_codecs = engine_.codecs(); std::vector<VideoCodec> engine_codecs = engine_.codecs();
RTC_DCHECK(!engine_codecs.empty()); RTC_DCHECK(!engine_codecs.empty());
bool codec_set = false; bool codec_set = false;
@ -172,11 +172,9 @@ class WebRtcVideoEngineTest : public ::testing::Test {
// present. // present.
cricket::VideoCodec GetEngineCodec(const std::string& name); cricket::VideoCodec GetEngineCodec(const std::string& name);
VideoMediaChannel* SetUpForExternalEncoderFactory( VideoMediaChannel* SetUpForExternalEncoderFactory();
cricket::WebRtcVideoEncoderFactory* encoder_factory);
VideoMediaChannel* SetUpForExternalDecoderFactory( VideoMediaChannel* SetUpForExternalDecoderFactory(
cricket::WebRtcVideoDecoderFactory* decoder_factory,
const std::vector<VideoCodec>& codecs); const std::vector<VideoCodec>& codecs);
void TestExtendedEncoderOveruse(bool use_external_encoder); void TestExtendedEncoderOveruse(bool use_external_encoder);
@ -186,6 +184,8 @@ class WebRtcVideoEngineTest : public ::testing::Test {
// Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
// initialized when the constructor is called. // initialized when the constructor is called.
std::unique_ptr<webrtc::Call> call_; std::unique_ptr<webrtc::Call> call_;
cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
cricket::FakeWebRtcVideoDecoderFactory decoder_factory_;
WebRtcVideoEngine engine_; WebRtcVideoEngine engine_;
VideoCodec default_codec_; VideoCodec default_codec_;
std::map<int, int> default_apt_rtx_types_; std::map<int, int> default_apt_rtx_types_;
@ -273,11 +273,9 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
// dtor is called. // dtor is called.
cricket::FakeVideoCapturer capturer; cricket::FakeVideoCapturer capturer;
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc))); EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
// Add CVO extension. // Add CVO extension.
@ -305,11 +303,9 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
// dtor is called. // dtor is called.
cricket::FakeVideoCapturer capturer; cricket::FakeVideoCapturer capturer;
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
// Add CVO extension. // Add CVO extension.
const int id = 1; const int id = 1;
cricket::VideoSendParameters parameters; cricket::VideoSendParameters parameters;
@ -329,12 +325,10 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) { TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
cricket::FakeVideoCapturer capturer; cricket::FakeVideoCapturer capturer;
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8"); encoder_factory_.AddSupportedVideoCodecType("VP9");
encoder_factory.AddSupportedVideoCodecType("VP9");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc))); EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
// Set capturer. // Set capturer.
@ -364,7 +358,6 @@ TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
} }
TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) { TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
engine_.Init();
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions())); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
@ -377,7 +370,6 @@ TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
} }
TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) { TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
engine_.Init();
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions())); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123))); EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
@ -386,16 +378,14 @@ TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
} }
TEST_F(WebRtcVideoEngineTest, UseExternalFactoryForVp8WhenSupported) { TEST_F(WebRtcVideoEngineTest, UseExternalFactoryForVp8WhenSupported) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
channel->OnReadyToSend(true); channel->OnReadyToSend(true);
EXPECT_TRUE( EXPECT_TRUE(
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
EXPECT_EQ(0, encoder_factory.GetNumCreatedEncoders()); EXPECT_EQ(0, encoder_factory_.GetNumCreatedEncoders());
EXPECT_TRUE(channel->SetSend(true)); EXPECT_TRUE(channel->SetSend(true));
cricket::FakeVideoCapturer capturer; cricket::FakeVideoCapturer capturer;
EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer)); EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
@ -403,11 +393,11 @@ TEST_F(WebRtcVideoEngineTest, UseExternalFactoryForVp8WhenSupported) {
capturer.Start(capturer.GetSupportedFormats()->front())); capturer.Start(capturer.GetSupportedFormats()->front()));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
// Sending one frame will have allocate the encoder. // Sending one frame will have allocate the encoder.
ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(1)); ASSERT_TRUE(encoder_factory_.WaitForCreatedVideoEncoders(1));
EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0, EXPECT_TRUE_WAIT(encoder_factory_.encoders()[0]->GetNumEncodedFrames() > 0,
kTimeout); kTimeout);
int num_created_encoders = encoder_factory.GetNumCreatedEncoders(); int num_created_encoders = encoder_factory_.GetNumCreatedEncoders();
EXPECT_EQ(num_created_encoders, 1); EXPECT_EQ(num_created_encoders, 1);
// Setting codecs of the same type should not reallocate any encoders // Setting codecs of the same type should not reallocate any encoders
@ -415,11 +405,11 @@ TEST_F(WebRtcVideoEngineTest, UseExternalFactoryForVp8WhenSupported) {
cricket::VideoSendParameters parameters; cricket::VideoSendParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8")); parameters.codecs.push_back(GetEngineCodec("VP8"));
EXPECT_TRUE(channel->SetSendParameters(parameters)); EXPECT_TRUE(channel->SetSendParameters(parameters));
EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders()); EXPECT_EQ(num_created_encoders, encoder_factory_.GetNumCreatedEncoders());
// Remove stream previously added to free the external encoder instance. // Remove stream previously added to free the external encoder instance.
EXPECT_TRUE(channel->RemoveSendStream(kSsrc)); EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
EXPECT_EQ(0u, encoder_factory.encoders().size()); EXPECT_EQ(0u, encoder_factory_.encoders().size());
} }
// Test that when an external encoder factory supports a codec we don't // Test that when an external encoder factory supports a codec we don't
@ -443,12 +433,9 @@ TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForExternalCodec) {
h264_high.params[kH264FmtpProfileLevelId] = *ProfileLevelIdToString( h264_high.params[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1)); ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodec(h264_constrained_baseline);
encoder_factory.AddSupportedVideoCodec(h264_constrained_baseline); encoder_factory_.AddSupportedVideoCodec(h264_constrained_high);
encoder_factory.AddSupportedVideoCodec(h264_constrained_high); encoder_factory_.AddSupportedVideoCodec(h264_high);
encoder_factory.AddSupportedVideoCodec(h264_high);
engine_.SetExternalEncoderFactory(&encoder_factory);
engine_.Init();
// First figure out what payload types the test codecs got assigned. // First figure out what payload types the test codecs got assigned.
const std::vector<cricket::VideoCodec> codecs = engine_.codecs(); const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
@ -464,15 +451,13 @@ TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForExternalCodec) {
void WebRtcVideoEngineTest::TestExtendedEncoderOveruse( void WebRtcVideoEngineTest::TestExtendedEncoderOveruse(
bool use_external_encoder) { bool use_external_encoder) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
encoder_factory.AddSupportedVideoCodecType("VP8");
std::unique_ptr<VideoMediaChannel> channel; std::unique_ptr<VideoMediaChannel> channel;
FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_)); FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
call_.reset(fake_call); call_.reset(fake_call);
if (use_external_encoder) { if (use_external_encoder) {
channel.reset(SetUpForExternalEncoderFactory(&encoder_factory)); encoder_factory_.AddSupportedVideoCodecType("VP8");
channel.reset(SetUpForExternalEncoderFactory());
} else { } else {
engine_.Init();
channel.reset( channel.reset(
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions())); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
} }
@ -500,11 +485,9 @@ TEST_F(WebRtcVideoEngineTest, DisablesFullEncoderTimeForNonExternalEncoders) {
#if !defined(RTC_DISABLE_VP9) #if !defined(RTC_DISABLE_VP9)
TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) { TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP9");
encoder_factory.AddSupportedVideoCodecType("VP9");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
EXPECT_TRUE( EXPECT_TRUE(
channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
@ -512,12 +495,10 @@ TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
#endif // !defined(RTC_DISABLE_VP9) #endif // !defined(RTC_DISABLE_VP9)
TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) { TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8");
FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_)); FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
call_.reset(fake_call); call_.reset(fake_call);
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
EXPECT_TRUE( EXPECT_TRUE(
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
@ -578,16 +559,12 @@ cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
return cricket::VideoCodec(); return cricket::VideoCodec();
} }
VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalEncoderFactory( VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalEncoderFactory() {
cricket::WebRtcVideoEncoderFactory* encoder_factory) {
engine_.SetExternalEncoderFactory(encoder_factory);
engine_.Init();
VideoMediaChannel* channel = VideoMediaChannel* channel =
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions());
cricket::VideoSendParameters parameters; cricket::VideoSendParameters parameters;
// We need to look up the codec in the engine to get the correct payload type. // We need to look up the codec in the engine to get the correct payload type.
for (const VideoCodec& codec : encoder_factory->supported_codecs()) for (const VideoCodec& codec : encoder_factory_.supported_codecs())
parameters.codecs.push_back(GetEngineCodec(codec.name)); parameters.codecs.push_back(GetEngineCodec(codec.name));
EXPECT_TRUE(channel->SetSendParameters(parameters)); EXPECT_TRUE(channel->SetSendParameters(parameters));
@ -596,11 +573,7 @@ VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalEncoderFactory(
} }
VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalDecoderFactory( VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalDecoderFactory(
cricket::WebRtcVideoDecoderFactory* decoder_factory,
const std::vector<VideoCodec>& codecs) { const std::vector<VideoCodec>& codecs) {
engine_.SetExternalDecoderFactory(decoder_factory);
engine_.Init();
VideoMediaChannel* channel = VideoMediaChannel* channel =
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions());
cricket::VideoRecvParameters parameters; cricket::VideoRecvParameters parameters;
@ -611,11 +584,9 @@ VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalDecoderFactory(
} }
TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) { TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3); std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
@ -629,15 +600,15 @@ TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
capturer.Start(capturer.GetSupportedFormats()->front())); capturer.Start(capturer.GetSupportedFormats()->front()));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2)); ASSERT_TRUE(encoder_factory_.WaitForCreatedVideoEncoders(2));
// Verify that encoders are configured for simulcast through adapter // Verify that encoders are configured for simulcast through adapter
// (increasing resolution and only configured to send one stream each). // (increasing resolution and only configured to send one stream each).
int prev_width = -1; int prev_width = -1;
for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) { for (size_t i = 0; i < encoder_factory_.encoders().size(); ++i) {
ASSERT_TRUE(encoder_factory.encoders()[i]->WaitForInitEncode()); ASSERT_TRUE(encoder_factory_.encoders()[i]->WaitForInitEncode());
webrtc::VideoCodec codec_settings = webrtc::VideoCodec codec_settings =
encoder_factory.encoders()[i]->GetCodecSettings(); encoder_factory_.encoders()[i]->GetCodecSettings();
EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams); EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
EXPECT_GT(codec_settings.width, prev_width); EXPECT_GT(codec_settings.width, prev_width);
prev_width = codec_settings.width; prev_width = codec_settings.width;
@ -646,33 +617,27 @@ TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, nullptr)); EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
channel.reset(); channel.reset();
ASSERT_EQ(0u, encoder_factory.encoders().size()); ASSERT_EQ(0u, encoder_factory_.encoders().size());
} }
TEST_F(WebRtcVideoEngineTest, ChannelWithExternalH264CanChangeToInternalVp8) { TEST_F(WebRtcVideoEngineTest, ChannelWithExternalH264CanChangeToInternalVp8) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("H264");
encoder_factory.AddSupportedVideoCodecType("H264");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
EXPECT_TRUE( EXPECT_TRUE(
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
ASSERT_EQ(1u, encoder_factory.encoders().size()); ASSERT_EQ(1u, encoder_factory_.encoders().size());
cricket::VideoSendParameters parameters; cricket::VideoSendParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8")); parameters.codecs.push_back(GetEngineCodec("VP8"));
EXPECT_TRUE(channel->SetSendParameters(parameters)); EXPECT_TRUE(channel->SetSendParameters(parameters));
ASSERT_EQ(0u, encoder_factory.encoders().size()); ASSERT_EQ(0u, encoder_factory_.encoders().size());
} }
TEST_F(WebRtcVideoEngineTest, TEST_F(WebRtcVideoEngineTest,
DontUseExternalEncoderFactoryForUnsupportedCodecs) { DontUseExternalEncoderFactoryForUnsupportedCodecs) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("H264");
encoder_factory.AddSupportedVideoCodecType("H264");
engine_.SetExternalEncoderFactory(&encoder_factory);
engine_.Init();
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions())); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
@ -683,17 +648,13 @@ TEST_F(WebRtcVideoEngineTest,
EXPECT_TRUE( EXPECT_TRUE(
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
// Make sure DestroyVideoEncoder was called on the factory. // Make sure DestroyVideoEncoder was called on the factory.
ASSERT_EQ(0u, encoder_factory.encoders().size()); ASSERT_EQ(0u, encoder_factory_.encoders().size());
} }
TEST_F(WebRtcVideoEngineTest, TEST_F(WebRtcVideoEngineTest,
UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) { UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8"); encoder_factory_.AddSupportedVideoCodecType("H264");
encoder_factory.AddSupportedVideoCodecType("H264");
engine_.SetExternalEncoderFactory(&encoder_factory);
engine_.Init();
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions())); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
@ -716,24 +677,20 @@ TEST_F(WebRtcVideoEngineTest,
capturer.Start(capturer.GetSupportedFormats()->front())); capturer.Start(capturer.GetSupportedFormats()->front()));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2)); ASSERT_TRUE(encoder_factory_.WaitForCreatedVideoEncoders(2));
ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode()); ASSERT_TRUE(encoder_factory_.encoders()[0]->WaitForInitEncode());
EXPECT_EQ(webrtc::kVideoCodecVP8, EXPECT_EQ(webrtc::kVideoCodecVP8,
encoder_factory.encoders()[0]->GetCodecSettings().codecType); encoder_factory_.encoders()[0]->GetCodecSettings().codecType);
channel.reset(); channel.reset();
// Make sure DestroyVideoEncoder was called on the factory. // Make sure DestroyVideoEncoder was called on the factory.
EXPECT_EQ(0u, encoder_factory.encoders().size()); EXPECT_EQ(0u, encoder_factory_.encoders().size());
} }
TEST_F(WebRtcVideoEngineTest, TEST_F(WebRtcVideoEngineTest,
DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) { DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8"); encoder_factory_.AddSupportedVideoCodecType("H264");
encoder_factory.AddSupportedVideoCodecType("H264");
engine_.SetExternalEncoderFactory(&encoder_factory);
engine_.Init();
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions())); engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
@ -743,7 +700,7 @@ TEST_F(WebRtcVideoEngineTest,
EXPECT_TRUE( EXPECT_TRUE(
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
ASSERT_EQ(1u, encoder_factory.encoders().size()); ASSERT_EQ(1u, encoder_factory_.encoders().size());
// Send a frame of 720p. This should trigger a "real" encoder initialization. // Send a frame of 720p. This should trigger a "real" encoder initialization.
cricket::VideoFormat format( cricket::VideoFormat format(
@ -752,21 +709,19 @@ TEST_F(WebRtcVideoEngineTest,
EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer)); EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format)); EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode()); ASSERT_TRUE(encoder_factory_.encoders()[0]->WaitForInitEncode());
EXPECT_EQ(webrtc::kVideoCodecH264, EXPECT_EQ(webrtc::kVideoCodecH264,
encoder_factory.encoders()[0]->GetCodecSettings().codecType); encoder_factory_.encoders()[0]->GetCodecSettings().codecType);
channel.reset(); channel.reset();
// Make sure DestroyVideoEncoder was called on the factory. // Make sure DestroyVideoEncoder was called on the factory.
ASSERT_EQ(0u, encoder_factory.encoders().size()); ASSERT_EQ(0u, encoder_factory_.encoders().size());
} }
TEST_F(WebRtcVideoEngineTest, SimulcastDisabledForH264) { TEST_F(WebRtcVideoEngineTest, SimulcastDisabledForH264) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("H264");
encoder_factory.AddSupportedVideoCodecType("H264");
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3); const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
EXPECT_TRUE( EXPECT_TRUE(
@ -780,9 +735,9 @@ TEST_F(WebRtcVideoEngineTest, SimulcastDisabledForH264) {
EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format)); EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_EQ(1u, encoder_factory.encoders().size()); ASSERT_EQ(1u, encoder_factory_.encoders().size());
FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0]; FakeWebRtcVideoEncoder* encoder = encoder_factory_.encoders()[0];
ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode()); ASSERT_TRUE(encoder_factory_.encoders()[0]->WaitForInitEncode());
EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType); EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams); EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, nullptr)); EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, nullptr));
@ -801,7 +756,6 @@ TEST_F(WebRtcVideoEngineTest,
}; };
// FlexFEC is not active without field trial. // FlexFEC is not active without field trial.
engine_.Init();
const std::vector<VideoCodec> codecs_before = engine_.codecs(); const std::vector<VideoCodec> codecs_before = engine_.codecs();
EXPECT_EQ(codecs_before.end(), std::find_if(codecs_before.begin(), EXPECT_EQ(codecs_before.end(), std::find_if(codecs_before.begin(),
codecs_before.end(), is_flexfec)); codecs_before.end(), is_flexfec));
@ -816,10 +770,7 @@ TEST_F(WebRtcVideoEngineTest,
// Test that external codecs are added to the end of the supported codec list. // Test that external codecs are added to the end of the supported codec list.
TEST_F(WebRtcVideoEngineTest, ReportSupportedExternalCodecs) { TEST_F(WebRtcVideoEngineTest, ReportSupportedExternalCodecs) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("FakeExternalCodec");
encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec");
engine_.SetExternalEncoderFactory(&encoder_factory);
engine_.Init();
std::vector<cricket::VideoCodec> codecs(engine_.codecs()); std::vector<cricket::VideoCodec> codecs(engine_.codecs());
ASSERT_GE(codecs.size(), 2u); ASSERT_GE(codecs.size(), 2u);
@ -835,42 +786,38 @@ TEST_F(WebRtcVideoEngineTest, ReportSupportedExternalCodecs) {
// does show up in the codec list after it was added. // does show up in the codec list after it was added.
TEST_F(WebRtcVideoEngineTest, ReportSupportedExternalCodecsWithAddedCodec) { TEST_F(WebRtcVideoEngineTest, ReportSupportedExternalCodecsWithAddedCodec) {
// Set up external encoder factory with first codec, and initialize engine. // Set up external encoder factory with first codec, and initialize engine.
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("FakeExternalCodec1");
encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec1");
engine_.SetExternalEncoderFactory(&encoder_factory);
engine_.Init();
// The first external codec will appear last in the vector. // The first external codec will appear last in the vector.
std::vector<cricket::VideoCodec> codecs_before(engine_.codecs()); std::vector<cricket::VideoCodec> codecs_before(engine_.codecs());
EXPECT_EQ("FakeExternalCodec1", codecs_before.back().name); EXPECT_EQ("FakeExternalCodec1", codecs_before.back().name);
// Add second codec. // Add second codec.
encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec2"); encoder_factory_.AddSupportedVideoCodecType("FakeExternalCodec2");
std::vector<cricket::VideoCodec> codecs_after(engine_.codecs()); std::vector<cricket::VideoCodec> codecs_after(engine_.codecs());
EXPECT_EQ(codecs_before.size() + 1, codecs_after.size()); EXPECT_EQ(codecs_before.size() + 1, codecs_after.size());
EXPECT_EQ("FakeExternalCodec2", codecs_after.back().name); EXPECT_EQ("FakeExternalCodec2", codecs_after.back().name);
} }
TEST_F(WebRtcVideoEngineTest, RegisterExternalDecodersIfSupported) { TEST_F(WebRtcVideoEngineTest, RegisterExternalDecodersIfSupported) {
cricket::FakeWebRtcVideoDecoderFactory decoder_factory; decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
cricket::VideoRecvParameters parameters; cricket::VideoRecvParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8")); parameters.codecs.push_back(GetEngineCodec("VP8"));
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs)); SetUpForExternalDecoderFactory(parameters.codecs));
EXPECT_TRUE( EXPECT_TRUE(
channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
ASSERT_EQ(1u, decoder_factory.decoders().size()); ASSERT_EQ(1u, decoder_factory_.decoders().size());
// Setting codecs of the same type should not reallocate the decoder. // Setting codecs of the same type should not reallocate the decoder.
EXPECT_TRUE(channel->SetRecvParameters(parameters)); EXPECT_TRUE(channel->SetRecvParameters(parameters));
EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders()); EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders());
// Remove stream previously added to free the external decoder instance. // Remove stream previously added to free the external decoder instance.
EXPECT_TRUE(channel->RemoveRecvStream(kSsrc)); EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
EXPECT_EQ(0u, decoder_factory.decoders().size()); EXPECT_EQ(0u, decoder_factory_.decoders().size());
} }
// Verifies that we can set up decoders that are not internally supported. // Verifies that we can set up decoders that are not internally supported.
@ -879,20 +826,17 @@ TEST_F(WebRtcVideoEngineTest, RegisterExternalH264DecoderIfSupported) {
// can't even query the WebRtcVideoDecoderFactory for supported codecs. // can't even query the WebRtcVideoDecoderFactory for supported codecs.
// For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
// codecs. // codecs.
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("H264");
encoder_factory.AddSupportedVideoCodecType("H264"); decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
engine_.SetExternalEncoderFactory(&encoder_factory);
cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
std::vector<cricket::VideoCodec> codecs; std::vector<cricket::VideoCodec> codecs;
codecs.push_back(GetEngineCodec("H264")); codecs.push_back(GetEngineCodec("H264"));
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
SetUpForExternalDecoderFactory(&decoder_factory, codecs)); SetUpForExternalDecoderFactory(codecs));
EXPECT_TRUE( EXPECT_TRUE(
channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
ASSERT_EQ(1u, decoder_factory.decoders().size()); ASSERT_EQ(1u, decoder_factory_.decoders().size());
} }
class WebRtcVideoChannelBaseTest class WebRtcVideoChannelBaseTest
@ -915,31 +859,28 @@ class WebRtcVideoChannelBaseTest
// Verifies that id given in stream params is passed to the decoder factory. // Verifies that id given in stream params is passed to the decoder factory.
TEST_F(WebRtcVideoEngineTest, StreamParamsIdPassedToDecoderFactory) { TEST_F(WebRtcVideoEngineTest, StreamParamsIdPassedToDecoderFactory) {
cricket::FakeWebRtcVideoDecoderFactory decoder_factory; decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
cricket::VideoRecvParameters parameters; cricket::VideoRecvParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8")); parameters.codecs.push_back(GetEngineCodec("VP8"));
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(
SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs)); SetUpForExternalDecoderFactory(parameters.codecs));
StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc); StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc);
sp.id = "FakeStreamParamsId"; sp.id = "FakeStreamParamsId";
EXPECT_TRUE(channel->AddRecvStream(sp)); EXPECT_TRUE(channel->AddRecvStream(sp));
EXPECT_EQ(1u, decoder_factory.decoders().size()); EXPECT_EQ(1u, decoder_factory_.decoders().size());
std::vector<cricket::VideoDecoderParams> params = decoder_factory.params(); std::vector<cricket::VideoDecoderParams> params = decoder_factory_.params();
ASSERT_EQ(1u, params.size()); ASSERT_EQ(1u, params.size());
EXPECT_EQ(sp.id, params[0].receive_stream_id); EXPECT_EQ(sp.id, params[0].receive_stream_id);
} }
TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) { TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory_.AddSupportedVideoCodecType("VP8");
encoder_factory.AddSupportedVideoCodecType("VP8");
std::unique_ptr<FakeCall> fake_call( std::unique_ptr<FakeCall> fake_call(
new FakeCall(webrtc::Call::Config(&event_log_))); new FakeCall(webrtc::Call::Config(&event_log_)));
std::unique_ptr<VideoMediaChannel> channel( std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
SetUpForExternalEncoderFactory(&encoder_factory));
ASSERT_TRUE( ASSERT_TRUE(
channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
cricket::VideoCodec codec = GetEngineCodec("VP8"); cricket::VideoCodec codec = GetEngineCodec("VP8");
@ -956,14 +897,14 @@ TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
EXPECT_EQ(cricket::CS_RUNNING, EXPECT_EQ(cricket::CS_RUNNING,
capturer.Start(capturer.GetSupportedFormats()->front())); capturer.Start(capturer.GetSupportedFormats()->front()));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(1)); ASSERT_TRUE(encoder_factory_.WaitForCreatedVideoEncoders(1));
EXPECT_EQ(webrtc::kRealtimeVideo, EXPECT_EQ(webrtc::kRealtimeVideo,
encoder_factory.encoders().back()->GetCodecSettings().mode); encoder_factory_.encoders().back()->GetCodecSettings().mode);
EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer)); EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
// No change in content type, keep current encoder. // No change in content type, keep current encoder.
EXPECT_EQ(1, encoder_factory.GetNumCreatedEncoders()); EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders());
options.is_screencast.emplace(true); options.is_screencast.emplace(true);
EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer)); EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
@ -971,14 +912,14 @@ TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
// Change to screen content, recreate encoder. For the simulcast encoder // Change to screen content, recreate encoder. For the simulcast encoder
// adapter case, this will result in two calls since InitEncode triggers a // adapter case, this will result in two calls since InitEncode triggers a
// a new instance. // a new instance.
ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2)); ASSERT_TRUE(encoder_factory_.WaitForCreatedVideoEncoders(2));
EXPECT_EQ(webrtc::kScreensharing, EXPECT_EQ(webrtc::kScreensharing,
encoder_factory.encoders().back()->GetCodecSettings().mode); encoder_factory_.encoders().back()->GetCodecSettings().mode);
EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer)); EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
// Still screen content, no need to update encoder. // Still screen content, no need to update encoder.
EXPECT_EQ(2, encoder_factory.GetNumCreatedEncoders()); EXPECT_EQ(2, encoder_factory_.GetNumCreatedEncoders());
options.is_screencast.emplace(false); options.is_screencast.emplace(false);
options.video_noise_reduction.emplace(false); options.video_noise_reduction.emplace(false);
@ -986,13 +927,13 @@ TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
// Change back to regular video content, update encoder. Also change // Change back to regular video content, update encoder. Also change
// a non |is_screencast| option just to verify it doesn't affect recreation. // a non |is_screencast| option just to verify it doesn't affect recreation.
EXPECT_TRUE(capturer.CaptureFrame()); EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(3)); ASSERT_TRUE(encoder_factory_.WaitForCreatedVideoEncoders(3));
EXPECT_EQ(webrtc::kRealtimeVideo, EXPECT_EQ(webrtc::kRealtimeVideo,
encoder_factory.encoders().back()->GetCodecSettings().mode); encoder_factory_.encoders().back()->GetCodecSettings().mode);
// Remove stream previously added to free the external encoder instance. // Remove stream previously added to free the external encoder instance.
EXPECT_TRUE(channel->RemoveSendStream(kSsrc)); EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
EXPECT_EQ(0u, encoder_factory.encoders().size()); EXPECT_EQ(0u, encoder_factory_.encoders().size());
} }
#define WEBRTC_BASE_TEST(test) \ #define WEBRTC_BASE_TEST(test) \
@ -1060,7 +1001,6 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
: WebRtcVideoEngineTest(field_trials), last_ssrc_(0) {} : WebRtcVideoEngineTest(field_trials), last_ssrc_(0) {}
void SetUp() override { void SetUp() override {
fake_call_.reset(new FakeCall(webrtc::Call::Config(&event_log_))); fake_call_.reset(new FakeCall(webrtc::Call::Config(&event_log_)));
engine_.Init();
channel_.reset(engine_.CreateChannel(fake_call_.get(), GetMediaConfig(), channel_.reset(engine_.CreateChannel(fake_call_.get(), GetMediaConfig(),
VideoOptions())); VideoOptions()));
channel_->OnReadyToSend(true); channel_->OnReadyToSend(true);
@ -1979,19 +1919,11 @@ class Vp9SettingsTest : public WebRtcVideoChannelTest {
virtual ~Vp9SettingsTest() {} virtual ~Vp9SettingsTest() {}
protected: protected:
void SetUp() override {
engine_.SetExternalEncoderFactory(&encoder_factory_);
WebRtcVideoChannelTest::SetUp();
}
void TearDown() override { void TearDown() override {
// Remove references to encoder_factory_ since this will be destroyed // Remove references to encoder_factory_ since this will be destroyed
// before channel_ and engine_. // before channel_ and engine_.
ASSERT_TRUE(channel_->SetSendParameters(send_parameters_)); ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
} }
cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
}; };
TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) { TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
@ -4498,10 +4430,11 @@ TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
class WebRtcVideoChannelSimulcastTest : public testing::Test { class WebRtcVideoChannelSimulcastTest : public testing::Test {
public: public:
WebRtcVideoChannelSimulcastTest() WebRtcVideoChannelSimulcastTest()
: fake_call_(webrtc::Call::Config(&event_log_)), last_ssrc_(0) {} : fake_call_(webrtc::Call::Config(&event_log_)),
engine_(&encoder_factory_, &decoder_factory_),
last_ssrc_(0) {}
void SetUp() override { void SetUp() override {
engine_.Init();
channel_.reset( channel_.reset(
engine_.CreateChannel(&fake_call_, GetMediaConfig(), VideoOptions())); engine_.CreateChannel(&fake_call_, GetMediaConfig(), VideoOptions()));
channel_->OnReadyToSend(true); channel_->OnReadyToSend(true);
@ -4657,6 +4590,8 @@ class WebRtcVideoChannelSimulcastTest : public testing::Test {
webrtc::RtcEventLogNullImpl event_log_; webrtc::RtcEventLogNullImpl event_log_;
FakeCall fake_call_; FakeCall fake_call_;
cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
cricket::FakeWebRtcVideoDecoderFactory decoder_factory_;
WebRtcVideoEngine engine_; WebRtcVideoEngine engine_;
std::unique_ptr<VideoMediaChannel> channel_; std::unique_ptr<VideoMediaChannel> channel_;
uint32_t last_ssrc_; uint32_t last_ssrc_;