Skip to content

Commit caf19bc

Browse files
Johannes KronWebRTC LUCI CQ
authored andcommitted
Merge M93: Calculate pacing delay based on decode start time
Schedule the frames to be decoded based on the pacing delay from the last decode scheduled time. In the current implementation, multiple threads and different functions in same thread can call MaxWaitingTime(), thereby increasing the wait time each time the function is called. Instead of returning the wait time for a future frame based on the number of times the function is called, return the wait time only for the next frame to be decoded. Threads can call the function repeatedly to check the waiting time for next frame and wake up and then go back to waiting if an encoded frame is not available. (cherry picked from commit 82c2248) Change-Id: I00886c1619599f94bde5d5eb87405572e435bd73 Bug: chromium:1237402 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/226502 Reviewed-by: Johannes Kron <[email protected]> Reviewed-by: Philip Eliasson <[email protected]> Commit-Queue: Johannes Kron <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#34660} Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/228532 Reviewed-by: Ilya Nikolaevskiy <[email protected]> Cr-Commit-Position: refs/branch-heads/4577@{#3} Cr-Branched-From: 5196931-refs/heads/master@{#34463}
1 parent bc94cec commit caf19bc

File tree

5 files changed

+33
-15
lines changed

5 files changed

+33
-15
lines changed

modules/video_coding/frame_buffer2.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ void FrameBuffer::StartWaitForNextFrameOnQueue() {
110110
if (!frames_to_decode_.empty()) {
111111
// We have frames, deliver!
112112
frame = absl::WrapUnique(GetNextFrame());
113+
timing_->SetLastDecodeScheduledTimestamp(
114+
clock_->TimeInMilliseconds());
113115
} else if (clock_->TimeInMilliseconds() < latest_return_time_ms_) {
114116
// If there's no frames to decode and there is still time left, it
115117
// means that the frame buffer was cleared between creation and

modules/video_coding/frame_buffer2_unittest.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ class VCMTimingFake : public VCMTiming {
5555
return last_ms_;
5656
}
5757

58-
int64_t MaxWaitingTime(int64_t render_time_ms, int64_t now_ms) override {
58+
int64_t MaxWaitingTime(int64_t render_time_ms,
59+
int64_t now_ms) const override {
5960
return render_time_ms - now_ms - kDecodeTime;
6061
}
6162

modules/video_coding/timing.cc

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ VCMTiming::VCMTiming(Clock* clock)
3636
num_decoded_frames_(0),
3737
low_latency_renderer_enabled_("enabled", true),
3838
zero_playout_delay_min_pacing_("min_pacing", TimeDelta::Millis(0)),
39-
earliest_next_decode_start_time_(0) {
39+
last_decode_scheduled_ts_(0) {
4040
ParseFieldTrial({&low_latency_renderer_enabled_},
4141
field_trial::FindFullName("WebRTC-LowLatencyRenderer"));
4242
ParseFieldTrial({&zero_playout_delay_min_pacing_},
@@ -172,6 +172,12 @@ int64_t VCMTiming::RenderTimeMs(uint32_t frame_timestamp,
172172
return RenderTimeMsInternal(frame_timestamp, now_ms);
173173
}
174174

175+
void VCMTiming::SetLastDecodeScheduledTimestamp(
176+
int64_t last_decode_scheduled_ts) {
177+
MutexLock lock(&mutex_);
178+
last_decode_scheduled_ts_ = last_decode_scheduled_ts;
179+
}
180+
175181
int64_t VCMTiming::RenderTimeMsInternal(uint32_t frame_timestamp,
176182
int64_t now_ms) const {
177183
constexpr int kLowLatencyRendererMaxPlayoutDelayMs = 500;
@@ -203,19 +209,20 @@ int VCMTiming::RequiredDecodeTimeMs() const {
203209
return decode_time_ms;
204210
}
205211

206-
int64_t VCMTiming::MaxWaitingTime(int64_t render_time_ms, int64_t now_ms) {
212+
int64_t VCMTiming::MaxWaitingTime(int64_t render_time_ms,
213+
int64_t now_ms) const {
207214
MutexLock lock(&mutex_);
208215

209216
if (render_time_ms == 0 && zero_playout_delay_min_pacing_->us() > 0) {
210217
// |render_time_ms| == 0 indicates that the frame should be decoded and
211218
// rendered as soon as possible. However, the decoder can be choked if too
212219
// many frames are sent at ones. Therefore, limit the interframe delay to
213220
// |zero_playout_delay_min_pacing_|.
214-
int64_t max_wait_time_ms = now_ms >= earliest_next_decode_start_time_
221+
int64_t earliest_next_decode_start_time =
222+
last_decode_scheduled_ts_ + zero_playout_delay_min_pacing_->ms();
223+
int64_t max_wait_time_ms = now_ms >= earliest_next_decode_start_time
215224
? 0
216-
: earliest_next_decode_start_time_ - now_ms;
217-
earliest_next_decode_start_time_ =
218-
now_ms + max_wait_time_ms + zero_playout_delay_min_pacing_->ms();
225+
: earliest_next_decode_start_time - now_ms;
219226
return max_wait_time_ms;
220227
}
221228
return render_time_ms - now_ms - RequiredDecodeTimeMs() - render_delay_ms_;

modules/video_coding/timing.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class VCMTiming {
8383

8484
// Returns the maximum time in ms that we can wait for a frame to become
8585
// complete before we must pass it to the decoder.
86-
virtual int64_t MaxWaitingTime(int64_t render_time_ms, int64_t now_ms);
86+
virtual int64_t MaxWaitingTime(int64_t render_time_ms, int64_t now_ms) const;
8787

8888
// Returns the current target delay which is required delay + decode time +
8989
// render delay.
@@ -105,6 +105,9 @@ class VCMTiming {
105105
absl::optional<int> max_composition_delay_in_frames);
106106
absl::optional<int> MaxCompositionDelayInFrames() const;
107107

108+
// Updates the last time a frame was scheduled for decoding.
109+
void SetLastDecodeScheduledTimestamp(int64_t last_decode_scheduled_ts);
110+
108111
enum { kDefaultRenderDelayMs = 10 };
109112
enum { kDelayMaxChangeMsPerS = 100 };
110113

@@ -145,10 +148,10 @@ class VCMTiming {
145148
// used when min playout delay=0 and max playout delay>=0.
146149
FieldTrialParameter<TimeDelta> zero_playout_delay_min_pacing_
147150
RTC_GUARDED_BY(mutex_);
148-
// An estimate of when the last frame is scheduled to be sent to the decoder.
151+
// Timestamp at which the last frame was scheduled to be sent to the decoder.
149152
// Used only when the RTP header extension playout delay is set to min=0 ms
150153
// which is indicated by a render time set to 0.
151-
int64_t earliest_next_decode_start_time_ RTC_GUARDED_BY(mutex_);
154+
int64_t last_decode_scheduled_ts_ RTC_GUARDED_BY(mutex_);
152155
};
153156
} // namespace webrtc
154157

modules/video_coding/timing_unittest.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,21 +169,26 @@ TEST(ReceiverTimingTest, MaxWaitingTimeZeroDelayPacingExperiment) {
169169
clock.AdvanceTimeMilliseconds(kTimeDeltaMs);
170170
int64_t now_ms = clock.TimeInMilliseconds();
171171
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), 0);
172+
timing.SetLastDecodeScheduledTimestamp(now_ms);
172173
}
173174
// Another frame submitted at the same time is paced according to the field
174175
// trial setting.
175176
int64_t now_ms = clock.TimeInMilliseconds();
176177
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), kMinPacingMs);
177-
// If there's a burst of frames, the min pacing interval is summed.
178-
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), 2 * kMinPacingMs);
179-
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), 3 * kMinPacingMs);
180-
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), 4 * kMinPacingMs);
178+
// If there's a burst of frames, the wait time is calculated based on next
179+
// decode time.
180+
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), kMinPacingMs);
181+
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), kMinPacingMs);
181182
// Allow a few ms to pass, this should be subtracted from the MaxWaitingTime.
182183
constexpr int64_t kTwoMs = 2;
183184
clock.AdvanceTimeMilliseconds(kTwoMs);
184185
now_ms = clock.TimeInMilliseconds();
185186
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms),
186-
5 * kMinPacingMs - kTwoMs);
187+
kMinPacingMs - kTwoMs);
188+
// A frame is decoded at the current time, the wait time should be restored to
189+
// pacing delay.
190+
timing.SetLastDecodeScheduledTimestamp(now_ms);
191+
EXPECT_EQ(timing.MaxWaitingTime(kZeroRenderTimeMs, now_ms), kMinPacingMs);
187192
}
188193

189194
TEST(ReceiverTimingTest, DefaultMaxWaitingTimeUnaffectedByPacingExperiment) {

0 commit comments

Comments
 (0)