RtpSenderInterface::SetEncoderSelector

This cl/ adds a way of setting an EncoderSelector on a specific
RtpSenderInterface. This makes it possible to easily use different
EncoderSelector on different streams within the same or different PeerConnections.

The cl/ is almost identical to the impl. of RtpSenderInterface::SetFrameEncryptor.

Iff a EncoderSelector is set on the RtpSender, it will take precedence
over the VideoEncoderFactory::GetEncoderSelector.

Bug: webrtc:14122
Change-Id: Ief4f7c06df7f1ef4ce3245de304a48e9de0ad587
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/264542
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37150}
This commit is contained in:
Jonas Oreland 2022-06-08 11:25:46 +02:00 committed by WebRTC LUCI CQ
parent 86c452ac5a
commit 6545516a14
18 changed files with 247 additions and 8 deletions

View file

@ -217,6 +217,7 @@ rtc_library("libjingle_peerconnection_api") {
"video:video_bitrate_allocator_factory", "video:video_bitrate_allocator_factory",
"video:video_frame", "video:video_frame",
"video:video_rtp_headers", "video:video_rtp_headers",
"video_codecs:video_codecs_api",
# Basically, don't add stuff here. You might break sensitive downstream # Basically, don't add stuff here. You might break sensitive downstream
# targets like pnacl. API should not depend on anything outside of this # targets like pnacl. API should not depend on anything outside of this
@ -968,6 +969,17 @@ if (rtc_include_tests) {
] ]
} }
rtc_library("mock_encoder_selector") {
visibility = [ "*" ]
testonly = true
sources = [ "test/mock_encoder_selector.h" ]
deps = [
":libjingle_peerconnection_api",
"../api/video_codecs:video_codecs_api",
"../test:test_support",
]
}
rtc_library("fake_frame_encryptor") { rtc_library("fake_frame_encryptor") {
visibility = [ "*" ] visibility = [ "*" ]
testonly = true testonly = true

View file

@ -14,6 +14,7 @@
#ifndef API_RTP_SENDER_INTERFACE_H_ #ifndef API_RTP_SENDER_INTERFACE_H_
#define API_RTP_SENDER_INTERFACE_H_ #define API_RTP_SENDER_INTERFACE_H_
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -26,6 +27,7 @@
#include "api/rtc_error.h" #include "api/rtc_error.h"
#include "api/rtp_parameters.h" #include "api/rtp_parameters.h"
#include "api/scoped_refptr.h" #include "api/scoped_refptr.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "rtc_base/ref_count.h" #include "rtc_base/ref_count.h"
#include "rtc_base/system/rtc_export.h" #include "rtc_base/system/rtc_export.h"
@ -96,6 +98,12 @@ class RTC_EXPORT RtpSenderInterface : public rtc::RefCountInterface {
virtual void SetEncoderToPacketizerFrameTransformer( virtual void SetEncoderToPacketizerFrameTransformer(
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer); rtc::scoped_refptr<FrameTransformerInterface> frame_transformer);
// Sets a user defined encoder selector.
// Overrides selector that is (optionally) provided by VideoEncoderFactory.
virtual void SetEncoderSelector(
std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
encoder_selector) {}
protected: protected:
~RtpSenderInterface() override = default; ~RtpSenderInterface() override = default;
}; };

View file

@ -0,0 +1,42 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef API_TEST_MOCK_ENCODER_SELECTOR_H_
#define API_TEST_MOCK_ENCODER_SELECTOR_H_
#include "api/video_codecs/video_encoder_factory.h"
#include "test/gmock.h"
namespace webrtc {
class MockEncoderSelector
: public VideoEncoderFactory::EncoderSelectorInterface {
public:
MOCK_METHOD(void,
OnCurrentEncoder,
(const SdpVideoFormat& format),
(override));
MOCK_METHOD(absl::optional<SdpVideoFormat>,
OnAvailableBitrate,
(const DataRate& rate),
(override));
MOCK_METHOD(absl::optional<SdpVideoFormat>,
OnResolutionChange,
(const RenderResolution& resolution),
(override));
MOCK_METHOD(absl::optional<SdpVideoFormat>, OnEncoderBroken, (), (override));
};
} // namespace webrtc
#endif // API_TEST_MOCK_ENCODER_SELECTOR_H_

View file

@ -34,7 +34,10 @@ class VideoEncoderFactory {
}; };
// An injectable class that is continuously updated with encoding conditions // An injectable class that is continuously updated with encoding conditions
// and selects the best encoder given those conditions. // and selects the best encoder given those conditions. An implementation is
// typically stateful to avoid toggling between different encoders, which is
// costly due to recreation of objects, a new codec will always start with a
// key-frame.
class EncoderSelectorInterface { class EncoderSelectorInterface {
public: public:
virtual ~EncoderSelectorInterface() {} virtual ~EncoderSelectorInterface() {}
@ -96,6 +99,22 @@ class VideoEncoderFactory {
virtual std::unique_ptr<VideoEncoder> CreateVideoEncoder( virtual std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) = 0; const SdpVideoFormat& format) = 0;
// This method creates a EncoderSelector to use for a VideoSendStream.
// (and hence should probably been called CreateEncoderSelector()).
//
// Note: This method is unsuitable if encoding several streams that
// are using same VideoEncoderFactory (either by several streams in one
// PeerConnection or streams with different PeerConnection but same
// PeerConnectionFactory). This is due to the fact that the method is not
// given any stream identifier, nor is the EncoderSelectorInterface given any
// stream identifiers, i.e one does not know which stream is being encoded
// with help of the selector.
//
// In such scenario, the `RtpSenderInterface::SetEncoderSelector` is
// recommended.
//
// TODO(bugs.webrtc.org:14122): Deprecate and remove in favor of
// `RtpSenderInterface::SetEncoderSelector`.
virtual std::unique_ptr<EncoderSelectorInterface> GetEncoderSelector() const { virtual std::unique_ptr<EncoderSelectorInterface> GetEncoderSelector() const {
return nullptr; return nullptr;
} }

View file

@ -190,6 +190,11 @@ class VideoSendStream {
// default. // default.
rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor; rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor;
// An optional encoder selector provided by the user.
// Overrides VideoEncoderFactory::GetEncoderSelector().
// Owned by RtpSenderBase.
VideoEncoderFactory::EncoderSelectorInterface* encoder_selector = nullptr;
// Per PeerConnection cryptography options. // Per PeerConnection cryptography options.
CryptoOptions crypto_options; CryptoOptions crypto_options;

View file

@ -587,6 +587,7 @@ if (rtc_include_tests) {
":rtc_simulcast_encoder_adapter", ":rtc_simulcast_encoder_adapter",
"../api:create_simulcast_test_fixture_api", "../api:create_simulcast_test_fixture_api",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
"../api:mock_encoder_selector",
"../api:mock_video_bitrate_allocator", "../api:mock_video_bitrate_allocator",
"../api:mock_video_bitrate_allocator_factory", "../api:mock_video_bitrate_allocator_factory",
"../api:mock_video_codec_factory", "../api:mock_video_codec_factory",

View file

@ -34,6 +34,7 @@
#include "api/video/video_source_interface.h" #include "api/video/video_source_interface.h"
#include "api/video/video_timing.h" #include "api/video/video_timing.h"
#include "api/video_codecs/video_encoder_config.h" #include "api/video_codecs/video_encoder_config.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "call/video_receive_stream.h" #include "call/video_receive_stream.h"
#include "common_video/include/quality_limitation_reason.h" #include "common_video/include/quality_limitation_reason.h"
#include "media/base/codec.h" #include "media/base/codec.h"
@ -244,6 +245,13 @@ class MediaChannel {
// Enable network condition based codec switching. // Enable network condition based codec switching.
virtual void SetVideoCodecSwitchingEnabled(bool enabled); virtual void SetVideoCodecSwitchingEnabled(bool enabled);
// note: The encoder_selector object must remain valid for the lifetime of the
// MediaChannel, unless replaced.
virtual void SetEncoderSelector(
uint32_t ssrc,
webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector) {
}
// Base method to send packet using NetworkInterface. // Base method to send packet using NetworkInterface.
bool SendPacket(rtc::CopyOnWriteBuffer* packet, bool SendPacket(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketOptions& options); const rtc::PacketOptions& options);

View file

@ -1942,6 +1942,18 @@ void WebRtcVideoChannel::SetFrameEncryptor(
} }
} }
void WebRtcVideoChannel::SetEncoderSelector(
uint32_t ssrc,
webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector) {
RTC_DCHECK_RUN_ON(&thread_checker_);
auto matching_stream = send_streams_.find(ssrc);
if (matching_stream != send_streams_.end()) {
matching_stream->second->SetEncoderSelector(encoder_selector);
} else {
RTC_LOG(LS_ERROR) << "No stream found to attach encoder selector";
}
}
void WebRtcVideoChannel::SetVideoCodecSwitchingEnabled(bool enabled) { void WebRtcVideoChannel::SetVideoCodecSwitchingEnabled(bool enabled) {
RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK_RUN_ON(&thread_checker_);
allow_codec_switching_ = enabled; allow_codec_switching_ = enabled;
@ -2388,6 +2400,18 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetFrameEncryptor(
} }
} }
void WebRtcVideoChannel::WebRtcVideoSendStream::SetEncoderSelector(
webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector) {
RTC_DCHECK_RUN_ON(&thread_checker_);
parameters_.config.encoder_selector = encoder_selector;
if (stream_) {
RTC_LOG(LS_INFO)
<< "RecreateWebRtcStream (send) because of SetEncoderSelector, ssrc="
<< parameters_.config.rtp.ssrcs[0];
RecreateWebRtcStream();
}
}
void WebRtcVideoChannel::WebRtcVideoSendStream::UpdateSendState() { void WebRtcVideoChannel::WebRtcVideoSendStream::UpdateSendState() {
RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK_RUN_ON(&thread_checker_);
if (sending_) { if (sending_) {

View file

@ -191,6 +191,12 @@ class WebRtcVideoChannel : public VideoMediaChannel,
rtc::scoped_refptr<webrtc::FrameEncryptorInterface> rtc::scoped_refptr<webrtc::FrameEncryptorInterface>
frame_encryptor) override; frame_encryptor) override;
// note: The encoder_selector object must remain valid for the lifetime of the
// MediaChannel, unless replaced.
void SetEncoderSelector(uint32_t ssrc,
webrtc::VideoEncoderFactory::EncoderSelectorInterface*
encoder_selector) override;
void SetVideoCodecSwitchingEnabled(bool enabled) override; void SetVideoCodecSwitchingEnabled(bool enabled) override;
bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override; bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override;
@ -351,6 +357,12 @@ class WebRtcVideoChannel : public VideoMediaChannel,
bool SetVideoSend(const VideoOptions* options, bool SetVideoSend(const VideoOptions* options,
rtc::VideoSourceInterface<webrtc::VideoFrame>* source); rtc::VideoSourceInterface<webrtc::VideoFrame>* source);
// note: The encoder_selector object must remain valid for the lifetime of
// the MediaChannel, unless replaced.
void SetEncoderSelector(
webrtc::VideoEncoderFactory::EncoderSelectorInterface*
encoder_selector);
void SetSend(bool send); void SetSend(bool send);
const std::vector<uint32_t>& GetSsrcs() const; const std::vector<uint32_t>& GetSsrcs() const;

View file

@ -23,6 +23,7 @@
#include "api/rtc_event_log/rtc_event_log.h" #include "api/rtc_event_log/rtc_event_log.h"
#include "api/rtp_parameters.h" #include "api/rtp_parameters.h"
#include "api/task_queue/default_task_queue_factory.h" #include "api/task_queue/default_task_queue_factory.h"
#include "api/test/mock_encoder_selector.h"
#include "api/test/mock_video_bitrate_allocator.h" #include "api/test/mock_video_bitrate_allocator.h"
#include "api/test/mock_video_bitrate_allocator_factory.h" #include "api/test/mock_video_bitrate_allocator_factory.h"
#include "api/test/mock_video_decoder_factory.h" #include "api/test/mock_video_decoder_factory.h"
@ -8983,4 +8984,29 @@ TEST_F(WebRtcVideoChannelTest, SetsRidsOnSendStream) {
EXPECT_THAT(config.rtp.rids, ElementsAreArray(rids)); EXPECT_THAT(config.rtp.rids, ElementsAreArray(rids));
} }
TEST_F(WebRtcVideoChannelBaseTest, EncoderSelectorSwitchCodec) {
VideoCodec vp9 = GetEngineCodec("VP9");
cricket::VideoSendParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP8"));
parameters.codecs.push_back(vp9);
EXPECT_TRUE(channel_->SetSendParameters(parameters));
channel_->SetSend(true);
VideoCodec codec;
ASSERT_TRUE(channel_->GetSendCodec(&codec));
EXPECT_EQ("VP8", codec.name);
webrtc::MockEncoderSelector encoder_selector;
EXPECT_CALL(encoder_selector, OnAvailableBitrate)
.WillRepeatedly(Return(webrtc::SdpVideoFormat("VP9")));
channel_->SetEncoderSelector(kSsrc, &encoder_selector);
rtc::Thread::Current()->ProcessMessages(30);
ASSERT_TRUE(channel_->GetSendCodec(&codec));
EXPECT_EQ("VP9", codec.name);
}
} // namespace cricket } // namespace cricket

View file

@ -2343,6 +2343,7 @@ if (rtc_include_tests && !build_with_chromium) {
"../api:libjingle_logging_api", "../api:libjingle_logging_api",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
"../api:media_stream_interface", "../api:media_stream_interface",
"../api:mock_encoder_selector",
"../api:mock_video_track", "../api:mock_video_track",
"../api:packet_socket_factory", "../api:packet_socket_factory",
"../api:priority", "../api:priority",

View file

@ -49,6 +49,7 @@
#include "api/stats/rtc_stats.h" #include "api/stats/rtc_stats.h"
#include "api/stats/rtc_stats_report.h" #include "api/stats/rtc_stats_report.h"
#include "api/stats/rtcstats_objects.h" #include "api/stats/rtcstats_objects.h"
#include "api/test/mock_encoder_selector.h"
#include "api/transport/rtp/rtp_source.h" #include "api/transport/rtp/rtp_source.h"
#include "api/uma_metrics.h" #include "api/uma_metrics.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
@ -3593,6 +3594,35 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan,
callee_track->state()); callee_track->state());
} }
TEST_P(PeerConnectionIntegrationTest, EndToEndRtpSenderVideoEncoderSelector) {
ASSERT_TRUE(
CreateOneDirectionalPeerConnectionWrappers(/*caller_to_callee=*/true));
ConnectFakeSignaling();
// Add one-directional video, from caller to callee.
rtc::scoped_refptr<webrtc::VideoTrackInterface> caller_track =
caller()->CreateLocalVideoTrack();
auto sender = caller()->AddTrack(caller_track);
PeerConnectionInterface::RTCOfferAnswerOptions options;
options.offer_to_receive_video = 0;
caller()->SetOfferAnswerOptions(options);
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
std::unique_ptr<MockEncoderSelector> encoder_selector =
std::make_unique<MockEncoderSelector>();
EXPECT_CALL(*encoder_selector, OnCurrentEncoder);
sender->SetEncoderSelector(std::move(encoder_selector));
// Expect video to be received in one direction.
MediaExpectations media_expectations;
media_expectations.CallerExpectsNoVideo();
media_expectations.CalleeExpectsSomeVideo();
EXPECT_TRUE(ExpectNewFrames(media_expectations));
}
} // namespace } // namespace
} // namespace webrtc } // namespace webrtc

View file

@ -132,6 +132,23 @@ void RtpSenderBase::SetFrameEncryptor(
} }
} }
void RtpSenderBase::SetEncoderSelector(
std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
encoder_selector) {
RTC_DCHECK_RUN_ON(signaling_thread_);
encoder_selector_ = std::move(encoder_selector);
SetEncoderSelectorOnChannel();
}
void RtpSenderBase::SetEncoderSelectorOnChannel() {
RTC_DCHECK_RUN_ON(signaling_thread_);
if (media_channel_ && ssrc_ && !stopped_) {
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
media_channel_->SetEncoderSelector(ssrc_, encoder_selector_.get());
});
}
}
void RtpSenderBase::SetMediaChannel(cricket::MediaChannel* media_channel) { void RtpSenderBase::SetMediaChannel(cricket::MediaChannel* media_channel) {
RTC_DCHECK(media_channel == nullptr || RTC_DCHECK(media_channel == nullptr ||
media_channel->media_type() == media_type()); media_channel->media_type() == media_type());
@ -321,6 +338,9 @@ void RtpSenderBase::SetSsrc(uint32_t ssrc) {
if (frame_transformer_) { if (frame_transformer_) {
SetEncoderToPacketizerFrameTransformer(frame_transformer_); SetEncoderToPacketizerFrameTransformer(frame_transformer_);
} }
if (encoder_selector_) {
SetEncoderSelectorOnChannel();
}
} }
void RtpSenderBase::Stop() { void RtpSenderBase::Stop() {

View file

@ -185,6 +185,12 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
void SetEncoderToPacketizerFrameTransformer( void SetEncoderToPacketizerFrameTransformer(
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) override; rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) override;
void SetEncoderSelector(
std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
encoder_selector) override;
void SetEncoderSelectorOnChannel();
void SetTransceiverAsStopped() override { void SetTransceiverAsStopped() override {
RTC_DCHECK_RUN_ON(signaling_thread_); RTC_DCHECK_RUN_ON(signaling_thread_);
is_transceiver_stopped_ = true; is_transceiver_stopped_ = true;
@ -247,6 +253,8 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
SetStreamsObserver* set_streams_observer_ = nullptr; SetStreamsObserver* set_streams_observer_ = nullptr;
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer_; rtc::scoped_refptr<FrameTransformerInterface> frame_transformer_;
std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
encoder_selector_;
}; };
// LocalAudioSinkAdapter receives data callback as a sink to the local // LocalAudioSinkAdapter receives data callback as a sink to the local

View file

@ -11,6 +11,7 @@
#ifndef PC_RTP_SENDER_PROXY_H_ #ifndef PC_RTP_SENDER_PROXY_H_
#define PC_RTP_SENDER_PROXY_H_ #define PC_RTP_SENDER_PROXY_H_
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -44,6 +45,9 @@ PROXY_METHOD1(void, SetStreams, const std::vector<std::string>&)
PROXY_METHOD1(void, PROXY_METHOD1(void,
SetEncoderToPacketizerFrameTransformer, SetEncoderToPacketizerFrameTransformer,
rtc::scoped_refptr<FrameTransformerInterface>) rtc::scoped_refptr<FrameTransformerInterface>)
PROXY_METHOD1(void,
SetEncoderSelector,
std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>)
END_PROXY_MAP(RtpSender) END_PROXY_MAP(RtpSender)
} // namespace webrtc } // namespace webrtc

View file

@ -115,7 +115,8 @@ std::unique_ptr<VideoStreamEncoder> CreateVideoStreamEncoder(
const VideoStreamEncoderSettings& encoder_settings, const VideoStreamEncoderSettings& encoder_settings,
VideoStreamEncoder::BitrateAllocationCallbackType VideoStreamEncoder::BitrateAllocationCallbackType
bitrate_allocation_callback_type, bitrate_allocation_callback_type,
const FieldTrialsView& field_trials) { const FieldTrialsView& field_trials,
webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector) {
std::unique_ptr<TaskQueueBase, TaskQueueDeleter> encoder_queue = std::unique_ptr<TaskQueueBase, TaskQueueDeleter> encoder_queue =
task_queue_factory->CreateTaskQueue("EncoderQueue", task_queue_factory->CreateTaskQueue("EncoderQueue",
TaskQueueFactory::Priority::NORMAL); TaskQueueFactory::Priority::NORMAL);
@ -125,7 +126,8 @@ std::unique_ptr<VideoStreamEncoder> CreateVideoStreamEncoder(
std::make_unique<OveruseFrameDetector>(stats_proxy, field_trials), std::make_unique<OveruseFrameDetector>(stats_proxy, field_trials),
FrameCadenceAdapterInterface::Create(clock, encoder_queue_ptr, FrameCadenceAdapterInterface::Create(clock, encoder_queue_ptr,
field_trials), field_trials),
std::move(encoder_queue), bitrate_allocation_callback_type, field_trials); std::move(encoder_queue), bitrate_allocation_callback_type, field_trials,
encoder_selector);
} }
} // namespace } // namespace
@ -160,7 +162,8 @@ VideoSendStream::VideoSendStream(
&stats_proxy_, &stats_proxy_,
config_.encoder_settings, config_.encoder_settings,
GetBitrateAllocationCallbackType(config_, field_trials), GetBitrateAllocationCallbackType(config_, field_trials),
field_trials)), field_trials,
config_.encoder_selector)),
encoder_feedback_( encoder_feedback_(
clock, clock,
config_.rtp.ssrcs, config_.rtp.ssrcs,

View file

@ -615,7 +615,8 @@ VideoStreamEncoder::VideoStreamEncoder(
std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter> std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>
encoder_queue, encoder_queue,
BitrateAllocationCallbackType allocation_cb_type, BitrateAllocationCallbackType allocation_cb_type,
const FieldTrialsView& field_trials) const FieldTrialsView& field_trials,
webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector)
: field_trials_(field_trials), : field_trials_(field_trials),
worker_queue_(TaskQueueBase::Current()), worker_queue_(TaskQueueBase::Current()),
number_of_cores_(number_of_cores), number_of_cores_(number_of_cores),
@ -623,7 +624,14 @@ VideoStreamEncoder::VideoStreamEncoder(
settings_(settings), settings_(settings),
allocation_cb_type_(allocation_cb_type), allocation_cb_type_(allocation_cb_type),
rate_control_settings_(RateControlSettings::ParseFromFieldTrials()), rate_control_settings_(RateControlSettings::ParseFromFieldTrials()),
encoder_selector_(settings.encoder_factory->GetEncoderSelector()), encoder_selector_from_constructor_(encoder_selector),
encoder_selector_from_factory_(
encoder_selector_from_constructor_
? nullptr
: settings.encoder_factory->GetEncoderSelector()),
encoder_selector_(encoder_selector_from_constructor_
? encoder_selector_from_constructor_
: encoder_selector_from_factory_.get()),
encoder_stats_observer_(encoder_stats_observer), encoder_stats_observer_(encoder_stats_observer),
cadence_callback_(*this), cadence_callback_(*this),
frame_cadence_adapter_(std::move(frame_cadence_adapter)), frame_cadence_adapter_(std::move(frame_cadence_adapter)),

View file

@ -81,7 +81,9 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter> std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>
encoder_queue, encoder_queue,
BitrateAllocationCallbackType allocation_cb_type, BitrateAllocationCallbackType allocation_cb_type,
const FieldTrialsView& field_trials); const FieldTrialsView& field_trials,
webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector =
nullptr);
~VideoStreamEncoder() override; ~VideoStreamEncoder() override;
VideoStreamEncoder(const VideoStreamEncoder&) = delete; VideoStreamEncoder(const VideoStreamEncoder&) = delete;
@ -262,8 +264,14 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
const BitrateAllocationCallbackType allocation_cb_type_; const BitrateAllocationCallbackType allocation_cb_type_;
const RateControlSettings rate_control_settings_; const RateControlSettings rate_control_settings_;
webrtc::VideoEncoderFactory::EncoderSelectorInterface* const
encoder_selector_from_constructor_;
std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface> const std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface> const
encoder_selector_; encoder_selector_from_factory_;
// Pointing to either encoder_selector_from_constructor_ or
// encoder_selector_from_factory_ but can be nullptr.
VideoEncoderFactory::EncoderSelectorInterface* const encoder_selector_;
VideoStreamEncoderObserver* const encoder_stats_observer_; VideoStreamEncoderObserver* const encoder_stats_observer_;
// Adapter that avoids public inheritance of the cadence adapter's callback // Adapter that avoids public inheritance of the cadence adapter's callback
// interface. // interface.