WebRTC-DeprecateGlobalFieldTrialString/Enabled/ - part 10/inf
This patch takes a stab at modules/video_coding, but reaches only about half. Bug: webrtc:10335 Change-Id: I0d47d0468b818145470c51ae4e8e75ff58d499ae Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/256112 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Jonas Oreland <jonaso@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36335}
This commit is contained in:
parent
2ff465f506
commit
e02f9eedb3
@ -267,6 +267,7 @@ rtc_library("video_stream_decoder_create") {
|
|||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":video_stream_decoder",
|
":video_stream_decoder",
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
"../../rtc_base:rtc_base_approved",
|
"../../rtc_base:rtc_base_approved",
|
||||||
"../../video:video_stream_decoder_impl",
|
"../../video:video_stream_decoder_impl",
|
||||||
"../task_queue",
|
"../task_queue",
|
||||||
|
|||||||
@ -20,10 +20,13 @@ std::unique_ptr<VideoStreamDecoderInterface> CreateVideoStreamDecoder(
|
|||||||
VideoStreamDecoderInterface::Callbacks* callbacks,
|
VideoStreamDecoderInterface::Callbacks* callbacks,
|
||||||
VideoDecoderFactory* decoder_factory,
|
VideoDecoderFactory* decoder_factory,
|
||||||
TaskQueueFactory* task_queue_factory,
|
TaskQueueFactory* task_queue_factory,
|
||||||
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings) {
|
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings,
|
||||||
return std::make_unique<VideoStreamDecoderImpl>(callbacks, decoder_factory,
|
// TODO(jonaso, webrtc:10335): Consider what to do with factories
|
||||||
task_queue_factory,
|
// vs. field trials.
|
||||||
std::move(decoder_settings));
|
const WebRtcKeyValueConfig* field_trials) {
|
||||||
|
return std::make_unique<VideoStreamDecoderImpl>(
|
||||||
|
callbacks, decoder_factory, task_queue_factory,
|
||||||
|
std::move(decoder_settings), field_trials);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "api/task_queue/task_queue_factory.h"
|
#include "api/task_queue/task_queue_factory.h"
|
||||||
#include "api/video/video_stream_decoder.h"
|
#include "api/video/video_stream_decoder.h"
|
||||||
#include "api/video_codecs/sdp_video_format.h"
|
#include "api/video_codecs/sdp_video_format.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
// The `decoder_settings` parameter is a map between:
|
// The `decoder_settings` parameter is a map between:
|
||||||
@ -28,7 +29,8 @@ std::unique_ptr<VideoStreamDecoderInterface> CreateVideoStreamDecoder(
|
|||||||
VideoStreamDecoderInterface::Callbacks* callbacks,
|
VideoStreamDecoderInterface::Callbacks* callbacks,
|
||||||
VideoDecoderFactory* decoder_factory,
|
VideoDecoderFactory* decoder_factory,
|
||||||
TaskQueueFactory* task_queue_factory,
|
TaskQueueFactory* task_queue_factory,
|
||||||
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings);
|
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings,
|
||||||
|
const WebRtcKeyValueConfig* field_trials = nullptr);
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|||||||
@ -1154,7 +1154,7 @@ webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream(
|
|||||||
VideoReceiveStream2* receive_stream = new VideoReceiveStream2(
|
VideoReceiveStream2* receive_stream = new VideoReceiveStream2(
|
||||||
task_queue_factory_, this, num_cpu_cores_,
|
task_queue_factory_, this, num_cpu_cores_,
|
||||||
transport_send_->packet_router(), std::move(configuration),
|
transport_send_->packet_router(), std::move(configuration),
|
||||||
call_stats_.get(), clock_, std::make_unique<VCMTiming>(clock_),
|
call_stats_.get(), clock_, std::make_unique<VCMTiming>(clock_, trials()),
|
||||||
&nack_periodic_processor_, decode_sync_.get());
|
&nack_periodic_processor_, decode_sync_.get());
|
||||||
// TODO(bugs.webrtc.org/11993): Set this up asynchronously on the network
|
// TODO(bugs.webrtc.org/11993): Set this up asynchronously on the network
|
||||||
// thread.
|
// thread.
|
||||||
|
|||||||
@ -360,6 +360,10 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver {
|
|||||||
*trials_, field_trial_string);
|
*trials_, field_trial_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const webrtc::WebRtcKeyValueConfig& trials() const override {
|
||||||
|
return *trials_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
webrtc::AudioSendStream* CreateAudioSendStream(
|
webrtc::AudioSendStream* CreateAudioSendStream(
|
||||||
const webrtc::AudioSendStream::Config& config) override;
|
const webrtc::AudioSendStream::Config& config) override;
|
||||||
@ -401,10 +405,6 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver {
|
|||||||
|
|
||||||
webrtc::Call::Stats GetStats() const override;
|
webrtc::Call::Stats GetStats() const override;
|
||||||
|
|
||||||
const webrtc::WebRtcKeyValueConfig& trials() const override {
|
|
||||||
return *trials_;
|
|
||||||
}
|
|
||||||
|
|
||||||
webrtc::TaskQueueBase* network_thread() const override;
|
webrtc::TaskQueueBase* network_thread() const override;
|
||||||
webrtc::TaskQueueBase* worker_thread() const override;
|
webrtc::TaskQueueBase* worker_thread() const override;
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,7 @@ rtc_library("nack_requester") {
|
|||||||
deps = [
|
deps = [
|
||||||
"..:module_api",
|
"..:module_api",
|
||||||
"../../api:sequence_checker",
|
"../../api:sequence_checker",
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
"../../api/task_queue",
|
"../../api/task_queue",
|
||||||
"../../api/units:time_delta",
|
"../../api/units:time_delta",
|
||||||
"../../api/units:timestamp",
|
"../../api/units:timestamp",
|
||||||
@ -93,7 +94,6 @@ rtc_library("nack_requester") {
|
|||||||
"../../rtc_base/task_utils:pending_task_safety_flag",
|
"../../rtc_base/task_utils:pending_task_safety_flag",
|
||||||
"../../rtc_base/task_utils:repeating_task",
|
"../../rtc_base/task_utils:repeating_task",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
"../../system_wrappers:field_trial",
|
|
||||||
"../utility",
|
"../utility",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -167,11 +167,11 @@ rtc_library("frame_buffer") {
|
|||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
":video_coding_utility",
|
":video_coding_utility",
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
"../../api/units:timestamp",
|
"../../api/units:timestamp",
|
||||||
"../../api/video:encoded_frame",
|
"../../api/video:encoded_frame",
|
||||||
"../../rtc_base:logging",
|
"../../rtc_base:logging",
|
||||||
"../../rtc_base:rtc_numerics",
|
"../../rtc_base:rtc_numerics",
|
||||||
"../../system_wrappers:field_trial",
|
|
||||||
]
|
]
|
||||||
absl_deps = [
|
absl_deps = [
|
||||||
"//third_party/abseil-cpp/absl/algorithm:container",
|
"//third_party/abseil-cpp/absl/algorithm:container",
|
||||||
@ -188,6 +188,7 @@ rtc_library("timing") {
|
|||||||
"timing.h",
|
"timing.h",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
"../../api/units:time_delta",
|
"../../api/units:time_delta",
|
||||||
"../../api/video:video_rtp_headers",
|
"../../api/video:video_rtp_headers",
|
||||||
"../../rtc_base:logging",
|
"../../rtc_base:logging",
|
||||||
@ -197,7 +198,6 @@ rtc_library("timing") {
|
|||||||
"../../rtc_base/synchronization:mutex",
|
"../../rtc_base/synchronization:mutex",
|
||||||
"../../rtc_base/time:timestamp_extrapolator",
|
"../../rtc_base/time:timestamp_extrapolator",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
"../../system_wrappers:field_trial",
|
|
||||||
]
|
]
|
||||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||||
}
|
}
|
||||||
@ -221,6 +221,7 @@ rtc_library("jitter_estimator") {
|
|||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
":rtt_filter",
|
":rtt_filter",
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
"../../api/units:data_size",
|
"../../api/units:data_size",
|
||||||
"../../api/units:frequency",
|
"../../api/units:frequency",
|
||||||
"../../api/units:time_delta",
|
"../../api/units:time_delta",
|
||||||
@ -229,7 +230,6 @@ rtc_library("jitter_estimator") {
|
|||||||
"../../rtc_base:safe_conversions",
|
"../../rtc_base:safe_conversions",
|
||||||
"../../rtc_base/experiments:jitter_upper_bound_experiment",
|
"../../rtc_base/experiments:jitter_upper_bound_experiment",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
"../../system_wrappers:field_trial",
|
|
||||||
]
|
]
|
||||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||||
}
|
}
|
||||||
@ -314,6 +314,7 @@ rtc_library("video_coding") {
|
|||||||
"../../api:rtp_packet_info",
|
"../../api:rtp_packet_info",
|
||||||
"../../api:scoped_refptr",
|
"../../api:scoped_refptr",
|
||||||
"../../api:sequence_checker",
|
"../../api:sequence_checker",
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
"../../api/task_queue",
|
"../../api/task_queue",
|
||||||
"../../api/units:data_rate",
|
"../../api/units:data_rate",
|
||||||
"../../api/units:data_size",
|
"../../api/units:data_size",
|
||||||
@ -424,6 +425,8 @@ rtc_library("video_coding_legacy") {
|
|||||||
"../../api:rtp_headers",
|
"../../api:rtp_headers",
|
||||||
"../../api:rtp_packet_info",
|
"../../api:rtp_packet_info",
|
||||||
"../../api:sequence_checker",
|
"../../api:sequence_checker",
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
|
"../../api/transport:field_trial_based_config",
|
||||||
"../../api/units:timestamp",
|
"../../api/units:timestamp",
|
||||||
"../../api/video:encoded_image",
|
"../../api/video:encoded_image",
|
||||||
"../../api/video:video_frame",
|
"../../api/video:video_frame",
|
||||||
@ -436,6 +439,7 @@ rtc_library("video_coding_legacy") {
|
|||||||
"../../rtc_base:logging",
|
"../../rtc_base:logging",
|
||||||
"../../rtc_base:rtc_base_approved",
|
"../../rtc_base:rtc_base_approved",
|
||||||
"../../rtc_base:rtc_event",
|
"../../rtc_base:rtc_event",
|
||||||
|
"../../rtc_base/memory:always_valid_pointer",
|
||||||
"../../rtc_base/synchronization:mutex",
|
"../../rtc_base/synchronization:mutex",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
"../rtp_rtcp:rtp_rtcp_format",
|
"../rtp_rtcp:rtp_rtcp_format",
|
||||||
@ -497,6 +501,7 @@ rtc_library("video_coding_utility") {
|
|||||||
"../../api:array_view",
|
"../../api:array_view",
|
||||||
"../../api:scoped_refptr",
|
"../../api:scoped_refptr",
|
||||||
"../../api:sequence_checker",
|
"../../api:sequence_checker",
|
||||||
|
"../../api:webrtc_key_value_config",
|
||||||
"../../api/video:encoded_frame",
|
"../../api/video:encoded_frame",
|
||||||
"../../api/video:encoded_image",
|
"../../api/video:encoded_image",
|
||||||
"../../api/video:video_adaptation",
|
"../../api/video:video_adaptation",
|
||||||
@ -1233,6 +1238,7 @@ if (rtc_include_tests) {
|
|||||||
"../../test:fake_video_codecs",
|
"../../test:fake_video_codecs",
|
||||||
"../../test:field_trial",
|
"../../test:field_trial",
|
||||||
"../../test:fileutils",
|
"../../test:fileutils",
|
||||||
|
"../../test:scoped_key_value_config",
|
||||||
"../../test:test_common",
|
"../../test:test_common",
|
||||||
"../../test:test_support",
|
"../../test:test_support",
|
||||||
"../../test:video_test_common",
|
"../../test:video_test_common",
|
||||||
|
|||||||
@ -17,6 +17,7 @@ rtc_library("nack_module") {
|
|||||||
deps = [
|
deps = [
|
||||||
"..:nack_requester",
|
"..:nack_requester",
|
||||||
"../..:module_api",
|
"../..:module_api",
|
||||||
|
"../../../api:webrtc_key_value_config",
|
||||||
"../../../api/units:time_delta",
|
"../../../api/units:time_delta",
|
||||||
"../../../api/units:timestamp",
|
"../../../api/units:timestamp",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
@ -27,7 +28,6 @@ rtc_library("nack_module") {
|
|||||||
"../../../rtc_base/experiments:field_trial_parser",
|
"../../../rtc_base/experiments:field_trial_parser",
|
||||||
"../../../rtc_base/synchronization:mutex",
|
"../../../rtc_base/synchronization:mutex",
|
||||||
"../../../system_wrappers",
|
"../../../system_wrappers",
|
||||||
"../../../system_wrappers:field_trial",
|
|
||||||
"../../utility",
|
"../../utility",
|
||||||
]
|
]
|
||||||
absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ]
|
absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ]
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -33,10 +32,9 @@ const int kMaxReorderedPackets = 128;
|
|||||||
const int kNumReorderingBuckets = 10;
|
const int kNumReorderingBuckets = 10;
|
||||||
const int kDefaultSendNackDelayMs = 0;
|
const int kDefaultSendNackDelayMs = 0;
|
||||||
|
|
||||||
int64_t GetSendNackDelay() {
|
int64_t GetSendNackDelay(const WebRtcKeyValueConfig& field_trials) {
|
||||||
int64_t delay_ms = strtol(
|
int64_t delay_ms = strtol(
|
||||||
webrtc::field_trial::FindFullName("WebRTC-SendNackDelayMs").c_str(),
|
field_trials.Lookup("WebRTC-SendNackDelayMs").c_str(), nullptr, 10);
|
||||||
nullptr, 10);
|
|
||||||
if (delay_ms > 0 && delay_ms <= 20) {
|
if (delay_ms > 0 && delay_ms <= 20) {
|
||||||
RTC_LOG(LS_INFO) << "SendNackDelay is set to " << delay_ms;
|
RTC_LOG(LS_INFO) << "SendNackDelay is set to " << delay_ms;
|
||||||
return delay_ms;
|
return delay_ms;
|
||||||
@ -63,7 +61,8 @@ DEPRECATED_NackModule::BackoffSettings::BackoffSettings(TimeDelta min_retry,
|
|||||||
: min_retry_interval(min_retry), max_rtt(max_rtt), base(base) {}
|
: min_retry_interval(min_retry), max_rtt(max_rtt), base(base) {}
|
||||||
|
|
||||||
absl::optional<DEPRECATED_NackModule::BackoffSettings>
|
absl::optional<DEPRECATED_NackModule::BackoffSettings>
|
||||||
DEPRECATED_NackModule::BackoffSettings::ParseFromFieldTrials() {
|
DEPRECATED_NackModule::BackoffSettings::ParseFromFieldTrials(
|
||||||
|
const WebRtcKeyValueConfig& field_trials) {
|
||||||
// Matches magic number in RTPSender::OnReceivedNack().
|
// Matches magic number in RTPSender::OnReceivedNack().
|
||||||
const TimeDelta kDefaultMinRetryInterval = TimeDelta::Millis(5);
|
const TimeDelta kDefaultMinRetryInterval = TimeDelta::Millis(5);
|
||||||
// Upper bound on link-delay considered for exponential backoff.
|
// Upper bound on link-delay considered for exponential backoff.
|
||||||
@ -79,7 +78,7 @@ DEPRECATED_NackModule::BackoffSettings::ParseFromFieldTrials() {
|
|||||||
FieldTrialParameter<TimeDelta> max_rtt("max_rtt", kDefaultMaxRtt);
|
FieldTrialParameter<TimeDelta> max_rtt("max_rtt", kDefaultMaxRtt);
|
||||||
FieldTrialParameter<double> base("base", kDefaultBase);
|
FieldTrialParameter<double> base("base", kDefaultBase);
|
||||||
ParseFieldTrial({&enabled, &min_retry, &max_rtt, &base},
|
ParseFieldTrial({&enabled, &min_retry, &max_rtt, &base},
|
||||||
field_trial::FindFullName("WebRTC-ExponentialNackBackoff"));
|
field_trials.Lookup("WebRTC-ExponentialNackBackoff"));
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
return DEPRECATED_NackModule::BackoffSettings(min_retry.Get(),
|
return DEPRECATED_NackModule::BackoffSettings(min_retry.Get(),
|
||||||
@ -91,7 +90,8 @@ DEPRECATED_NackModule::BackoffSettings::ParseFromFieldTrials() {
|
|||||||
DEPRECATED_NackModule::DEPRECATED_NackModule(
|
DEPRECATED_NackModule::DEPRECATED_NackModule(
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
NackSender* nack_sender,
|
NackSender* nack_sender,
|
||||||
KeyFrameRequestSender* keyframe_request_sender)
|
KeyFrameRequestSender* keyframe_request_sender,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
nack_sender_(nack_sender),
|
nack_sender_(nack_sender),
|
||||||
keyframe_request_sender_(keyframe_request_sender),
|
keyframe_request_sender_(keyframe_request_sender),
|
||||||
@ -100,8 +100,8 @@ DEPRECATED_NackModule::DEPRECATED_NackModule(
|
|||||||
rtt_ms_(kDefaultRttMs),
|
rtt_ms_(kDefaultRttMs),
|
||||||
newest_seq_num_(0),
|
newest_seq_num_(0),
|
||||||
next_process_time_ms_(-1),
|
next_process_time_ms_(-1),
|
||||||
send_nack_delay_ms_(GetSendNackDelay()),
|
send_nack_delay_ms_(GetSendNackDelay(field_trials)),
|
||||||
backoff_settings_(BackoffSettings::ParseFromFieldTrials()) {
|
backoff_settings_(BackoffSettings::ParseFromFieldTrials(field_trials)) {
|
||||||
RTC_DCHECK(clock_);
|
RTC_DCHECK(clock_);
|
||||||
RTC_DCHECK(nack_sender_);
|
RTC_DCHECK(nack_sender_);
|
||||||
RTC_DCHECK(keyframe_request_sender_);
|
RTC_DCHECK(keyframe_request_sender_);
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/include/module.h"
|
#include "modules/include/module.h"
|
||||||
#include "modules/include/module_common_types.h"
|
#include "modules/include/module_common_types.h"
|
||||||
#include "modules/video_coding/histogram.h"
|
#include "modules/video_coding/histogram.h"
|
||||||
@ -33,7 +34,8 @@ class DEPRECATED_NackModule : public Module {
|
|||||||
public:
|
public:
|
||||||
DEPRECATED_NackModule(Clock* clock,
|
DEPRECATED_NackModule(Clock* clock,
|
||||||
NackSender* nack_sender,
|
NackSender* nack_sender,
|
||||||
KeyFrameRequestSender* keyframe_request_sender);
|
KeyFrameRequestSender* keyframe_request_sender,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
|
|
||||||
int OnReceivedPacket(uint16_t seq_num, bool is_keyframe);
|
int OnReceivedPacket(uint16_t seq_num, bool is_keyframe);
|
||||||
int OnReceivedPacket(uint16_t seq_num, bool is_keyframe, bool is_recovered);
|
int OnReceivedPacket(uint16_t seq_num, bool is_keyframe, bool is_recovered);
|
||||||
@ -69,7 +71,8 @@ class DEPRECATED_NackModule : public Module {
|
|||||||
|
|
||||||
struct BackoffSettings {
|
struct BackoffSettings {
|
||||||
BackoffSettings(TimeDelta min_retry, TimeDelta max_rtt, double base);
|
BackoffSettings(TimeDelta min_retry, TimeDelta max_rtt, double base);
|
||||||
static absl::optional<BackoffSettings> ParseFromFieldTrials();
|
static absl::optional<BackoffSettings> ParseFromFieldTrials(
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
|
|
||||||
// Min time between nacks.
|
// Min time between nacks.
|
||||||
const TimeDelta min_retry_interval;
|
const TimeDelta min_retry_interval;
|
||||||
|
|||||||
@ -33,7 +33,6 @@
|
|||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_util.h"
|
||||||
#include "rtc_base/trace_event.h"
|
#include "rtc_base/trace_event.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace video_coding {
|
namespace video_coding {
|
||||||
@ -58,11 +57,12 @@ constexpr int64_t kLogNonDecodedIntervalMs = 5000;
|
|||||||
|
|
||||||
FrameBuffer::FrameBuffer(Clock* clock,
|
FrameBuffer::FrameBuffer(Clock* clock,
|
||||||
VCMTiming* timing,
|
VCMTiming* timing,
|
||||||
VCMReceiveStatisticsCallback* stats_callback)
|
VCMReceiveStatisticsCallback* stats_callback,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: decoded_frames_history_(kMaxFramesHistory),
|
: decoded_frames_history_(kMaxFramesHistory),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
callback_queue_(nullptr),
|
callback_queue_(nullptr),
|
||||||
jitter_estimator_(clock),
|
jitter_estimator_(clock, field_trials),
|
||||||
timing_(timing),
|
timing_(timing),
|
||||||
stopped_(false),
|
stopped_(false),
|
||||||
protection_mode_(kProtectionNack),
|
protection_mode_(kProtectionNack),
|
||||||
@ -73,7 +73,7 @@ FrameBuffer::FrameBuffer(Clock* clock,
|
|||||||
"max_decode_queue_size",
|
"max_decode_queue_size",
|
||||||
kZeroPlayoutDelayDefaultMaxDecodeQueueSize) {
|
kZeroPlayoutDelayDefaultMaxDecodeQueueSize) {
|
||||||
ParseFieldTrial({&zero_playout_delay_max_decode_queue_size_},
|
ParseFieldTrial({&zero_playout_delay_max_decode_queue_size_},
|
||||||
field_trial::FindFullName("WebRTC-ZeroPlayoutDelay"));
|
field_trials.Lookup("WebRTC-ZeroPlayoutDelay"));
|
||||||
callback_checker_.Detach();
|
callback_checker_.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "absl/container/inlined_vector.h"
|
#include "absl/container/inlined_vector.h"
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
#include "api/video/encoded_frame.h"
|
#include "api/video/encoded_frame.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/include/video_coding_defines.h"
|
#include "modules/video_coding/include/video_coding_defines.h"
|
||||||
#include "modules/video_coding/inter_frame_delay.h"
|
#include "modules/video_coding/inter_frame_delay.h"
|
||||||
#include "modules/video_coding/jitter_estimator.h"
|
#include "modules/video_coding/jitter_estimator.h"
|
||||||
@ -47,7 +48,8 @@ class FrameBuffer {
|
|||||||
public:
|
public:
|
||||||
FrameBuffer(Clock* clock,
|
FrameBuffer(Clock* clock,
|
||||||
VCMTiming* timing,
|
VCMTiming* timing,
|
||||||
VCMReceiveStatisticsCallback* stats_callback);
|
VCMReceiveStatisticsCallback* stats_callback,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
|
|
||||||
FrameBuffer() = delete;
|
FrameBuffer() = delete;
|
||||||
FrameBuffer(const FrameBuffer&) = delete;
|
FrameBuffer(const FrameBuffer&) = delete;
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "test/field_trial.h"
|
#include "test/field_trial.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
#include "test/time_controller/simulated_time_controller.h"
|
#include "test/time_controller/simulated_time_controller.h"
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
@ -40,7 +41,8 @@ namespace video_coding {
|
|||||||
|
|
||||||
class VCMTimingFake : public VCMTiming {
|
class VCMTimingFake : public VCMTiming {
|
||||||
public:
|
public:
|
||||||
explicit VCMTimingFake(Clock* clock) : VCMTiming(clock) {}
|
explicit VCMTimingFake(Clock* clock, const WebRtcKeyValueConfig& field_trials)
|
||||||
|
: VCMTiming(clock, field_trials) {}
|
||||||
|
|
||||||
Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
|
Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
|
||||||
if (last_render_time_.IsMinusInfinity()) {
|
if (last_render_time_.IsMinusInfinity()) {
|
||||||
@ -131,10 +133,11 @@ class TestFrameBuffer2 : public ::testing::Test {
|
|||||||
time_controller_.GetTaskQueueFactory()->CreateTaskQueue(
|
time_controller_.GetTaskQueueFactory()->CreateTaskQueue(
|
||||||
"extract queue",
|
"extract queue",
|
||||||
TaskQueueFactory::Priority::NORMAL)),
|
TaskQueueFactory::Priority::NORMAL)),
|
||||||
timing_(time_controller_.GetClock()),
|
timing_(time_controller_.GetClock(), field_trials_),
|
||||||
buffer_(new FrameBuffer(time_controller_.GetClock(),
|
buffer_(new FrameBuffer(time_controller_.GetClock(),
|
||||||
&timing_,
|
&timing_,
|
||||||
&stats_callback_)),
|
&stats_callback_,
|
||||||
|
field_trials_)),
|
||||||
rand_(0x34678213) {}
|
rand_(0x34678213) {}
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
@ -213,6 +216,7 @@ class TestFrameBuffer2 : public ::testing::Test {
|
|||||||
|
|
||||||
uint32_t Rand() { return rand_.Rand<uint32_t>(); }
|
uint32_t Rand() { return rand_.Rand<uint32_t>(); }
|
||||||
|
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
webrtc::GlobalSimulatedTimeController time_controller_;
|
webrtc::GlobalSimulatedTimeController time_controller_;
|
||||||
rtc::TaskQueue time_task_queue_;
|
rtc::TaskQueue time_task_queue_;
|
||||||
VCMTimingFake timing_;
|
VCMTimingFake timing_;
|
||||||
@ -276,9 +280,10 @@ TEST_F(TestFrameBuffer2, OneSuperFrame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestFrameBuffer2, ZeroPlayoutDelay) {
|
TEST_F(TestFrameBuffer2, ZeroPlayoutDelay) {
|
||||||
VCMTiming timing(time_controller_.GetClock());
|
test::ScopedKeyValueConfig field_trials;
|
||||||
buffer_.reset(
|
VCMTiming timing(time_controller_.GetClock(), field_trials);
|
||||||
new FrameBuffer(time_controller_.GetClock(), &timing, &stats_callback_));
|
buffer_.reset(new FrameBuffer(time_controller_.GetClock(), &timing,
|
||||||
|
&stats_callback_, field_trials));
|
||||||
const VideoPlayoutDelay kPlayoutDelayMs = {0, 0};
|
const VideoPlayoutDelay kPlayoutDelayMs = {0, 0};
|
||||||
std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
|
std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
|
||||||
test_frame->SetId(0);
|
test_frame->SetId(0);
|
||||||
|
|||||||
@ -19,7 +19,6 @@
|
|||||||
#include "absl/container/inlined_vector.h"
|
#include "absl/container/inlined_vector.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_util.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -63,9 +62,11 @@ bool IsLastFrameInTemporalUnit(const FrameIteratorT& it) {
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
FrameBuffer::FrameBuffer(int max_size, int max_decode_history)
|
FrameBuffer::FrameBuffer(int max_size,
|
||||||
|
int max_decode_history,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: legacy_frame_id_jump_behavior_(
|
: legacy_frame_id_jump_behavior_(
|
||||||
!field_trial::IsDisabled("WebRTC-LegacyFrameIdJumpBehavior")),
|
!field_trials.IsDisabled("WebRTC-LegacyFrameIdJumpBehavior")),
|
||||||
max_size_(max_size),
|
max_size_(max_size),
|
||||||
decoded_frame_history_(max_decode_history) {}
|
decoded_frame_history_(max_decode_history) {}
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/units/timestamp.h"
|
#include "api/units/timestamp.h"
|
||||||
#include "api/video/encoded_frame.h"
|
#include "api/video/encoded_frame.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/utility/decoded_frames_history.h"
|
#include "modules/video_coding/utility/decoded_frames_history.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -33,7 +34,10 @@ class FrameBuffer {
|
|||||||
// The `max_size` determines the maxmimum number of frames the buffer will
|
// The `max_size` determines the maxmimum number of frames the buffer will
|
||||||
// store, and max_decode_history determines how far back (by frame ID) the
|
// store, and max_decode_history determines how far back (by frame ID) the
|
||||||
// buffer will store if a frame was decoded or not.
|
// buffer will store if a frame was decoded or not.
|
||||||
FrameBuffer(int max_size, int max_decode_history);
|
FrameBuffer(int max_size,
|
||||||
|
int max_decode_history,
|
||||||
|
// TODO(hta): remove field trials!
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
FrameBuffer(const FrameBuffer&) = delete;
|
FrameBuffer(const FrameBuffer&) = delete;
|
||||||
FrameBuffer& operator=(const FrameBuffer&) = delete;
|
FrameBuffer& operator=(const FrameBuffer&) = delete;
|
||||||
~FrameBuffer() = default;
|
~FrameBuffer() = default;
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include "test/field_trial.h"
|
#include "test/field_trial.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -79,7 +80,9 @@ class Builder {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, RejectInvalidRefs) {
|
TEST(FrameBuffer3Test, RejectInvalidRefs) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
// Ref must be less than the id of this frame.
|
// Ref must be less than the id of this frame.
|
||||||
buffer.InsertFrame(Builder().Time(0).Id(0).Refs({0}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(0).Id(0).Refs({0}).AsLast().Build());
|
||||||
EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
|
EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
|
||||||
@ -91,7 +94,9 @@ TEST(FrameBuffer3Test, RejectInvalidRefs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, LastContinuousUpdatesOnInsertedFrames) {
|
TEST(FrameBuffer3Test, LastContinuousUpdatesOnInsertedFrames) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
|
EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
|
||||||
EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
|
EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
|
||||||
|
|
||||||
@ -105,7 +110,9 @@ TEST(FrameBuffer3Test, LastContinuousUpdatesOnInsertedFrames) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, LastContinuousFrameReordering) {
|
TEST(FrameBuffer3Test, LastContinuousFrameReordering) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build());
|
||||||
@ -116,7 +123,9 @@ TEST(FrameBuffer3Test, LastContinuousFrameReordering) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, LastContinuousTemporalUnit) {
|
TEST(FrameBuffer3Test, LastContinuousTemporalUnit) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).Build());
|
||||||
EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
|
EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
|
||||||
@ -125,7 +134,9 @@ TEST(FrameBuffer3Test, LastContinuousTemporalUnit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, LastContinuousTemporalUnitReordering) {
|
TEST(FrameBuffer3Test, LastContinuousTemporalUnitReordering) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).Build());
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(3).Refs({1}).Build());
|
buffer.InsertFrame(Builder().Time(20).Id(3).Refs({1}).Build());
|
||||||
@ -137,7 +148,9 @@ TEST(FrameBuffer3Test, LastContinuousTemporalUnitReordering) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, NextDecodable) {
|
TEST(FrameBuffer3Test, NextDecodable) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(),
|
EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(),
|
||||||
Eq(absl::nullopt));
|
Eq(absl::nullopt));
|
||||||
@ -146,7 +159,9 @@ TEST(FrameBuffer3Test, NextDecodable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) {
|
TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build());
|
||||||
@ -164,7 +179,9 @@ TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, AdvanceLastDecodableOnExtraction) {
|
TEST(FrameBuffer3Test, AdvanceLastDecodableOnExtraction) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
||||||
@ -177,7 +194,9 @@ TEST(FrameBuffer3Test, AdvanceLastDecodableOnExtraction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) {
|
TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build());
|
||||||
EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(20U));
|
EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(20U));
|
||||||
@ -187,7 +206,9 @@ TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) {
|
TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/5, /*max_decode_history=*/10);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/5, /*max_decode_history=*/10,
|
||||||
|
field_trials);
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build());
|
||||||
@ -204,7 +225,9 @@ TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, DropNextDecodableTemporalUnit) {
|
TEST(FrameBuffer3Test, DropNextDecodableTemporalUnit) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());
|
||||||
@ -216,7 +239,9 @@ TEST(FrameBuffer3Test, DropNextDecodableTemporalUnit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, OldFramesAreIgnored) {
|
TEST(FrameBuffer3Test, OldFramesAreIgnored) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
||||||
|
|
||||||
@ -232,7 +257,9 @@ TEST(FrameBuffer3Test, OldFramesAreIgnored) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, ReturnFullTemporalUnitKSVC) {
|
TEST(FrameBuffer3Test, ReturnFullTemporalUnitKSVC) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).Build());
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).Build());
|
buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).Build());
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(3).Refs({2}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(3).Refs({2}).AsLast().Build());
|
||||||
@ -245,7 +272,9 @@ TEST(FrameBuffer3Test, ReturnFullTemporalUnitKSVC) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, InterleavedStream) {
|
TEST(FrameBuffer3Test, InterleavedStream) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build());
|
||||||
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build());
|
||||||
@ -275,9 +304,10 @@ TEST(FrameBuffer3Test, InterleavedStream) {
|
|||||||
|
|
||||||
TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) {
|
TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) {
|
||||||
{
|
{
|
||||||
test::ScopedFieldTrials field_trial(
|
test::ScopedKeyValueConfig field_trials(
|
||||||
"WebRTC-LegacyFrameIdJumpBehavior/Disabled/");
|
"WebRTC-LegacyFrameIdJumpBehavior/Disabled/");
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build());
|
||||||
EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
|
EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
|
||||||
@ -288,7 +318,9 @@ TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// WebRTC-LegacyFrameIdJumpBehavior is disabled by default.
|
// WebRTC-LegacyFrameIdJumpBehavior is disabled by default.
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build());
|
||||||
EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
|
EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
|
||||||
@ -302,7 +334,9 @@ TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, TotalNumberOfContinuousTemporalUnits) {
|
TEST(FrameBuffer3Test, TotalNumberOfContinuousTemporalUnits) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(0));
|
EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(0));
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
@ -321,7 +355,9 @@ TEST(FrameBuffer3Test, TotalNumberOfContinuousTemporalUnits) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FrameBuffer3Test, TotalNumberOfDroppedFrames) {
|
TEST(FrameBuffer3Test, TotalNumberOfDroppedFrames) {
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
|
||||||
|
field_trials);
|
||||||
EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));
|
EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));
|
||||||
|
|
||||||
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build());
|
||||||
|
|||||||
@ -23,12 +23,13 @@
|
|||||||
#include "rtc_base/time_utils.h"
|
#include "rtc_base/time_utils.h"
|
||||||
#include "rtc_base/trace_event.h"
|
#include "rtc_base/trace_event.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming* timing,
|
VCMDecodedFrameCallback::VCMDecodedFrameCallback(
|
||||||
Clock* clock)
|
VCMTiming* timing,
|
||||||
|
Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: _clock(clock),
|
: _clock(clock),
|
||||||
_timing(timing),
|
_timing(timing),
|
||||||
_timestampMap(kDecoderFrameMemoryLength),
|
_timestampMap(kDecoderFrameMemoryLength),
|
||||||
@ -40,10 +41,10 @@ VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming* timing,
|
|||||||
_clock->CurrentNtpInMilliseconds() - _clock->TimeInMilliseconds();
|
_clock->CurrentNtpInMilliseconds() - _clock->TimeInMilliseconds();
|
||||||
|
|
||||||
ParseFieldTrial({&_extra_decode_time},
|
ParseFieldTrial({&_extra_decode_time},
|
||||||
field_trial::FindFullName("WebRTC-SlowDownDecoder"));
|
field_trials.Lookup("WebRTC-SlowDownDecoder"));
|
||||||
ParseFieldTrial({&low_latency_renderer_enabled_,
|
ParseFieldTrial({&low_latency_renderer_enabled_,
|
||||||
&low_latency_renderer_include_predecode_buffer_},
|
&low_latency_renderer_include_predecode_buffer_},
|
||||||
field_trial::FindFullName("WebRTC-LowLatencyRenderer"));
|
field_trials.Lookup("WebRTC-LowLatencyRenderer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
VCMDecodedFrameCallback::~VCMDecodedFrameCallback() {}
|
VCMDecodedFrameCallback::~VCMDecodedFrameCallback() {}
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
#include "api/video_codecs/video_decoder.h"
|
#include "api/video_codecs/video_decoder.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/encoded_frame.h"
|
#include "modules/video_coding/encoded_frame.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "modules/video_coding/timestamp_map.h"
|
#include "modules/video_coding/timestamp_map.h"
|
||||||
@ -31,7 +32,9 @@ enum { kDecoderFrameMemoryLength = 10 };
|
|||||||
|
|
||||||
class VCMDecodedFrameCallback : public DecodedImageCallback {
|
class VCMDecodedFrameCallback : public DecodedImageCallback {
|
||||||
public:
|
public:
|
||||||
VCMDecodedFrameCallback(VCMTiming* timing, Clock* clock);
|
VCMDecodedFrameCallback(VCMTiming* timing,
|
||||||
|
Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
~VCMDecodedFrameCallback() override;
|
~VCMDecodedFrameCallback() override;
|
||||||
void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback);
|
void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback);
|
||||||
VCMReceiveCallback* UserReceiveCallback();
|
VCMReceiveCallback* UserReceiveCallback();
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include "test/fake_decoder.h"
|
#include "test/fake_decoder.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace video_coding {
|
namespace video_coding {
|
||||||
@ -66,10 +67,10 @@ class GenericDecoderTest : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
GenericDecoderTest()
|
GenericDecoderTest()
|
||||||
: clock_(0),
|
: clock_(0),
|
||||||
timing_(&clock_),
|
timing_(&clock_, field_trials_),
|
||||||
task_queue_factory_(CreateDefaultTaskQueueFactory()),
|
task_queue_factory_(CreateDefaultTaskQueueFactory()),
|
||||||
decoder_(task_queue_factory_.get()),
|
decoder_(task_queue_factory_.get()),
|
||||||
vcm_callback_(&timing_, &clock_),
|
vcm_callback_(&timing_, &clock_, field_trials_),
|
||||||
generic_decoder_(&decoder_) {}
|
generic_decoder_(&decoder_) {}
|
||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
@ -82,6 +83,7 @@ class GenericDecoderTest : public ::testing::Test {
|
|||||||
generic_decoder_.Configure(settings);
|
generic_decoder_.Configure(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
SimulatedClock clock_;
|
SimulatedClock clock_;
|
||||||
VCMTiming timing_;
|
VCMTiming timing_;
|
||||||
std::unique_ptr<TaskQueueFactory> task_queue_factory_;
|
std::unique_ptr<TaskQueueFactory> task_queue_factory_;
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "api/video/video_frame.h"
|
#include "api/video/video_frame.h"
|
||||||
#include "api/video_codecs/video_decoder.h"
|
#include "api/video_codecs/video_decoder.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/include/module.h"
|
#include "modules/include/module.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_video_header.h"
|
#include "modules/rtp_rtcp/source/rtp_video_header.h"
|
||||||
#include "modules/video_coding/include/video_coding_defines.h"
|
#include "modules/video_coding/include/video_coding_defines.h"
|
||||||
@ -28,7 +29,9 @@ struct CodecSpecificInfo;
|
|||||||
class VideoCodingModule : public Module {
|
class VideoCodingModule : public Module {
|
||||||
public:
|
public:
|
||||||
// DEPRECATED.
|
// DEPRECATED.
|
||||||
static VideoCodingModule* Create(Clock* clock);
|
static VideoCodingModule* Create(
|
||||||
|
Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig* field_trials = nullptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receiver
|
* Receiver
|
||||||
|
|||||||
@ -109,7 +109,8 @@ void FrameList::Reset(UnorderedFrameList* free_frames) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
|
VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
|
||||||
std::unique_ptr<EventWrapper> event)
|
std::unique_ptr<EventWrapper> event,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
running_(false),
|
running_(false),
|
||||||
frame_event_(std::move(event)),
|
frame_event_(std::move(event)),
|
||||||
@ -122,7 +123,7 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
|
|||||||
num_consecutive_old_packets_(0),
|
num_consecutive_old_packets_(0),
|
||||||
num_packets_(0),
|
num_packets_(0),
|
||||||
num_duplicated_packets_(0),
|
num_duplicated_packets_(0),
|
||||||
jitter_estimate_(clock),
|
jitter_estimate_(clock, field_trials),
|
||||||
missing_sequence_numbers_(SequenceNumberLessThan()),
|
missing_sequence_numbers_(SequenceNumberLessThan()),
|
||||||
latest_received_sequence_number_(0),
|
latest_received_sequence_number_(0),
|
||||||
max_nack_list_size_(0),
|
max_nack_list_size_(0),
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/include/module_common_types.h"
|
#include "modules/include/module_common_types.h"
|
||||||
#include "modules/include/module_common_types_public.h"
|
#include "modules/include/module_common_types_public.h"
|
||||||
#include "modules/video_coding/decoding_state.h"
|
#include "modules/video_coding/decoding_state.h"
|
||||||
@ -69,7 +70,9 @@ class FrameList
|
|||||||
|
|
||||||
class VCMJitterBuffer {
|
class VCMJitterBuffer {
|
||||||
public:
|
public:
|
||||||
VCMJitterBuffer(Clock* clock, std::unique_ptr<EventWrapper> event);
|
VCMJitterBuffer(Clock* clock,
|
||||||
|
std::unique_ptr<EventWrapper> event,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
|
|
||||||
~VCMJitterBuffer();
|
~VCMJitterBuffer();
|
||||||
|
|
||||||
|
|||||||
@ -23,11 +23,10 @@
|
|||||||
#include "modules/video_coding/test/stream_generator.h"
|
#include "modules/video_coding/test/stream_generator.h"
|
||||||
#include "rtc_base/location.h"
|
#include "rtc_base/location.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
#include "system_wrappers/include/metrics.h"
|
#include "system_wrappers/include/metrics.h"
|
||||||
#include "test/field_trial.h"
|
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ class TestBasicJitterBuffer : public ::testing::Test {
|
|||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
clock_.reset(new SimulatedClock(0));
|
clock_.reset(new SimulatedClock(0));
|
||||||
jitter_buffer_.reset(new VCMJitterBuffer(
|
jitter_buffer_.reset(new VCMJitterBuffer(
|
||||||
clock_.get(), absl::WrapUnique(EventWrapper::Create())));
|
clock_.get(), absl::WrapUnique(EventWrapper::Create()), field_trials_));
|
||||||
jitter_buffer_->Start();
|
jitter_buffer_->Start();
|
||||||
seq_num_ = 1234;
|
seq_num_ = 1234;
|
||||||
timestamp_ = 0;
|
timestamp_ = 0;
|
||||||
@ -118,6 +117,7 @@ class TestBasicJitterBuffer : public ::testing::Test {
|
|||||||
uint32_t timestamp_;
|
uint32_t timestamp_;
|
||||||
int size_;
|
int size_;
|
||||||
uint8_t data_[1500];
|
uint8_t data_[1500];
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
std::unique_ptr<VCMPacket> packet_;
|
std::unique_ptr<VCMPacket> packet_;
|
||||||
std::unique_ptr<SimulatedClock> clock_;
|
std::unique_ptr<SimulatedClock> clock_;
|
||||||
std::unique_ptr<VCMJitterBuffer> jitter_buffer_;
|
std::unique_ptr<VCMJitterBuffer> jitter_buffer_;
|
||||||
@ -132,7 +132,7 @@ class TestRunningJitterBuffer : public ::testing::Test {
|
|||||||
max_nack_list_size_ = 150;
|
max_nack_list_size_ = 150;
|
||||||
oldest_packet_to_nack_ = 250;
|
oldest_packet_to_nack_ = 250;
|
||||||
jitter_buffer_ = new VCMJitterBuffer(
|
jitter_buffer_ = new VCMJitterBuffer(
|
||||||
clock_.get(), absl::WrapUnique(EventWrapper::Create()));
|
clock_.get(), absl::WrapUnique(EventWrapper::Create()), field_trials_);
|
||||||
stream_generator_ = new StreamGenerator(0, clock_->TimeInMilliseconds());
|
stream_generator_ = new StreamGenerator(0, clock_->TimeInMilliseconds());
|
||||||
jitter_buffer_->Start();
|
jitter_buffer_->Start();
|
||||||
jitter_buffer_->SetNackSettings(max_nack_list_size_, oldest_packet_to_nack_,
|
jitter_buffer_->SetNackSettings(max_nack_list_size_, oldest_packet_to_nack_,
|
||||||
@ -212,6 +212,7 @@ class TestRunningJitterBuffer : public ::testing::Test {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
VCMJitterBuffer* jitter_buffer_;
|
VCMJitterBuffer* jitter_buffer_;
|
||||||
StreamGenerator* stream_generator_;
|
StreamGenerator* stream_generator_;
|
||||||
std::unique_ptr<SimulatedClock> clock_;
|
std::unique_ptr<SimulatedClock> clock_;
|
||||||
|
|||||||
@ -21,11 +21,11 @@
|
|||||||
#include "api/units/frequency.h"
|
#include "api/units/frequency.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
#include "api/units/timestamp.h"
|
#include "api/units/timestamp.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/rtt_filter.h"
|
#include "modules/video_coding/rtt_filter.h"
|
||||||
#include "rtc_base/experiments/jitter_upper_bound_experiment.h"
|
#include "rtc_base/experiments/jitter_upper_bound_experiment.h"
|
||||||
#include "rtc_base/numerics/safe_conversions.h"
|
#include "rtc_base/numerics/safe_conversions.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -49,14 +49,15 @@ constexpr double kNoiseStdDevOffset = 30.0;
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
VCMJitterEstimator::VCMJitterEstimator(Clock* clock)
|
VCMJitterEstimator::VCMJitterEstimator(Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: fps_counter_(30), // TODO(sprang): Use an estimator with limit based on
|
: fps_counter_(30), // TODO(sprang): Use an estimator with limit based on
|
||||||
// time, rather than number of samples.
|
// time, rather than number of samples.
|
||||||
time_deviation_upper_bound_(
|
time_deviation_upper_bound_(
|
||||||
JitterUpperBoundExperiment::GetUpperBoundSigmas().value_or(
|
JitterUpperBoundExperiment::GetUpperBoundSigmas().value_or(
|
||||||
kDefaultMaxTimestampDeviationInSigmas)),
|
kDefaultMaxTimestampDeviationInSigmas)),
|
||||||
enable_reduced_delay_(
|
enable_reduced_delay_(
|
||||||
!field_trial::IsEnabled("WebRTC-ReducedJitterDelayKillSwitch")),
|
!field_trials.IsEnabled("WebRTC-ReducedJitterDelayKillSwitch")),
|
||||||
clock_(clock) {
|
clock_(clock) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "api/units/frequency.h"
|
#include "api/units/frequency.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
#include "api/units/timestamp.h"
|
#include "api/units/timestamp.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/rtt_filter.h"
|
#include "modules/video_coding/rtt_filter.h"
|
||||||
#include "rtc_base/rolling_accumulator.h"
|
#include "rtc_base/rolling_accumulator.h"
|
||||||
|
|
||||||
@ -25,7 +26,8 @@ class Clock;
|
|||||||
|
|
||||||
class VCMJitterEstimator {
|
class VCMJitterEstimator {
|
||||||
public:
|
public:
|
||||||
explicit VCMJitterEstimator(Clock* clock);
|
explicit VCMJitterEstimator(Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
virtual ~VCMJitterEstimator();
|
virtual ~VCMJitterEstimator();
|
||||||
VCMJitterEstimator(const VCMJitterEstimator&) = delete;
|
VCMJitterEstimator(const VCMJitterEstimator&) = delete;
|
||||||
VCMJitterEstimator& operator=(const VCMJitterEstimator&) = delete;
|
VCMJitterEstimator& operator=(const VCMJitterEstimator&) = delete;
|
||||||
|
|||||||
@ -23,8 +23,8 @@
|
|||||||
#include "rtc_base/strings/string_builder.h"
|
#include "rtc_base/strings/string_builder.h"
|
||||||
#include "rtc_base/time_utils.h"
|
#include "rtc_base/time_utils.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "test/field_trial.h"
|
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -33,10 +33,12 @@ class TestVCMJitterEstimator : public ::testing::Test {
|
|||||||
TestVCMJitterEstimator() : fake_clock_(0) {}
|
TestVCMJitterEstimator() : fake_clock_(0) {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
estimator_ = std::make_unique<VCMJitterEstimator>(&fake_clock_);
|
estimator_ =
|
||||||
|
std::make_unique<VCMJitterEstimator>(&fake_clock_, field_trials_);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedClock fake_clock_;
|
SimulatedClock fake_clock_;
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
std::unique_ptr<VCMJitterEstimator> estimator_;
|
std::unique_ptr<VCMJitterEstimator> estimator_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,8 +80,8 @@ TEST_F(TestVCMJitterEstimator, TestLowRate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestVCMJitterEstimator, TestLowRateDisabled) {
|
TEST_F(TestVCMJitterEstimator, TestLowRateDisabled) {
|
||||||
test::ScopedFieldTrials field_trials(
|
test::ScopedKeyValueConfig field_trials(
|
||||||
"WebRTC-ReducedJitterDelayKillSwitch/Enabled/");
|
field_trials_, "WebRTC-ReducedJitterDelayKillSwitch/Enabled/");
|
||||||
SetUp();
|
SetUp();
|
||||||
|
|
||||||
ValueGenerator gen(10);
|
ValueGenerator gen(10);
|
||||||
@ -132,7 +134,7 @@ TEST_F(TestVCMJitterEstimator, TestUpperBound) {
|
|||||||
rtc::SimpleStringBuilder ssb(string_buf);
|
rtc::SimpleStringBuilder ssb(string_buf);
|
||||||
ssb << JitterUpperBoundExperiment::kJitterUpperBoundExperimentName
|
ssb << JitterUpperBoundExperiment::kJitterUpperBoundExperimentName
|
||||||
<< "/Enabled-" << context.upper_bound << "/";
|
<< "/Enabled-" << context.upper_bound << "/";
|
||||||
test::ScopedFieldTrials field_trials(ssb.str());
|
test::ScopedKeyValueConfig field_trials(field_trials_, ssb.str());
|
||||||
SetUp();
|
SetUp();
|
||||||
|
|
||||||
ValueGenerator gen(50);
|
ValueGenerator gen(50);
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "test/field_trial.h"
|
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class TestNackModule : public ::testing::TestWithParam<bool>,
|
class TestNackModule : public ::testing::TestWithParam<bool>,
|
||||||
@ -29,7 +29,7 @@ class TestNackModule : public ::testing::TestWithParam<bool>,
|
|||||||
field_trial_(GetParam()
|
field_trial_(GetParam()
|
||||||
? "WebRTC-ExponentialNackBackoff/enabled:true/"
|
? "WebRTC-ExponentialNackBackoff/enabled:true/"
|
||||||
: "WebRTC-ExponentialNackBackoff/enabled:false/"),
|
: "WebRTC-ExponentialNackBackoff/enabled:false/"),
|
||||||
nack_module_(clock_.get(), this, this),
|
nack_module_(clock_.get(), this, this, field_trial_),
|
||||||
keyframes_requested_(0) {}
|
keyframes_requested_(0) {}
|
||||||
|
|
||||||
void SetUp() override { nack_module_.UpdateRtt(kDefaultRttMs); }
|
void SetUp() override { nack_module_.UpdateRtt(kDefaultRttMs); }
|
||||||
@ -44,7 +44,7 @@ class TestNackModule : public ::testing::TestWithParam<bool>,
|
|||||||
|
|
||||||
static constexpr int64_t kDefaultRttMs = 20;
|
static constexpr int64_t kDefaultRttMs = 20;
|
||||||
std::unique_ptr<SimulatedClock> clock_;
|
std::unique_ptr<SimulatedClock> clock_;
|
||||||
test::ScopedFieldTrials field_trial_;
|
test::ScopedKeyValueConfig field_trial_;
|
||||||
DEPRECATED_NackModule nack_module_;
|
DEPRECATED_NackModule nack_module_;
|
||||||
std::vector<uint16_t> sent_nacks_;
|
std::vector<uint16_t> sent_nacks_;
|
||||||
int keyframes_requested_;
|
int keyframes_requested_;
|
||||||
@ -339,7 +339,7 @@ class TestNackModuleWithFieldTrial : public ::testing::Test,
|
|||||||
TestNackModuleWithFieldTrial()
|
TestNackModuleWithFieldTrial()
|
||||||
: nack_delay_field_trial_("WebRTC-SendNackDelayMs/10/"),
|
: nack_delay_field_trial_("WebRTC-SendNackDelayMs/10/"),
|
||||||
clock_(new SimulatedClock(0)),
|
clock_(new SimulatedClock(0)),
|
||||||
nack_module_(clock_.get(), this, this),
|
nack_module_(clock_.get(), this, this, nack_delay_field_trial_),
|
||||||
keyframes_requested_(0) {}
|
keyframes_requested_(0) {}
|
||||||
|
|
||||||
void SendNack(const std::vector<uint16_t>& sequence_numbers,
|
void SendNack(const std::vector<uint16_t>& sequence_numbers,
|
||||||
@ -350,7 +350,7 @@ class TestNackModuleWithFieldTrial : public ::testing::Test,
|
|||||||
|
|
||||||
void RequestKeyFrame() override { ++keyframes_requested_; }
|
void RequestKeyFrame() override { ++keyframes_requested_; }
|
||||||
|
|
||||||
test::ScopedFieldTrials nack_delay_field_trial_;
|
test::ScopedKeyValueConfig nack_delay_field_trial_;
|
||||||
std::unique_ptr<SimulatedClock> clock_;
|
std::unique_ptr<SimulatedClock> clock_;
|
||||||
DEPRECATED_NackModule nack_module_;
|
DEPRECATED_NackModule nack_module_;
|
||||||
std::vector<uint16_t> sent_nacks_;
|
std::vector<uint16_t> sent_nacks_;
|
||||||
|
|||||||
@ -20,7 +20,6 @@
|
|||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/task_queue.h"
|
#include "rtc_base/task_queue.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -33,10 +32,9 @@ const int kMaxReorderedPackets = 128;
|
|||||||
const int kNumReorderingBuckets = 10;
|
const int kNumReorderingBuckets = 10;
|
||||||
const int kDefaultSendNackDelayMs = 0;
|
const int kDefaultSendNackDelayMs = 0;
|
||||||
|
|
||||||
int64_t GetSendNackDelay() {
|
int64_t GetSendNackDelay(const WebRtcKeyValueConfig& field_trials) {
|
||||||
int64_t delay_ms = strtol(
|
int64_t delay_ms = strtol(
|
||||||
webrtc::field_trial::FindFullName("WebRTC-SendNackDelayMs").c_str(),
|
field_trials.Lookup("WebRTC-SendNackDelayMs").c_str(), nullptr, 10);
|
||||||
nullptr, 10);
|
|
||||||
if (delay_ms > 0 && delay_ms <= 20) {
|
if (delay_ms > 0 && delay_ms <= 20) {
|
||||||
RTC_LOG(LS_INFO) << "SendNackDelay is set to " << delay_ms;
|
RTC_LOG(LS_INFO) << "SendNackDelay is set to " << delay_ms;
|
||||||
return delay_ms;
|
return delay_ms;
|
||||||
@ -110,7 +108,8 @@ NackRequester::BackoffSettings::BackoffSettings(TimeDelta min_retry,
|
|||||||
: min_retry_interval(min_retry), max_rtt(max_rtt), base(base) {}
|
: min_retry_interval(min_retry), max_rtt(max_rtt), base(base) {}
|
||||||
|
|
||||||
absl::optional<NackRequester::BackoffSettings>
|
absl::optional<NackRequester::BackoffSettings>
|
||||||
NackRequester::BackoffSettings::ParseFromFieldTrials() {
|
NackRequester::BackoffSettings::ParseFromFieldTrials(
|
||||||
|
const WebRtcKeyValueConfig& field_trials) {
|
||||||
// Matches magic number in RTPSender::OnReceivedNack().
|
// Matches magic number in RTPSender::OnReceivedNack().
|
||||||
const TimeDelta kDefaultMinRetryInterval = TimeDelta::Millis(5);
|
const TimeDelta kDefaultMinRetryInterval = TimeDelta::Millis(5);
|
||||||
// Upper bound on link-delay considered for exponential backoff.
|
// Upper bound on link-delay considered for exponential backoff.
|
||||||
@ -126,7 +125,7 @@ NackRequester::BackoffSettings::ParseFromFieldTrials() {
|
|||||||
FieldTrialParameter<TimeDelta> max_rtt("max_rtt", kDefaultMaxRtt);
|
FieldTrialParameter<TimeDelta> max_rtt("max_rtt", kDefaultMaxRtt);
|
||||||
FieldTrialParameter<double> base("base", kDefaultBase);
|
FieldTrialParameter<double> base("base", kDefaultBase);
|
||||||
ParseFieldTrial({&enabled, &min_retry, &max_rtt, &base},
|
ParseFieldTrial({&enabled, &min_retry, &max_rtt, &base},
|
||||||
field_trial::FindFullName("WebRTC-ExponentialNackBackoff"));
|
field_trials.Lookup("WebRTC-ExponentialNackBackoff"));
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
return NackRequester::BackoffSettings(min_retry.Get(), max_rtt.Get(),
|
return NackRequester::BackoffSettings(min_retry.Get(), max_rtt.Get(),
|
||||||
@ -139,7 +138,8 @@ NackRequester::NackRequester(TaskQueueBase* current_queue,
|
|||||||
NackPeriodicProcessor* periodic_processor,
|
NackPeriodicProcessor* periodic_processor,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
NackSender* nack_sender,
|
NackSender* nack_sender,
|
||||||
KeyFrameRequestSender* keyframe_request_sender)
|
KeyFrameRequestSender* keyframe_request_sender,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: worker_thread_(current_queue),
|
: worker_thread_(current_queue),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
nack_sender_(nack_sender),
|
nack_sender_(nack_sender),
|
||||||
@ -148,8 +148,8 @@ NackRequester::NackRequester(TaskQueueBase* current_queue,
|
|||||||
initialized_(false),
|
initialized_(false),
|
||||||
rtt_ms_(kDefaultRttMs),
|
rtt_ms_(kDefaultRttMs),
|
||||||
newest_seq_num_(0),
|
newest_seq_num_(0),
|
||||||
send_nack_delay_ms_(GetSendNackDelay()),
|
send_nack_delay_ms_(GetSendNackDelay(field_trials)),
|
||||||
backoff_settings_(BackoffSettings::ParseFromFieldTrials()),
|
backoff_settings_(BackoffSettings::ParseFromFieldTrials(field_trials)),
|
||||||
processor_registration_(this, periodic_processor) {
|
processor_registration_(this, periodic_processor) {
|
||||||
RTC_DCHECK(clock_);
|
RTC_DCHECK(clock_);
|
||||||
RTC_DCHECK(nack_sender_);
|
RTC_DCHECK(nack_sender_);
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/include/module_common_types.h"
|
#include "modules/include/module_common_types.h"
|
||||||
#include "modules/video_coding/histogram.h"
|
#include "modules/video_coding/histogram.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_util.h"
|
||||||
@ -70,7 +71,8 @@ class NackRequester final : public NackRequesterBase {
|
|||||||
NackPeriodicProcessor* periodic_processor,
|
NackPeriodicProcessor* periodic_processor,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
NackSender* nack_sender,
|
NackSender* nack_sender,
|
||||||
KeyFrameRequestSender* keyframe_request_sender);
|
KeyFrameRequestSender* keyframe_request_sender,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
~NackRequester();
|
~NackRequester();
|
||||||
|
|
||||||
void ProcessNacks() override;
|
void ProcessNacks() override;
|
||||||
@ -104,7 +106,8 @@ class NackRequester final : public NackRequesterBase {
|
|||||||
|
|
||||||
struct BackoffSettings {
|
struct BackoffSettings {
|
||||||
BackoffSettings(TimeDelta min_retry, TimeDelta max_rtt, double base);
|
BackoffSettings(TimeDelta min_retry, TimeDelta max_rtt, double base);
|
||||||
static absl::optional<BackoffSettings> ParseFromFieldTrials();
|
static absl::optional<BackoffSettings> ParseFromFieldTrials(
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
|
|
||||||
// Min time between nacks.
|
// Min time between nacks.
|
||||||
const TimeDelta min_retry_interval;
|
const TimeDelta min_retry_interval;
|
||||||
|
|||||||
@ -16,9 +16,9 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "test/field_trial.h"
|
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
#include "test/run_loop.h"
|
#include "test/run_loop.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
// TODO(bugs.webrtc.org/11594): Use the use the GlobalSimulatedTimeController
|
// TODO(bugs.webrtc.org/11594): Use the use the GlobalSimulatedTimeController
|
||||||
@ -86,7 +86,7 @@ class TestNackRequester : public ::testing::TestWithParam<bool>,
|
|||||||
std::make_unique<NackPeriodicProcessor>(interval);
|
std::make_unique<NackPeriodicProcessor>(interval);
|
||||||
nack_module_ = std::make_unique<NackRequester>(
|
nack_module_ = std::make_unique<NackRequester>(
|
||||||
TaskQueueBase::Current(), nack_periodic_processor_.get(), clock_.get(),
|
TaskQueueBase::Current(), nack_periodic_processor_.get(), clock_.get(),
|
||||||
this, this);
|
this, this, field_trial_);
|
||||||
nack_module_->UpdateRtt(kDefaultRttMs);
|
nack_module_->UpdateRtt(kDefaultRttMs);
|
||||||
return *nack_module_.get();
|
return *nack_module_.get();
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ class TestNackRequester : public ::testing::TestWithParam<bool>,
|
|||||||
static constexpr int64_t kDefaultRttMs = 20;
|
static constexpr int64_t kDefaultRttMs = 20;
|
||||||
test::RunLoop loop_;
|
test::RunLoop loop_;
|
||||||
std::unique_ptr<SimulatedClock> clock_;
|
std::unique_ptr<SimulatedClock> clock_;
|
||||||
test::ScopedFieldTrials field_trial_;
|
test::ScopedKeyValueConfig field_trial_;
|
||||||
std::unique_ptr<NackPeriodicProcessor> nack_periodic_processor_;
|
std::unique_ptr<NackPeriodicProcessor> nack_periodic_processor_;
|
||||||
std::unique_ptr<NackRequester> nack_module_;
|
std::unique_ptr<NackRequester> nack_module_;
|
||||||
std::vector<uint16_t> sent_nacks_;
|
std::vector<uint16_t> sent_nacks_;
|
||||||
@ -387,7 +387,8 @@ class TestNackRequesterWithFieldTrial : public ::testing::Test,
|
|||||||
&nack_periodic_processor_,
|
&nack_periodic_processor_,
|
||||||
clock_.get(),
|
clock_.get(),
|
||||||
this,
|
this,
|
||||||
this),
|
this,
|
||||||
|
nack_delay_field_trial_),
|
||||||
keyframes_requested_(0) {}
|
keyframes_requested_(0) {}
|
||||||
|
|
||||||
void SendNack(const std::vector<uint16_t>& sequence_numbers,
|
void SendNack(const std::vector<uint16_t>& sequence_numbers,
|
||||||
@ -398,7 +399,7 @@ class TestNackRequesterWithFieldTrial : public ::testing::Test,
|
|||||||
|
|
||||||
void RequestKeyFrame() override { ++keyframes_requested_; }
|
void RequestKeyFrame() override { ++keyframes_requested_; }
|
||||||
|
|
||||||
test::ScopedFieldTrials nack_delay_field_trial_;
|
test::ScopedKeyValueConfig nack_delay_field_trial_;
|
||||||
std::unique_ptr<SimulatedClock> clock_;
|
std::unique_ptr<SimulatedClock> clock_;
|
||||||
NackPeriodicProcessor nack_periodic_processor_;
|
NackPeriodicProcessor nack_periodic_processor_;
|
||||||
NackRequester nack_module_;
|
NackRequester nack_module_;
|
||||||
|
|||||||
@ -30,18 +30,22 @@ namespace webrtc {
|
|||||||
|
|
||||||
enum { kMaxReceiverDelayMs = 10000 };
|
enum { kMaxReceiverDelayMs = 10000 };
|
||||||
|
|
||||||
VCMReceiver::VCMReceiver(VCMTiming* timing, Clock* clock)
|
VCMReceiver::VCMReceiver(VCMTiming* timing,
|
||||||
|
Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: VCMReceiver::VCMReceiver(timing,
|
: VCMReceiver::VCMReceiver(timing,
|
||||||
clock,
|
clock,
|
||||||
absl::WrapUnique(EventWrapper::Create()),
|
absl::WrapUnique(EventWrapper::Create()),
|
||||||
absl::WrapUnique(EventWrapper::Create())) {}
|
absl::WrapUnique(EventWrapper::Create()),
|
||||||
|
field_trials) {}
|
||||||
|
|
||||||
VCMReceiver::VCMReceiver(VCMTiming* timing,
|
VCMReceiver::VCMReceiver(VCMTiming* timing,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
std::unique_ptr<EventWrapper> receiver_event,
|
std::unique_ptr<EventWrapper> receiver_event,
|
||||||
std::unique_ptr<EventWrapper> jitter_buffer_event)
|
std::unique_ptr<EventWrapper> jitter_buffer_event,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
jitter_buffer_(clock_, std::move(jitter_buffer_event)),
|
jitter_buffer_(clock_, std::move(jitter_buffer_event), field_trials),
|
||||||
timing_(timing),
|
timing_(timing),
|
||||||
render_wait_event_(std::move(receiver_event)),
|
render_wait_event_(std::move(receiver_event)),
|
||||||
max_video_delay_ms_(kMaxVideoDelayMs) {
|
max_video_delay_ms_(kMaxVideoDelayMs) {
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/event_wrapper.h"
|
#include "modules/video_coding/event_wrapper.h"
|
||||||
#include "modules/video_coding/include/video_coding.h"
|
#include "modules/video_coding/include/video_coding.h"
|
||||||
#include "modules/video_coding/include/video_coding_defines.h"
|
#include "modules/video_coding/include/video_coding_defines.h"
|
||||||
@ -28,7 +29,9 @@ class VCMEncodedFrame;
|
|||||||
|
|
||||||
class VCMReceiver {
|
class VCMReceiver {
|
||||||
public:
|
public:
|
||||||
VCMReceiver(VCMTiming* timing, Clock* clock);
|
VCMReceiver(VCMTiming* timing,
|
||||||
|
Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
|
|
||||||
// Using this constructor, you can specify a different event implemetation for
|
// Using this constructor, you can specify a different event implemetation for
|
||||||
// the jitter buffer. Useful for unit tests when you want to simulate incoming
|
// the jitter buffer. Useful for unit tests when you want to simulate incoming
|
||||||
@ -37,7 +40,8 @@ class VCMReceiver {
|
|||||||
VCMReceiver(VCMTiming* timing,
|
VCMReceiver(VCMTiming* timing,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
std::unique_ptr<EventWrapper> receiver_event,
|
std::unique_ptr<EventWrapper> receiver_event,
|
||||||
std::unique_ptr<EventWrapper> jitter_buffer_event);
|
std::unique_ptr<EventWrapper> jitter_buffer_event,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
|
|
||||||
~VCMReceiver();
|
~VCMReceiver();
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -31,8 +32,8 @@ class TestVCMReceiver : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
TestVCMReceiver()
|
TestVCMReceiver()
|
||||||
: clock_(0),
|
: clock_(0),
|
||||||
timing_(&clock_),
|
timing_(&clock_, field_trials_),
|
||||||
receiver_(&timing_, &clock_),
|
receiver_(&timing_, &clock_, field_trials_),
|
||||||
stream_generator_(0, clock_.TimeInMilliseconds()) {}
|
stream_generator_(0, clock_.TimeInMilliseconds()) {}
|
||||||
|
|
||||||
int32_t InsertPacket(int index) {
|
int32_t InsertPacket(int index) {
|
||||||
@ -78,6 +79,7 @@ class TestVCMReceiver : public ::testing::Test {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
SimulatedClock clock_;
|
SimulatedClock clock_;
|
||||||
VCMTiming timing_;
|
VCMTiming timing_;
|
||||||
VCMReceiver receiver_;
|
VCMReceiver receiver_;
|
||||||
@ -365,16 +367,17 @@ class VCMReceiverTimingTest : public ::testing::Test {
|
|||||||
VCMReceiverTimingTest()
|
VCMReceiverTimingTest()
|
||||||
: clock_(&stream_generator_, &receiver_),
|
: clock_(&stream_generator_, &receiver_),
|
||||||
stream_generator_(0, clock_.TimeInMilliseconds()),
|
stream_generator_(0, clock_.TimeInMilliseconds()),
|
||||||
timing_(&clock_),
|
timing_(&clock_, field_trials_),
|
||||||
receiver_(
|
receiver_(
|
||||||
&timing_,
|
&timing_,
|
||||||
&clock_,
|
&clock_,
|
||||||
std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
|
std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
|
||||||
std::unique_ptr<EventWrapper>(
|
std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, true)),
|
||||||
new FrameInjectEvent(&clock_, true))) {}
|
field_trials_) {}
|
||||||
|
|
||||||
virtual void SetUp() {}
|
virtual void SetUp() {}
|
||||||
|
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
SimulatedClockWithFrames clock_;
|
SimulatedClockWithFrames clock_;
|
||||||
StreamGenerator stream_generator_;
|
StreamGenerator stream_generator_;
|
||||||
VCMTiming timing_;
|
VCMTiming timing_;
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/time/timestamp_extrapolator.h"
|
#include "rtc_base/time/timestamp_extrapolator.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "system_wrappers/include/field_trial.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -25,7 +24,7 @@ namespace {
|
|||||||
constexpr TimeDelta kZeroPlayoutDelayDefaultMinPacing = TimeDelta::Millis(8);
|
constexpr TimeDelta kZeroPlayoutDelayDefaultMinPacing = TimeDelta::Millis(8);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
VCMTiming::VCMTiming(Clock* clock)
|
VCMTiming::VCMTiming(Clock* clock, const WebRtcKeyValueConfig& field_trials)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
ts_extrapolator_(
|
ts_extrapolator_(
|
||||||
std::make_unique<TimestampExtrapolator>(clock_->CurrentTime())),
|
std::make_unique<TimestampExtrapolator>(clock_->CurrentTime())),
|
||||||
@ -42,9 +41,9 @@ VCMTiming::VCMTiming(Clock* clock)
|
|||||||
kZeroPlayoutDelayDefaultMinPacing),
|
kZeroPlayoutDelayDefaultMinPacing),
|
||||||
last_decode_scheduled_(Timestamp::Zero()) {
|
last_decode_scheduled_(Timestamp::Zero()) {
|
||||||
ParseFieldTrial({&low_latency_renderer_enabled_},
|
ParseFieldTrial({&low_latency_renderer_enabled_},
|
||||||
field_trial::FindFullName("WebRTC-LowLatencyRenderer"));
|
field_trials.Lookup("WebRTC-LowLatencyRenderer"));
|
||||||
ParseFieldTrial({&zero_playout_delay_min_pacing_},
|
ParseFieldTrial({&zero_playout_delay_min_pacing_},
|
||||||
field_trial::FindFullName("WebRTC-ZeroPlayoutDelay"));
|
field_trials.Lookup("WebRTC-ZeroPlayoutDelay"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCMTiming::Reset() {
|
void VCMTiming::Reset() {
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
#include "api/video/video_timing.h"
|
#include "api/video/video_timing.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/codec_timer.h"
|
#include "modules/video_coding/codec_timer.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/synchronization/mutex.h"
|
#include "rtc_base/synchronization/mutex.h"
|
||||||
@ -32,7 +33,7 @@ class VCMTiming {
|
|||||||
static constexpr auto kDefaultRenderDelay = TimeDelta::Millis(10);
|
static constexpr auto kDefaultRenderDelay = TimeDelta::Millis(10);
|
||||||
static constexpr auto kDelayMaxChangeMsPerS = 100;
|
static constexpr auto kDelayMaxChangeMsPerS = 100;
|
||||||
|
|
||||||
explicit VCMTiming(Clock* clock);
|
VCMTiming(Clock* clock, const WebRtcKeyValueConfig& field_trials);
|
||||||
virtual ~VCMTiming() = default;
|
virtual ~VCMTiming() = default;
|
||||||
|
|
||||||
// Resets the timing to the initial state.
|
// Resets the timing to the initial state.
|
||||||
|
|||||||
@ -13,8 +13,8 @@
|
|||||||
#include "api/units/frequency.h"
|
#include "api/units/frequency.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "test/field_trial.h"
|
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -25,8 +25,9 @@ constexpr Frequency k90kHz = Frequency::KiloHertz(90);
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(ReceiverTimingTest, JitterDelay) {
|
TEST(ReceiverTimingTest, JitterDelay) {
|
||||||
|
test::ScopedKeyValueConfig field_trials;
|
||||||
SimulatedClock clock(0);
|
SimulatedClock clock(0);
|
||||||
VCMTiming timing(&clock);
|
VCMTiming timing(&clock, field_trials);
|
||||||
timing.Reset();
|
timing.Reset();
|
||||||
|
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
@ -118,8 +119,9 @@ TEST(ReceiverTimingTest, JitterDelay) {
|
|||||||
|
|
||||||
TEST(ReceiverTimingTest, TimestampWrapAround) {
|
TEST(ReceiverTimingTest, TimestampWrapAround) {
|
||||||
constexpr auto kStartTime = Timestamp::Millis(1337);
|
constexpr auto kStartTime = Timestamp::Millis(1337);
|
||||||
|
test::ScopedKeyValueConfig field_trials;
|
||||||
SimulatedClock clock(kStartTime);
|
SimulatedClock clock(kStartTime);
|
||||||
VCMTiming timing(&clock);
|
VCMTiming timing(&clock, field_trials);
|
||||||
|
|
||||||
// Provoke a wrap-around. The fifth frame will have wrapped at 25 fps.
|
// Provoke a wrap-around. The fifth frame will have wrapped at 25 fps.
|
||||||
constexpr uint32_t kRtpTicksPerFrame = k90kHz / k25Fps;
|
constexpr uint32_t kRtpTicksPerFrame = k90kHz / k25Fps;
|
||||||
@ -143,7 +145,8 @@ TEST(ReceiverTimingTest, MaxWaitingTimeIsZeroForZeroRenderTime) {
|
|||||||
constexpr TimeDelta kTimeDelta = 1 / Frequency::Hertz(60);
|
constexpr TimeDelta kTimeDelta = 1 / Frequency::Hertz(60);
|
||||||
constexpr Timestamp kZeroRenderTime = Timestamp::Zero();
|
constexpr Timestamp kZeroRenderTime = Timestamp::Zero();
|
||||||
SimulatedClock clock(kStartTimeUs);
|
SimulatedClock clock(kStartTimeUs);
|
||||||
VCMTiming timing(&clock);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
VCMTiming timing(&clock, field_trials);
|
||||||
timing.Reset();
|
timing.Reset();
|
||||||
timing.set_max_playout_delay(TimeDelta::Zero());
|
timing.set_max_playout_delay(TimeDelta::Zero());
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
@ -175,13 +178,13 @@ TEST(ReceiverTimingTest, MaxWaitingTimeZeroDelayPacingExperiment) {
|
|||||||
// The minimum pacing is enabled by a field trial and active if the RTP
|
// The minimum pacing is enabled by a field trial and active if the RTP
|
||||||
// playout delay header extension is set to min==0.
|
// playout delay header extension is set to min==0.
|
||||||
constexpr TimeDelta kMinPacing = TimeDelta::Millis(3);
|
constexpr TimeDelta kMinPacing = TimeDelta::Millis(3);
|
||||||
test::ScopedFieldTrials override_field_trials(
|
test::ScopedKeyValueConfig field_trials(
|
||||||
"WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
|
"WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
|
||||||
constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
|
constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
|
||||||
constexpr TimeDelta kTimeDelta = 1 / Frequency::Hertz(60);
|
constexpr TimeDelta kTimeDelta = 1 / Frequency::Hertz(60);
|
||||||
constexpr auto kZeroRenderTime = Timestamp::Zero();
|
constexpr auto kZeroRenderTime = Timestamp::Zero();
|
||||||
SimulatedClock clock(kStartTimeUs);
|
SimulatedClock clock(kStartTimeUs);
|
||||||
VCMTiming timing(&clock);
|
VCMTiming timing(&clock, field_trials);
|
||||||
timing.Reset();
|
timing.Reset();
|
||||||
// MaxWaitingTime() returns zero for evenly spaced video frames.
|
// MaxWaitingTime() returns zero for evenly spaced video frames.
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
@ -224,12 +227,12 @@ TEST(ReceiverTimingTest, MaxWaitingTimeZeroDelayPacingExperiment) {
|
|||||||
TEST(ReceiverTimingTest, DefaultMaxWaitingTimeUnaffectedByPacingExperiment) {
|
TEST(ReceiverTimingTest, DefaultMaxWaitingTimeUnaffectedByPacingExperiment) {
|
||||||
// The minimum pacing is enabled by a field trial but should not have any
|
// The minimum pacing is enabled by a field trial but should not have any
|
||||||
// effect if render_time_ms is greater than 0;
|
// effect if render_time_ms is greater than 0;
|
||||||
test::ScopedFieldTrials override_field_trials(
|
test::ScopedKeyValueConfig field_trials(
|
||||||
"WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
|
"WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
|
||||||
constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
|
constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
|
||||||
const TimeDelta kTimeDelta = TimeDelta::Millis(1000.0 / 60.0);
|
const TimeDelta kTimeDelta = TimeDelta::Millis(1000.0 / 60.0);
|
||||||
SimulatedClock clock(kStartTimeUs);
|
SimulatedClock clock(kStartTimeUs);
|
||||||
VCMTiming timing(&clock);
|
VCMTiming timing(&clock, field_trials);
|
||||||
timing.Reset();
|
timing.Reset();
|
||||||
clock.AdvanceTime(kTimeDelta);
|
clock.AdvanceTime(kTimeDelta);
|
||||||
auto now = clock.CurrentTime();
|
auto now = clock.CurrentTime();
|
||||||
@ -255,13 +258,13 @@ TEST(ReceiverTimingTest, MaxWaitingTimeReturnsZeroIfTooManyFramesQueuedIsTrue) {
|
|||||||
// The minimum pacing is enabled by a field trial and active if the RTP
|
// The minimum pacing is enabled by a field trial and active if the RTP
|
||||||
// playout delay header extension is set to min==0.
|
// playout delay header extension is set to min==0.
|
||||||
constexpr TimeDelta kMinPacing = TimeDelta::Millis(3);
|
constexpr TimeDelta kMinPacing = TimeDelta::Millis(3);
|
||||||
test::ScopedFieldTrials override_field_trials(
|
test::ScopedKeyValueConfig field_trials(
|
||||||
"WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
|
"WebRTC-ZeroPlayoutDelay/min_pacing:3ms/");
|
||||||
constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
|
constexpr int64_t kStartTimeUs = 3.15e13; // About one year in us.
|
||||||
const TimeDelta kTimeDelta = TimeDelta::Millis(1000.0 / 60.0);
|
const TimeDelta kTimeDelta = TimeDelta::Millis(1000.0 / 60.0);
|
||||||
constexpr auto kZeroRenderTime = Timestamp::Zero();
|
constexpr auto kZeroRenderTime = Timestamp::Zero();
|
||||||
SimulatedClock clock(kStartTimeUs);
|
SimulatedClock clock(kStartTimeUs);
|
||||||
VCMTiming timing(&clock);
|
VCMTiming timing(&clock, field_trials);
|
||||||
timing.Reset();
|
timing.Reset();
|
||||||
// MaxWaitingTime() returns zero for evenly spaced video frames.
|
// MaxWaitingTime() returns zero for evenly spaced video frames.
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
|||||||
@ -14,9 +14,12 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
|
#include "api/transport/field_trial_based_config.h"
|
||||||
#include "api/video/encoded_image.h"
|
#include "api/video/encoded_image.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "modules/video_coding/timing.h"
|
#include "modules/video_coding/timing.h"
|
||||||
|
#include "rtc_base/memory/always_valid_pointer.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -41,10 +44,12 @@ namespace {
|
|||||||
|
|
||||||
class VideoCodingModuleImpl : public VideoCodingModule {
|
class VideoCodingModuleImpl : public VideoCodingModule {
|
||||||
public:
|
public:
|
||||||
explicit VideoCodingModuleImpl(Clock* clock)
|
explicit VideoCodingModuleImpl(Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig* field_trials)
|
||||||
: VideoCodingModule(),
|
: VideoCodingModule(),
|
||||||
timing_(new VCMTiming(clock)),
|
field_trials_(field_trials),
|
||||||
receiver_(clock, timing_.get()) {}
|
timing_(new VCMTiming(clock, *field_trials_)),
|
||||||
|
receiver_(clock, timing_.get(), *field_trials_) {}
|
||||||
|
|
||||||
~VideoCodingModuleImpl() override {}
|
~VideoCodingModuleImpl() override {}
|
||||||
|
|
||||||
@ -104,6 +109,8 @@ class VideoCodingModuleImpl : public VideoCodingModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
AlwaysValidPointer<const WebRtcKeyValueConfig, FieldTrialBasedConfig>
|
||||||
|
field_trials_;
|
||||||
SequenceChecker construction_thread_;
|
SequenceChecker construction_thread_;
|
||||||
const std::unique_ptr<VCMTiming> timing_;
|
const std::unique_ptr<VCMTiming> timing_;
|
||||||
vcm::VideoReceiver receiver_;
|
vcm::VideoReceiver receiver_;
|
||||||
@ -112,9 +119,11 @@ class VideoCodingModuleImpl : public VideoCodingModule {
|
|||||||
|
|
||||||
// DEPRECATED. Create method for current interface, will be removed when the
|
// DEPRECATED. Create method for current interface, will be removed when the
|
||||||
// new jitter buffer is in place.
|
// new jitter buffer is in place.
|
||||||
VideoCodingModule* VideoCodingModule::Create(Clock* clock) {
|
VideoCodingModule* VideoCodingModule::Create(
|
||||||
|
Clock* clock,
|
||||||
|
const WebRtcKeyValueConfig* field_trials) {
|
||||||
RTC_DCHECK(clock);
|
RTC_DCHECK(clock);
|
||||||
return new VideoCodingModuleImpl(clock);
|
return new VideoCodingModuleImpl(clock, field_trials);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/decoder_database.h"
|
#include "modules/video_coding/decoder_database.h"
|
||||||
#include "modules/video_coding/frame_buffer.h"
|
#include "modules/video_coding/frame_buffer.h"
|
||||||
#include "modules/video_coding/generic_decoder.h"
|
#include "modules/video_coding/generic_decoder.h"
|
||||||
@ -56,7 +57,9 @@ class VCMProcessTimer {
|
|||||||
|
|
||||||
class VideoReceiver : public Module {
|
class VideoReceiver : public Module {
|
||||||
public:
|
public:
|
||||||
VideoReceiver(Clock* clock, VCMTiming* timing);
|
VideoReceiver(Clock* clock,
|
||||||
|
VCMTiming* timing,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
~VideoReceiver() override;
|
~VideoReceiver() override;
|
||||||
|
|
||||||
void RegisterReceiveCodec(uint8_t payload_type,
|
void RegisterReceiveCodec(uint8_t payload_type,
|
||||||
|
|||||||
@ -40,11 +40,13 @@
|
|||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace vcm {
|
namespace vcm {
|
||||||
|
|
||||||
VideoReceiver::VideoReceiver(Clock* clock, VCMTiming* timing)
|
VideoReceiver::VideoReceiver(Clock* clock,
|
||||||
|
VCMTiming* timing,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
_timing(timing),
|
_timing(timing),
|
||||||
_receiver(_timing, clock_),
|
_receiver(_timing, clock_, field_trials),
|
||||||
_decodedFrameCallback(_timing, clock_),
|
_decodedFrameCallback(_timing, clock_, field_trials),
|
||||||
_frameTypeCallback(nullptr),
|
_frameTypeCallback(nullptr),
|
||||||
_packetRequestCallback(nullptr),
|
_packetRequestCallback(nullptr),
|
||||||
_scheduleKeyRequest(false),
|
_scheduleKeyRequest(false),
|
||||||
|
|||||||
@ -28,10 +28,12 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
VideoReceiver2::VideoReceiver2(Clock* clock, VCMTiming* timing)
|
VideoReceiver2::VideoReceiver2(Clock* clock,
|
||||||
|
VCMTiming* timing,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
timing_(timing),
|
timing_(timing),
|
||||||
decodedFrameCallback_(timing_, clock_),
|
decodedFrameCallback_(timing_, clock_, field_trials),
|
||||||
codecDataBase_() {
|
codecDataBase_() {
|
||||||
decoder_sequence_checker_.Detach();
|
decoder_sequence_checker_.Detach();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
#include "api/video_codecs/video_decoder.h"
|
#include "api/video_codecs/video_decoder.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/decoder_database.h"
|
#include "modules/video_coding/decoder_database.h"
|
||||||
#include "modules/video_coding/encoded_frame.h"
|
#include "modules/video_coding/encoded_frame.h"
|
||||||
#include "modules/video_coding/generic_decoder.h"
|
#include "modules/video_coding/generic_decoder.h"
|
||||||
@ -28,7 +29,9 @@ namespace webrtc {
|
|||||||
// VideoCodingModule api.
|
// VideoCodingModule api.
|
||||||
class VideoReceiver2 {
|
class VideoReceiver2 {
|
||||||
public:
|
public:
|
||||||
VideoReceiver2(Clock* clock, VCMTiming* timing);
|
VideoReceiver2(Clock* clock,
|
||||||
|
VCMTiming* timing,
|
||||||
|
const WebRtcKeyValueConfig& field_trials);
|
||||||
~VideoReceiver2();
|
~VideoReceiver2();
|
||||||
|
|
||||||
void RegisterReceiveCodec(uint8_t payload_type,
|
void RegisterReceiveCodec(uint8_t payload_type,
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include "modules/video_coding/video_coding_impl.h"
|
#include "modules/video_coding/video_coding_impl.h"
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::AnyNumber;
|
using ::testing::AnyNumber;
|
||||||
@ -51,7 +52,9 @@ class TestVideoReceiver : public ::testing::Test {
|
|||||||
static const uint16_t kMaxWaitTimeMs = 100;
|
static const uint16_t kMaxWaitTimeMs = 100;
|
||||||
|
|
||||||
TestVideoReceiver()
|
TestVideoReceiver()
|
||||||
: clock_(0), timing_(&clock_), receiver_(&clock_, &timing_) {}
|
: clock_(0),
|
||||||
|
timing_(&clock_, field_trials_),
|
||||||
|
receiver_(&clock_, &timing_, field_trials_) {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
// Register decoder.
|
// Register decoder.
|
||||||
@ -118,6 +121,7 @@ class TestVideoReceiver : public ::testing::Test {
|
|||||||
EXPECT_EQ(0, receiver_.Decode(kMaxWaitTimeMs));
|
EXPECT_EQ(0, receiver_.Decode(kMaxWaitTimeMs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
SimulatedClock clock_;
|
SimulatedClock clock_;
|
||||||
NiceMock<MockVideoDecoder> decoder_;
|
NiceMock<MockVideoDecoder> decoder_;
|
||||||
NiceMock<MockPacketRequestCallback> packet_request_callback_;
|
NiceMock<MockPacketRequestCallback> packet_request_callback_;
|
||||||
|
|||||||
@ -613,6 +613,7 @@ webrtc_fuzzer_test("frame_buffer2_fuzzer") {
|
|||||||
deps = [
|
deps = [
|
||||||
"../../modules/video_coding:timing",
|
"../../modules/video_coding:timing",
|
||||||
"../../modules/video_coding/",
|
"../../modules/video_coding/",
|
||||||
|
"../../test:scoped_key_value_config",
|
||||||
"../time_controller:time_controller",
|
"../time_controller:time_controller",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -625,6 +626,7 @@ webrtc_fuzzer_test("frame_buffer3_fuzzer") {
|
|||||||
"../../api/video:encoded_frame",
|
"../../api/video:encoded_frame",
|
||||||
"../../modules/video_coding:frame_buffer",
|
"../../modules/video_coding:frame_buffer",
|
||||||
"../../rtc_base:rtc_numerics",
|
"../../rtc_base:rtc_numerics",
|
||||||
|
"../../test:scoped_key_value_config",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "modules/video_coding/frame_buffer2.h"
|
#include "modules/video_coding/frame_buffer2.h"
|
||||||
#include "modules/video_coding/timing.h"
|
#include "modules/video_coding/timing.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
#include "test/time_controller/simulated_time_controller.h"
|
#include "test/time_controller/simulated_time_controller.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -68,9 +69,10 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
|||||||
rtc::TaskQueue task_queue(
|
rtc::TaskQueue task_queue(
|
||||||
time_controller.GetTaskQueueFactory()->CreateTaskQueue(
|
time_controller.GetTaskQueueFactory()->CreateTaskQueue(
|
||||||
"time_tq", TaskQueueFactory::Priority::NORMAL));
|
"time_tq", TaskQueueFactory::Priority::NORMAL));
|
||||||
VCMTiming timing(time_controller.GetClock());
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
VCMTiming timing(time_controller.GetClock(), field_trials);
|
||||||
video_coding::FrameBuffer frame_buffer(time_controller.GetClock(), &timing,
|
video_coding::FrameBuffer frame_buffer(time_controller.GetClock(), &timing,
|
||||||
nullptr);
|
nullptr, field_trials);
|
||||||
|
|
||||||
bool next_frame_task_running = false;
|
bool next_frame_task_running = false;
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include "modules/video_coding/frame_buffer3.h"
|
#include "modules/video_coding/frame_buffer3.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_util.h"
|
||||||
#include "test/fuzzers/fuzz_data_helper.h"
|
#include "test/fuzzers/fuzz_data_helper.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -31,7 +32,9 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer buffer(/*max_frame_slots=*/100, /*max_decode_history=*/1000);
|
test::ScopedKeyValueConfig field_trials;
|
||||||
|
FrameBuffer buffer(/*max_frame_slots=*/100, /*max_decode_history=*/1000,
|
||||||
|
field_trials);
|
||||||
test::FuzzDataHelper helper(rtc::MakeArrayView(data, size));
|
test::FuzzDataHelper helper(rtc::MakeArrayView(data, size));
|
||||||
SeqNumUnwrapper<uint16_t, kFrameIdLength> unwrapper;
|
SeqNumUnwrapper<uint16_t, kFrameIdLength> unwrapper;
|
||||||
|
|
||||||
|
|||||||
@ -232,7 +232,9 @@ rtc_library("video_stream_decoder_impl") {
|
|||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
"../api:sequence_checker",
|
"../api:sequence_checker",
|
||||||
|
"../api:webrtc_key_value_config",
|
||||||
"../api/task_queue",
|
"../api/task_queue",
|
||||||
|
"../api/transport:field_trial_based_config",
|
||||||
"../api/video:encoded_frame",
|
"../api/video:encoded_frame",
|
||||||
"../api/video:video_frame",
|
"../api/video:video_frame",
|
||||||
"../api/video:video_rtp_headers",
|
"../api/video:video_rtp_headers",
|
||||||
@ -242,6 +244,7 @@ rtc_library("video_stream_decoder_impl") {
|
|||||||
"../modules/video_coding:timing",
|
"../modules/video_coding:timing",
|
||||||
"../rtc_base:rtc_base_approved",
|
"../rtc_base:rtc_base_approved",
|
||||||
"../rtc_base:rtc_task_queue",
|
"../rtc_base:rtc_task_queue",
|
||||||
|
"../rtc_base/memory:always_valid_pointer",
|
||||||
"../rtc_base/synchronization:mutex",
|
"../rtc_base/synchronization:mutex",
|
||||||
"../system_wrappers",
|
"../system_wrappers",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -42,10 +42,11 @@ class FrameBuffer2Proxy : public FrameBufferProxy {
|
|||||||
rtc::TaskQueue* decode_queue,
|
rtc::TaskQueue* decode_queue,
|
||||||
FrameSchedulingReceiver* receiver,
|
FrameSchedulingReceiver* receiver,
|
||||||
TimeDelta max_wait_for_keyframe,
|
TimeDelta max_wait_for_keyframe,
|
||||||
TimeDelta max_wait_for_frame)
|
TimeDelta max_wait_for_frame,
|
||||||
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: max_wait_for_keyframe_(max_wait_for_keyframe),
|
: max_wait_for_keyframe_(max_wait_for_keyframe),
|
||||||
max_wait_for_frame_(max_wait_for_frame),
|
max_wait_for_frame_(max_wait_for_frame),
|
||||||
frame_buffer_(clock, timing, stats_proxy),
|
frame_buffer_(clock, timing, stats_proxy, field_trials),
|
||||||
decode_queue_(decode_queue),
|
decode_queue_(decode_queue),
|
||||||
stats_proxy_(stats_proxy),
|
stats_proxy_(stats_proxy),
|
||||||
receiver_(receiver) {
|
receiver_(receiver) {
|
||||||
@ -182,7 +183,8 @@ class FrameBuffer3Proxy : public FrameBufferProxy {
|
|||||||
TimeDelta max_wait_for_frame,
|
TimeDelta max_wait_for_frame,
|
||||||
std::unique_ptr<FrameDecodeScheduler> frame_decode_scheduler,
|
std::unique_ptr<FrameDecodeScheduler> frame_decode_scheduler,
|
||||||
const WebRtcKeyValueConfig& field_trials)
|
const WebRtcKeyValueConfig& field_trials)
|
||||||
: max_wait_for_keyframe_(max_wait_for_keyframe),
|
: field_trials_(field_trials),
|
||||||
|
max_wait_for_keyframe_(max_wait_for_keyframe),
|
||||||
max_wait_for_frame_(max_wait_for_frame),
|
max_wait_for_frame_(max_wait_for_frame),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
worker_queue_(worker_queue),
|
worker_queue_(worker_queue),
|
||||||
@ -191,9 +193,10 @@ class FrameBuffer3Proxy : public FrameBufferProxy {
|
|||||||
receiver_(receiver),
|
receiver_(receiver),
|
||||||
timing_(timing),
|
timing_(timing),
|
||||||
frame_decode_scheduler_(std::move(frame_decode_scheduler)),
|
frame_decode_scheduler_(std::move(frame_decode_scheduler)),
|
||||||
jitter_estimator_(clock_),
|
jitter_estimator_(clock_, field_trials),
|
||||||
buffer_(std::make_unique<FrameBuffer>(kMaxFramesBuffered,
|
buffer_(std::make_unique<FrameBuffer>(kMaxFramesBuffered,
|
||||||
kMaxFramesHistory)),
|
kMaxFramesHistory,
|
||||||
|
field_trials)),
|
||||||
decode_timing_(clock_, timing_),
|
decode_timing_(clock_, timing_),
|
||||||
timeout_tracker_(clock_,
|
timeout_tracker_(clock_,
|
||||||
worker_queue_,
|
worker_queue_,
|
||||||
@ -237,8 +240,8 @@ class FrameBuffer3Proxy : public FrameBufferProxy {
|
|||||||
void Clear() override {
|
void Clear() override {
|
||||||
RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
|
RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
|
||||||
stats_proxy_->OnDroppedFrames(buffer_->CurrentSize());
|
stats_proxy_->OnDroppedFrames(buffer_->CurrentSize());
|
||||||
buffer_ =
|
buffer_ = std::make_unique<FrameBuffer>(kMaxFramesBuffered,
|
||||||
std::make_unique<FrameBuffer>(kMaxFramesBuffered, kMaxFramesHistory);
|
kMaxFramesHistory, field_trials_);
|
||||||
frame_decode_scheduler_->CancelOutstanding();
|
frame_decode_scheduler_->CancelOutstanding();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,6 +488,7 @@ class FrameBuffer3Proxy : public FrameBufferProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_sequence_checker_;
|
RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_sequence_checker_;
|
||||||
|
const WebRtcKeyValueConfig& field_trials_;
|
||||||
const TimeDelta max_wait_for_keyframe_;
|
const TimeDelta max_wait_for_keyframe_;
|
||||||
const TimeDelta max_wait_for_frame_;
|
const TimeDelta max_wait_for_frame_;
|
||||||
const absl::optional<RttMultExperiment::Settings> rtt_mult_settings_ =
|
const absl::optional<RttMultExperiment::Settings> rtt_mult_settings_ =
|
||||||
@ -597,7 +601,7 @@ std::unique_ptr<FrameBufferProxy> FrameBufferProxy::CreateFromFieldTrial(
|
|||||||
default:
|
default:
|
||||||
return std::make_unique<FrameBuffer2Proxy>(
|
return std::make_unique<FrameBuffer2Proxy>(
|
||||||
clock, timing, stats_proxy, decode_queue, receiver,
|
clock, timing, stats_proxy, decode_queue, receiver,
|
||||||
max_wait_for_keyframe, max_wait_for_frame);
|
max_wait_for_keyframe, max_wait_for_frame, field_trials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -221,7 +221,7 @@ class FrameBufferProxyFixture
|
|||||||
fake_metronome_(time_controller_.GetTaskQueueFactory(),
|
fake_metronome_(time_controller_.GetTaskQueueFactory(),
|
||||||
TimeDelta::Millis(16)),
|
TimeDelta::Millis(16)),
|
||||||
decode_sync_(clock_, &fake_metronome_, run_loop_.task_queue()),
|
decode_sync_(clock_, &fake_metronome_, run_loop_.task_queue()),
|
||||||
timing_(clock_),
|
timing_(clock_, field_trials_),
|
||||||
proxy_(FrameBufferProxy::CreateFromFieldTrial(clock_,
|
proxy_(FrameBufferProxy::CreateFromFieldTrial(clock_,
|
||||||
run_loop_.task_queue(),
|
run_loop_.task_queue(),
|
||||||
&timing_,
|
&timing_,
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "rtc_base/containers/flat_map.h"
|
#include "rtc_base/containers/flat_map.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -30,7 +31,8 @@ namespace {
|
|||||||
|
|
||||||
class FakeVCMTiming : public webrtc::VCMTiming {
|
class FakeVCMTiming : public webrtc::VCMTiming {
|
||||||
public:
|
public:
|
||||||
explicit FakeVCMTiming(Clock* clock) : webrtc::VCMTiming(clock) {}
|
explicit FakeVCMTiming(Clock* clock, const WebRtcKeyValueConfig& field_trials)
|
||||||
|
: webrtc::VCMTiming(clock, field_trials) {}
|
||||||
|
|
||||||
Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
|
Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
|
||||||
RTC_DCHECK(render_time_map_.contains(frame_timestamp));
|
RTC_DCHECK(render_time_map_.contains(frame_timestamp));
|
||||||
@ -63,10 +65,11 @@ class FrameDecodeTimingTest : public ::testing::Test {
|
|||||||
public:
|
public:
|
||||||
FrameDecodeTimingTest()
|
FrameDecodeTimingTest()
|
||||||
: clock_(Timestamp::Millis(1000)),
|
: clock_(Timestamp::Millis(1000)),
|
||||||
timing_(&clock_),
|
timing_(&clock_, field_trials_),
|
||||||
frame_decode_scheduler_(&clock_, &timing_) {}
|
frame_decode_scheduler_(&clock_, &timing_) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
SimulatedClock clock_;
|
SimulatedClock clock_;
|
||||||
FakeVCMTiming timing_;
|
FakeVCMTiming timing_;
|
||||||
FrameDecodeTiming frame_decode_scheduler_;
|
FrameDecodeTiming frame_decode_scheduler_;
|
||||||
|
|||||||
@ -322,7 +322,7 @@ RtpVideoStreamReceiver::RtpVideoStreamReceiver(
|
|||||||
|
|
||||||
if (config_.rtp.nack.rtp_history_ms != 0) {
|
if (config_.rtp.nack.rtp_history_ms != 0) {
|
||||||
nack_module_ = std::make_unique<DEPRECATED_NackModule>(
|
nack_module_ = std::make_unique<DEPRECATED_NackModule>(
|
||||||
clock_, &rtcp_feedback_buffer_, &rtcp_feedback_buffer_);
|
clock_, &rtcp_feedback_buffer_, &rtcp_feedback_buffer_, field_trials_);
|
||||||
process_thread_->RegisterModule(nack_module_.get(), RTC_FROM_HERE);
|
process_thread_->RegisterModule(nack_module_.get(), RTC_FROM_HERE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -108,14 +108,15 @@ std::unique_ptr<NackRequester> MaybeConstructNackModule(
|
|||||||
const VideoReceiveStream::Config& config,
|
const VideoReceiveStream::Config& config,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
NackSender* nack_sender,
|
NackSender* nack_sender,
|
||||||
KeyFrameRequestSender* keyframe_request_sender) {
|
KeyFrameRequestSender* keyframe_request_sender,
|
||||||
|
const WebRtcKeyValueConfig& field_trials) {
|
||||||
if (config.rtp.nack.rtp_history_ms == 0)
|
if (config.rtp.nack.rtp_history_ms == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// TODO(bugs.webrtc.org/12420): pass rtp_history_ms to the nack module.
|
// TODO(bugs.webrtc.org/12420): pass rtp_history_ms to the nack module.
|
||||||
return std::make_unique<NackRequester>(current_queue, nack_periodic_processor,
|
return std::make_unique<NackRequester>(current_queue, nack_periodic_processor,
|
||||||
clock, nack_sender,
|
clock, nack_sender,
|
||||||
keyframe_request_sender);
|
keyframe_request_sender, field_trials);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int kPacketLogIntervalMs = 10000;
|
static const int kPacketLogIntervalMs = 10000;
|
||||||
@ -252,7 +253,8 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2(
|
|||||||
config_,
|
config_,
|
||||||
clock_,
|
clock_,
|
||||||
&rtcp_feedback_buffer_,
|
&rtcp_feedback_buffer_,
|
||||||
&rtcp_feedback_buffer_)),
|
&rtcp_feedback_buffer_,
|
||||||
|
field_trials_)),
|
||||||
packet_buffer_(kPacketBufferStartSize,
|
packet_buffer_(kPacketBufferStartSize,
|
||||||
PacketBufferMaxSize(field_trials_)),
|
PacketBufferMaxSize(field_trials_)),
|
||||||
reference_finder_(std::make_unique<RtpFrameReferenceFinder>()),
|
reference_finder_(std::make_unique<RtpFrameReferenceFinder>()),
|
||||||
|
|||||||
@ -226,7 +226,7 @@ VideoReceiveStream2::VideoReceiveStream2(
|
|||||||
call->trials()),
|
call->trials()),
|
||||||
rtp_receive_statistics_(ReceiveStatistics::Create(clock_)),
|
rtp_receive_statistics_(ReceiveStatistics::Create(clock_)),
|
||||||
timing_(std::move(timing)),
|
timing_(std::move(timing)),
|
||||||
video_receiver_(clock_, timing_.get()),
|
video_receiver_(clock_, timing_.get(), call->trials()),
|
||||||
rtp_video_stream_receiver_(call->worker_thread(),
|
rtp_video_stream_receiver_(call->worker_thread(),
|
||||||
clock_,
|
clock_,
|
||||||
&transport_adapter_,
|
&transport_adapter_,
|
||||||
|
|||||||
@ -102,7 +102,7 @@ class VideoReceiveStream2Test : public ::testing::Test {
|
|||||||
config_.decoders.push_back(h264_decoder);
|
config_.decoders.push_back(h264_decoder);
|
||||||
|
|
||||||
clock_ = Clock::GetRealTimeClock();
|
clock_ = Clock::GetRealTimeClock();
|
||||||
timing_ = new VCMTiming(clock_);
|
timing_ = new VCMTiming(clock_, fake_call_.trials());
|
||||||
|
|
||||||
video_receive_stream_ =
|
video_receive_stream_ =
|
||||||
std::make_unique<webrtc::internal::VideoReceiveStream2>(
|
std::make_unique<webrtc::internal::VideoReceiveStream2>(
|
||||||
@ -292,7 +292,7 @@ class VideoReceiveStream2TestWithFakeDecoder : public ::testing::Test {
|
|||||||
video_receive_stream_->UnregisterFromTransport();
|
video_receive_stream_->UnregisterFromTransport();
|
||||||
video_receive_stream_ = nullptr;
|
video_receive_stream_ = nullptr;
|
||||||
}
|
}
|
||||||
timing_ = new VCMTiming(clock_);
|
timing_ = new VCMTiming(clock_, fake_call_.trials());
|
||||||
video_receive_stream_ =
|
video_receive_stream_ =
|
||||||
std::make_unique<webrtc::internal::VideoReceiveStream2>(
|
std::make_unique<webrtc::internal::VideoReceiveStream2>(
|
||||||
task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
|
task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
|
||||||
@ -564,7 +564,8 @@ class VideoReceiveStream2TestWithSimulatedClock
|
|||||||
config_.Copy(),
|
config_.Copy(),
|
||||||
&call_stats_,
|
&call_stats_,
|
||||||
time_controller_.GetClock(),
|
time_controller_.GetClock(),
|
||||||
std::make_unique<VCMTiming>(time_controller_.GetClock()),
|
std::make_unique<VCMTiming>(time_controller_.GetClock(),
|
||||||
|
fake_call_.trials()),
|
||||||
&nack_periodic_processor_,
|
&nack_periodic_processor_,
|
||||||
nullptr) {
|
nullptr) {
|
||||||
if (std::get<1>(GetParam())) {
|
if (std::get<1>(GetParam())) {
|
||||||
@ -748,7 +749,7 @@ class VideoReceiveStream2TestWithLazyDecoderCreation : public ::testing::Test {
|
|||||||
config_.decoders.push_back(h264_decoder);
|
config_.decoders.push_back(h264_decoder);
|
||||||
|
|
||||||
clock_ = Clock::GetRealTimeClock();
|
clock_ = Clock::GetRealTimeClock();
|
||||||
timing_ = new VCMTiming(clock_);
|
timing_ = new VCMTiming(clock_, fake_call_.trials());
|
||||||
|
|
||||||
video_receive_stream_ =
|
video_receive_stream_ =
|
||||||
std::make_unique<webrtc::internal::VideoReceiveStream2>(
|
std::make_unique<webrtc::internal::VideoReceiveStream2>(
|
||||||
|
|||||||
@ -23,8 +23,10 @@ VideoStreamDecoderImpl::VideoStreamDecoderImpl(
|
|||||||
VideoStreamDecoderInterface::Callbacks* callbacks,
|
VideoStreamDecoderInterface::Callbacks* callbacks,
|
||||||
VideoDecoderFactory* decoder_factory,
|
VideoDecoderFactory* decoder_factory,
|
||||||
TaskQueueFactory* task_queue_factory,
|
TaskQueueFactory* task_queue_factory,
|
||||||
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings)
|
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings,
|
||||||
: timing_(Clock::GetRealTimeClock()),
|
const WebRtcKeyValueConfig* field_trials)
|
||||||
|
: field_trials_(field_trials),
|
||||||
|
timing_(Clock::GetRealTimeClock(), *field_trials_),
|
||||||
decode_callbacks_(this),
|
decode_callbacks_(this),
|
||||||
next_frame_info_index_(0),
|
next_frame_info_index_(0),
|
||||||
callbacks_(callbacks),
|
callbacks_(callbacks),
|
||||||
@ -32,7 +34,10 @@ VideoStreamDecoderImpl::VideoStreamDecoderImpl(
|
|||||||
decoder_factory_(decoder_factory),
|
decoder_factory_(decoder_factory),
|
||||||
decoder_settings_(std::move(decoder_settings)),
|
decoder_settings_(std::move(decoder_settings)),
|
||||||
shut_down_(false),
|
shut_down_(false),
|
||||||
frame_buffer_(Clock::GetRealTimeClock(), &timing_, nullptr),
|
frame_buffer_(Clock::GetRealTimeClock(),
|
||||||
|
&timing_,
|
||||||
|
nullptr,
|
||||||
|
*field_trials_),
|
||||||
bookkeeping_queue_(task_queue_factory->CreateTaskQueue(
|
bookkeeping_queue_(task_queue_factory->CreateTaskQueue(
|
||||||
"video_stream_decoder_bookkeeping_queue",
|
"video_stream_decoder_bookkeeping_queue",
|
||||||
TaskQueueFactory::Priority::NORMAL)),
|
TaskQueueFactory::Priority::NORMAL)),
|
||||||
|
|||||||
@ -17,9 +17,12 @@
|
|||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/sequence_checker.h"
|
#include "api/sequence_checker.h"
|
||||||
|
#include "api/transport/field_trial_based_config.h"
|
||||||
#include "api/video/video_stream_decoder.h"
|
#include "api/video/video_stream_decoder.h"
|
||||||
|
#include "api/webrtc_key_value_config.h"
|
||||||
#include "modules/video_coding/frame_buffer2.h"
|
#include "modules/video_coding/frame_buffer2.h"
|
||||||
#include "modules/video_coding/timing.h"
|
#include "modules/video_coding/timing.h"
|
||||||
|
#include "rtc_base/memory/always_valid_pointer.h"
|
||||||
#include "rtc_base/platform_thread.h"
|
#include "rtc_base/platform_thread.h"
|
||||||
#include "rtc_base/synchronization/mutex.h"
|
#include "rtc_base/synchronization/mutex.h"
|
||||||
#include "rtc_base/task_queue.h"
|
#include "rtc_base/task_queue.h"
|
||||||
@ -33,7 +36,8 @@ class VideoStreamDecoderImpl : public VideoStreamDecoderInterface {
|
|||||||
VideoStreamDecoderInterface::Callbacks* callbacks,
|
VideoStreamDecoderInterface::Callbacks* callbacks,
|
||||||
VideoDecoderFactory* decoder_factory,
|
VideoDecoderFactory* decoder_factory,
|
||||||
TaskQueueFactory* task_queue_factory,
|
TaskQueueFactory* task_queue_factory,
|
||||||
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings);
|
std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings,
|
||||||
|
const WebRtcKeyValueConfig* field_trials);
|
||||||
|
|
||||||
~VideoStreamDecoderImpl() override;
|
~VideoStreamDecoderImpl() override;
|
||||||
|
|
||||||
@ -82,6 +86,8 @@ class VideoStreamDecoderImpl : public VideoStreamDecoderInterface {
|
|||||||
VideoStreamDecoderImpl::DecodeResult DecodeFrame(
|
VideoStreamDecoderImpl::DecodeResult DecodeFrame(
|
||||||
std::unique_ptr<EncodedFrame> frame) RTC_RUN_ON(decode_queue_);
|
std::unique_ptr<EncodedFrame> frame) RTC_RUN_ON(decode_queue_);
|
||||||
|
|
||||||
|
AlwaysValidPointer<const WebRtcKeyValueConfig, FieldTrialBasedConfig>
|
||||||
|
field_trials_;
|
||||||
VCMTiming timing_;
|
VCMTiming timing_;
|
||||||
DecodeCallbacks decode_callbacks_;
|
DecodeCallbacks decode_callbacks_;
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "api/video_codecs/video_decoder.h"
|
#include "api/video_codecs/video_decoder.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
#include "test/scoped_key_value_config.h"
|
||||||
#include "test/time_controller/simulated_time_controller.h"
|
#include "test/time_controller/simulated_time_controller.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -163,12 +164,14 @@ class VideoStreamDecoderImplTest : public ::testing::Test {
|
|||||||
&decoder_factory_,
|
&decoder_factory_,
|
||||||
time_controller_.GetTaskQueueFactory(),
|
time_controller_.GetTaskQueueFactory(),
|
||||||
{{1, std::make_pair(SdpVideoFormat("VP8"), 1)},
|
{{1, std::make_pair(SdpVideoFormat("VP8"), 1)},
|
||||||
{2, std::make_pair(SdpVideoFormat("AV1"), 1)}}) {
|
{2, std::make_pair(SdpVideoFormat("AV1"), 1)}},
|
||||||
|
&field_trials_) {
|
||||||
// Set the min playout delay to a value greater than zero to not activate
|
// Set the min playout delay to a value greater than zero to not activate
|
||||||
// the low-latency renderer.
|
// the low-latency renderer.
|
||||||
video_stream_decoder_.SetMinPlayoutDelay(TimeDelta::Millis(10));
|
video_stream_decoder_.SetMinPlayoutDelay(TimeDelta::Millis(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test::ScopedKeyValueConfig field_trials_;
|
||||||
NiceMock<MockVideoStreamDecoderCallbacks> callbacks_;
|
NiceMock<MockVideoStreamDecoderCallbacks> callbacks_;
|
||||||
FakeVideoDecoderFactory decoder_factory_;
|
FakeVideoDecoderFactory decoder_factory_;
|
||||||
GlobalSimulatedTimeController time_controller_;
|
GlobalSimulatedTimeController time_controller_;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user