Log when conflicting recv video playout delays are set
There are two cases that can be confusing for applications developers which may result in the playout delay not being set as intended. First, it is not well defined which min playout delay should be used when multiple are set. This changes adds a warning to alert application developers that they are setting multiple playout delays. Second, if the playout delay header extension is used, developers must be careful that the max playout delay is always larger than the min playout delay, otherwise the behaviour is undefined. This change logs an error when this case is detected. Bug: None Change-Id: I8477d48ef64636da080792362fa898e42f038bef Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/263202 Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Commit-Queue: Evan Shrubsole <eshr@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36977}
This commit is contained in:
parent
8101e7b79b
commit
eabaf8d7fe
@ -14,6 +14,7 @@
|
||||
|
||||
#include "api/units/time_delta.h"
|
||||
#include "rtc_base/experiments/field_trial_parser.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/time/timestamp_extrapolator.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
@ -61,6 +62,11 @@ void VCMTiming::set_render_delay(TimeDelta render_delay) {
|
||||
render_delay_ = render_delay;
|
||||
}
|
||||
|
||||
TimeDelta VCMTiming::min_playout_delay() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return min_playout_delay_;
|
||||
}
|
||||
|
||||
void VCMTiming::set_min_playout_delay(TimeDelta min_playout_delay) {
|
||||
MutexLock lock(&mutex_);
|
||||
min_playout_delay_ = min_playout_delay;
|
||||
@ -68,7 +74,18 @@ void VCMTiming::set_min_playout_delay(TimeDelta min_playout_delay) {
|
||||
|
||||
void VCMTiming::set_max_playout_delay(TimeDelta max_playout_delay) {
|
||||
MutexLock lock(&mutex_);
|
||||
max_playout_delay_ = max_playout_delay;
|
||||
if (max_playout_delay_ != max_playout_delay) {
|
||||
if (min_playout_delay_ > max_playout_delay) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "Playout delays set incorrectly: min playout delay ("
|
||||
<< min_playout_delay_ << ") > max playout delay ("
|
||||
<< max_playout_delay
|
||||
<< "). This is undefined behaviour. Application writers should "
|
||||
"ensure that the min delay is always less than or equals max "
|
||||
"delay.";
|
||||
}
|
||||
max_playout_delay_ = max_playout_delay;
|
||||
}
|
||||
}
|
||||
|
||||
void VCMTiming::SetJitterDelay(TimeDelta jitter_delay) {
|
||||
|
||||
@ -47,6 +47,7 @@ class VCMTiming {
|
||||
void SetJitterDelay(TimeDelta required_delay);
|
||||
|
||||
// Set/get the minimum playout delay from capture to render.
|
||||
TimeDelta min_playout_delay() const;
|
||||
void set_min_playout_delay(TimeDelta min_playout_delay);
|
||||
|
||||
// Set/get the maximum playout delay from capture to render in ms.
|
||||
|
||||
@ -181,6 +181,10 @@ bool IsKeyFrameAndUnspecifiedResolution(const EncodedFrame& frame) {
|
||||
// timestamps wraparound to affect FrameBuffer.
|
||||
constexpr TimeDelta kInactiveStreamThreshold = TimeDelta::Minutes(10);
|
||||
|
||||
std::string OptionalDelayToLogString(const absl::optional<TimeDelta> opt) {
|
||||
return opt.has_value() ? ToLogString(*opt) : "<unset>";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TimeDelta DetermineMaxWaitForFrame(
|
||||
@ -977,12 +981,26 @@ bool VideoReceiveStream2::IsReceivingKeyFrame(Timestamp now) const {
|
||||
|
||||
void VideoReceiveStream2::UpdatePlayoutDelays() const {
|
||||
// Running on worker_sequence_checker_.
|
||||
const std::initializer_list<absl::optional<TimeDelta>> min_delays = {
|
||||
frame_minimum_playout_delay_, base_minimum_playout_delay_,
|
||||
syncable_minimum_playout_delay_};
|
||||
// Since nullopt < anything, this will return the largest of the minumum
|
||||
// delays, or nullopt if all are nullopt.
|
||||
absl::optional<TimeDelta> minimum_delay =
|
||||
std::max({frame_minimum_playout_delay_, base_minimum_playout_delay_,
|
||||
syncable_minimum_playout_delay_});
|
||||
absl::optional<TimeDelta> minimum_delay = std::max(min_delays);
|
||||
if (minimum_delay) {
|
||||
auto num_playout_delays_set =
|
||||
absl::c_count_if(min_delays, [](auto opt) { return opt.has_value(); });
|
||||
if (num_playout_delays_set > 1 &&
|
||||
timing_->min_playout_delay() != minimum_delay) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "Multiple playout delays set. Actual delay value set to "
|
||||
<< *minimum_delay << " frame min delay="
|
||||
<< OptionalDelayToLogString(frame_maximum_playout_delay_)
|
||||
<< " base min delay="
|
||||
<< OptionalDelayToLogString(base_minimum_playout_delay_)
|
||||
<< " sync min delay="
|
||||
<< OptionalDelayToLogString(syncable_minimum_playout_delay_);
|
||||
}
|
||||
timing_->set_min_playout_delay(*minimum_delay);
|
||||
if (frame_minimum_playout_delay_ == TimeDelta::Zero() &&
|
||||
frame_maximum_playout_delay_ > TimeDelta::Zero()) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user