blob: 955cd43ea2f268a08cb4a9280e6da693ab4f6c8c [file] [log] [blame]
Evan Shrubsole476f18d2022-08-15 15:21:16 +00001/*
2 * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "video/video_stream_buffer_controller.h"
12
13#include <algorithm>
14#include <memory>
15#include <utility>
16
17#include "absl/base/attributes.h"
18#include "absl/functional/bind_front.h"
19#include "api/sequence_checker.h"
20#include "api/task_queue/task_queue_base.h"
21#include "api/units/data_size.h"
22#include "api/video/encoded_frame.h"
23#include "api/video/frame_buffer.h"
24#include "api/video/video_content_type.h"
25#include "modules/video_coding/frame_helpers.h"
26#include "modules/video_coding/timing/inter_frame_delay.h"
27#include "modules/video_coding/timing/jitter_estimator.h"
28#include "rtc_base/checks.h"
29#include "rtc_base/logging.h"
30#include "rtc_base/thread_annotations.h"
Evan Shrubsolea006ba12022-09-05 10:09:08 +000031#include "video/frame_decode_scheduler.h"
Evan Shrubsole476f18d2022-08-15 15:21:16 +000032#include "video/frame_decode_timing.h"
33#include "video/task_queue_frame_decode_scheduler.h"
34#include "video/video_receive_stream_timeout_tracker.h"
35
36namespace webrtc {
37
38namespace {
39
40// Max number of frames the buffer will hold.
41static constexpr size_t kMaxFramesBuffered = 800;
42// Max number of decoded frame info that will be saved.
43static constexpr int kMaxFramesHistory = 1 << 13;
44
45// Default value for the maximum decode queue size that is used when the
46// low-latency renderer is used.
47static constexpr size_t kZeroPlayoutDelayDefaultMaxDecodeQueueSize = 8;
48
49struct FrameMetadata {
50 explicit FrameMetadata(const EncodedFrame& frame)
51 : is_last_spatial_layer(frame.is_last_spatial_layer),
52 is_keyframe(frame.is_keyframe()),
53 size(frame.size()),
54 contentType(frame.contentType()),
55 delayed_by_retransmission(frame.delayed_by_retransmission()),
56 rtp_timestamp(frame.Timestamp()),
57 receive_time(frame.ReceivedTimestamp()) {}
58
59 const bool is_last_spatial_layer;
60 const bool is_keyframe;
61 const size_t size;
62 const VideoContentType contentType;
63 const bool delayed_by_retransmission;
64 const uint32_t rtp_timestamp;
65 const absl::optional<Timestamp> receive_time;
66};
67
68Timestamp ReceiveTime(const EncodedFrame& frame) {
69 absl::optional<Timestamp> ts = frame.ReceivedTimestamp();
70 RTC_DCHECK(ts.has_value()) << "Received frame must have a timestamp set!";
71 return *ts;
72}
73
Evan Shrubsole476f18d2022-08-15 15:21:16 +000074} // namespace
75
Evan Shrubsole476f18d2022-08-15 15:21:16 +000076VideoStreamBufferController::VideoStreamBufferController(
77 Clock* clock,
78 TaskQueueBase* worker_queue,
79 VCMTiming* timing,
80 VCMReceiveStatisticsCallback* stats_proxy,
Evan Shrubsole476f18d2022-08-15 15:21:16 +000081 FrameSchedulingReceiver* receiver,
82 TimeDelta max_wait_for_keyframe,
83 TimeDelta max_wait_for_frame,
84 std::unique_ptr<FrameDecodeScheduler> frame_decode_scheduler,
85 const FieldTrialsView& field_trials)
86 : field_trials_(field_trials),
87 clock_(clock),
Evan Shrubsole476f18d2022-08-15 15:21:16 +000088 stats_proxy_(stats_proxy),
89 receiver_(receiver),
90 timing_(timing),
91 frame_decode_scheduler_(std::move(frame_decode_scheduler)),
92 jitter_estimator_(clock_, field_trials),
93 buffer_(std::make_unique<FrameBuffer>(kMaxFramesBuffered,
94 kMaxFramesHistory,
95 field_trials)),
96 decode_timing_(clock_, timing_),
97 timeout_tracker_(
98 clock_,
Evan Shrubsole214cab52022-08-16 09:48:23 +000099 worker_queue,
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000100 VideoReceiveStreamTimeoutTracker::Timeouts{
101 .max_wait_for_keyframe = max_wait_for_keyframe,
102 .max_wait_for_frame = max_wait_for_frame},
103 absl::bind_front(&VideoStreamBufferController::OnTimeout, this)),
104 zero_playout_delay_max_decode_queue_size_(
105 "max_decode_queue_size",
106 kZeroPlayoutDelayDefaultMaxDecodeQueueSize) {
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000107 RTC_DCHECK(stats_proxy_);
108 RTC_DCHECK(receiver_);
109 RTC_DCHECK(timing_);
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000110 RTC_DCHECK(clock_);
111 RTC_DCHECK(frame_decode_scheduler_);
112 RTC_LOG(LS_WARNING) << "Using FrameBuffer3";
113
114 ParseFieldTrial({&zero_playout_delay_max_decode_queue_size_},
115 field_trials.Lookup("WebRTC-ZeroPlayoutDelay"));
116}
117
Evan Shrubsole214cab52022-08-16 09:48:23 +0000118void VideoStreamBufferController::Stop() {
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000119 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
120 frame_decode_scheduler_->Stop();
121 timeout_tracker_.Stop();
122 decoder_ready_for_new_frame_ = false;
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000123}
124
125void VideoStreamBufferController::SetProtectionMode(
126 VCMVideoProtection protection_mode) {
127 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
128 protection_mode_ = protection_mode;
129}
130
131void VideoStreamBufferController::Clear() {
132 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
133 stats_proxy_->OnDroppedFrames(buffer_->CurrentSize());
134 buffer_ = std::make_unique<FrameBuffer>(kMaxFramesBuffered, kMaxFramesHistory,
135 field_trials_);
136 frame_decode_scheduler_->CancelOutstanding();
137}
138
139absl::optional<int64_t> VideoStreamBufferController::InsertFrame(
140 std::unique_ptr<EncodedFrame> frame) {
141 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
142 FrameMetadata metadata(*frame);
143 int complete_units = buffer_->GetTotalNumberOfContinuousTemporalUnits();
144 if (buffer_->InsertFrame(std::move(frame))) {
145 RTC_DCHECK(metadata.receive_time) << "Frame receive time must be set!";
philipel7446b602022-10-06 15:49:17 +0200146 if (!metadata.delayed_by_retransmission && metadata.receive_time &&
147 (field_trials_.IsDisabled("WebRTC-IncomingTimestampOnMarkerBitOnly") ||
148 metadata.is_last_spatial_layer)) {
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000149 timing_->IncomingTimestamp(metadata.rtp_timestamp,
150 *metadata.receive_time);
philipel7446b602022-10-06 15:49:17 +0200151 }
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000152 if (complete_units < buffer_->GetTotalNumberOfContinuousTemporalUnits()) {
153 stats_proxy_->OnCompleteFrame(metadata.is_keyframe, metadata.size,
154 metadata.contentType);
155 MaybeScheduleFrameForRelease();
156 }
157 }
158
159 return buffer_->LastContinuousFrameId();
160}
161
162void VideoStreamBufferController::UpdateRtt(int64_t max_rtt_ms) {
163 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
164 jitter_estimator_.UpdateRtt(TimeDelta::Millis(max_rtt_ms));
165}
166
167void VideoStreamBufferController::SetMaxWaits(TimeDelta max_wait_for_keyframe,
168 TimeDelta max_wait_for_frame) {
169 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
170 timeout_tracker_.SetTimeouts({.max_wait_for_keyframe = max_wait_for_keyframe,
171 .max_wait_for_frame = max_wait_for_frame});
172}
173
174void VideoStreamBufferController::StartNextDecode(bool keyframe_required) {
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000175 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
176 if (!timeout_tracker_.Running())
177 timeout_tracker_.Start(keyframe_required);
178 keyframe_required_ = keyframe_required;
179 if (keyframe_required_) {
180 timeout_tracker_.SetWaitingForKeyframe();
181 }
182 decoder_ready_for_new_frame_ = true;
183 MaybeScheduleFrameForRelease();
184}
185
186int VideoStreamBufferController::Size() {
187 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
188 return buffer_->CurrentSize();
189}
190
191void VideoStreamBufferController::OnFrameReady(
192 absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4> frames,
193 Timestamp render_time) {
194 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
195 RTC_DCHECK(!frames.empty());
196
197 timeout_tracker_.OnEncodedFrameReleased();
198
199 Timestamp now = clock_->CurrentTime();
200 bool superframe_delayed_by_retransmission = false;
201 DataSize superframe_size = DataSize::Zero();
202 const EncodedFrame& first_frame = *frames.front();
203 Timestamp receive_time = ReceiveTime(first_frame);
204
205 if (first_frame.is_keyframe())
206 keyframe_required_ = false;
207
208 // Gracefully handle bad RTP timestamps and render time issues.
209 if (FrameHasBadRenderTiming(render_time, now, timing_->TargetVideoDelay())) {
210 jitter_estimator_.Reset();
211 timing_->Reset();
212 render_time = timing_->RenderTime(first_frame.Timestamp(), now);
213 }
214
215 for (std::unique_ptr<EncodedFrame>& frame : frames) {
216 frame->SetRenderTime(render_time.ms());
217
218 superframe_delayed_by_retransmission |= frame->delayed_by_retransmission();
219 receive_time = std::max(receive_time, ReceiveTime(*frame));
220 superframe_size += DataSize::Bytes(frame->size());
221 }
222
223 if (!superframe_delayed_by_retransmission) {
224 auto frame_delay = inter_frame_delay_.CalculateDelay(
225 first_frame.Timestamp(), receive_time);
226 if (frame_delay) {
227 jitter_estimator_.UpdateEstimate(*frame_delay, superframe_size);
228 }
229
230 float rtt_mult = protection_mode_ == kProtectionNackFEC ? 0.0 : 1.0;
231 absl::optional<TimeDelta> rtt_mult_add_cap_ms = absl::nullopt;
232 if (rtt_mult_settings_.has_value()) {
233 rtt_mult = rtt_mult_settings_->rtt_mult_setting;
234 rtt_mult_add_cap_ms =
235 TimeDelta::Millis(rtt_mult_settings_->rtt_mult_add_cap_ms);
236 }
237 timing_->SetJitterDelay(
238 jitter_estimator_.GetJitterEstimate(rtt_mult, rtt_mult_add_cap_ms));
239 timing_->UpdateCurrentDelay(render_time, now);
240 } else if (RttMultExperiment::RttMultEnabled()) {
241 jitter_estimator_.FrameNacked();
242 }
243
244 // Update stats.
245 UpdateDroppedFrames();
246 UpdateJitterDelay();
247 UpdateTimingFrameInfo();
248
249 std::unique_ptr<EncodedFrame> frame =
250 CombineAndDeleteFrames(std::move(frames));
251
252 timing_->SetLastDecodeScheduledTimestamp(now);
253
254 decoder_ready_for_new_frame_ = false;
Evan Shrubsole214cab52022-08-16 09:48:23 +0000255 receiver_->OnEncodedFrame(std::move(frame));
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000256}
257
258void VideoStreamBufferController::OnTimeout(TimeDelta delay) {
259 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
Evan Shrubsole214cab52022-08-16 09:48:23 +0000260
261 // Stop sending timeouts until receiver starts waiting for a new frame.
262 timeout_tracker_.Stop();
263
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000264 // If the stream is paused then ignore the timeout.
265 if (!decoder_ready_for_new_frame_) {
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000266 return;
267 }
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000268 decoder_ready_for_new_frame_ = false;
Evan Shrubsole214cab52022-08-16 09:48:23 +0000269 receiver_->OnDecodableFrameTimeout(delay);
Evan Shrubsole476f18d2022-08-15 15:21:16 +0000270}
271
272void VideoStreamBufferController::FrameReadyForDecode(uint32_t rtp_timestamp,
273 Timestamp render_time) {
274 RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
275 auto frames = buffer_->ExtractNextDecodableTemporalUnit();
276 RTC_DCHECK(frames[0]->Timestamp() == rtp_timestamp)
277 << "Frame buffer's next decodable frame was not the one sent for "
278 "extraction rtp="
279 << rtp_timestamp << " extracted rtp=" << frames[0]->Timestamp();
280 OnFrameReady(std::move(frames), render_time);
281}
282
283void VideoStreamBufferController::UpdateDroppedFrames()
284 RTC_RUN_ON(&worker_sequence_checker_) {
285 const int dropped_frames = buffer_->GetTotalNumberOfDroppedFrames() -
286 frames_dropped_before_last_new_frame_;
287 if (dropped_frames > 0)
288 stats_proxy_->OnDroppedFrames(dropped_frames);
289 frames_dropped_before_last_new_frame_ =
290 buffer_->GetTotalNumberOfDroppedFrames();
291}
292
293void VideoStreamBufferController::UpdateJitterDelay() {
294 auto timings = timing_->GetTimings();
295 if (timings.num_decoded_frames) {
296 stats_proxy_->OnFrameBufferTimingsUpdated(
297 timings.max_decode_duration.ms(), timings.current_delay.ms(),
298 timings.target_delay.ms(), timings.jitter_buffer_delay.ms(),
299 timings.min_playout_delay.ms(), timings.render_delay.ms());
300 }
301}
302
303void VideoStreamBufferController::UpdateTimingFrameInfo() {
304 absl::optional<TimingFrameInfo> info = timing_->GetTimingFrameInfo();
305 if (info)
306 stats_proxy_->OnTimingFrameInfoUpdated(*info);
307}
308
309bool VideoStreamBufferController::IsTooManyFramesQueued() const
310 RTC_RUN_ON(&worker_sequence_checker_) {
311 return buffer_->CurrentSize() > zero_playout_delay_max_decode_queue_size_;
312}
313
314void VideoStreamBufferController::ForceKeyFrameReleaseImmediately()
315 RTC_RUN_ON(&worker_sequence_checker_) {
316 RTC_DCHECK(keyframe_required_);
317 // Iterate through the frame buffer until there is a complete keyframe and
318 // release this right away.
319 while (buffer_->DecodableTemporalUnitsInfo()) {
320 auto next_frame = buffer_->ExtractNextDecodableTemporalUnit();
321 if (next_frame.empty()) {
322 RTC_DCHECK_NOTREACHED()
323 << "Frame buffer should always return at least 1 frame.";
324 continue;
325 }
326 // Found keyframe - decode right away.
327 if (next_frame.front()->is_keyframe()) {
328 auto render_time = timing_->RenderTime(next_frame.front()->Timestamp(),
329 clock_->CurrentTime());
330 OnFrameReady(std::move(next_frame), render_time);
331 return;
332 }
333 }
334}
335
336void VideoStreamBufferController::MaybeScheduleFrameForRelease()
337 RTC_RUN_ON(&worker_sequence_checker_) {
338 auto decodable_tu_info = buffer_->DecodableTemporalUnitsInfo();
339 if (!decoder_ready_for_new_frame_ || !decodable_tu_info) {
340 return;
341 }
342
343 if (keyframe_required_) {
344 return ForceKeyFrameReleaseImmediately();
345 }
346
347 // If already scheduled then abort.
348 if (frame_decode_scheduler_->ScheduledRtpTimestamp() ==
349 decodable_tu_info->next_rtp_timestamp) {
350 return;
351 }
352
353 TimeDelta max_wait = timeout_tracker_.TimeUntilTimeout();
354 // Ensures the frame is scheduled for decode before the stream times out.
355 // This is otherwise a race condition.
356 max_wait = std::max(max_wait - TimeDelta::Millis(1), TimeDelta::Zero());
357 absl::optional<FrameDecodeTiming::FrameSchedule> schedule;
358 while (decodable_tu_info) {
359 schedule = decode_timing_.OnFrameBufferUpdated(
360 decodable_tu_info->next_rtp_timestamp,
361 decodable_tu_info->last_rtp_timestamp, max_wait,
362 IsTooManyFramesQueued());
363 if (schedule) {
364 // Don't schedule if already waiting for the same frame.
365 if (frame_decode_scheduler_->ScheduledRtpTimestamp() !=
366 decodable_tu_info->next_rtp_timestamp) {
367 frame_decode_scheduler_->CancelOutstanding();
368 frame_decode_scheduler_->ScheduleFrame(
369 decodable_tu_info->next_rtp_timestamp, *schedule,
370 absl::bind_front(&VideoStreamBufferController::FrameReadyForDecode,
371 this));
372 }
373 return;
374 }
375 // If no schedule for current rtp, drop and try again.
376 buffer_->DropNextDecodableTemporalUnit();
377 decodable_tu_info = buffer_->DecodableTemporalUnitsInfo();
378 }
379}
380
381} // namespace webrtc