1 /*
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/task_queue_frame_decode_scheduler.h"
12
13 #include <algorithm>
14 #include <utility>
15
16 #include "api/sequence_checker.h"
17 #include "api/task_queue/task_queue_base.h"
18 #include "rtc_base/checks.h"
19
20 namespace webrtc {
21
TaskQueueFrameDecodeScheduler(Clock * clock,TaskQueueBase * const bookkeeping_queue)22 TaskQueueFrameDecodeScheduler::TaskQueueFrameDecodeScheduler(
23 Clock* clock,
24 TaskQueueBase* const bookkeeping_queue)
25 : clock_(clock), bookkeeping_queue_(bookkeeping_queue) {
26 RTC_DCHECK(clock_);
27 RTC_DCHECK(bookkeeping_queue_);
28 }
29
~TaskQueueFrameDecodeScheduler()30 TaskQueueFrameDecodeScheduler::~TaskQueueFrameDecodeScheduler() {
31 RTC_DCHECK(stopped_);
32 RTC_DCHECK(!scheduled_rtp_) << "Outstanding scheduled rtp=" << *scheduled_rtp_
33 << ". Call CancelOutstanding before destruction.";
34 }
35
ScheduleFrame(uint32_t rtp,FrameDecodeTiming::FrameSchedule schedule,FrameReleaseCallback cb)36 void TaskQueueFrameDecodeScheduler::ScheduleFrame(
37 uint32_t rtp,
38 FrameDecodeTiming::FrameSchedule schedule,
39 FrameReleaseCallback cb) {
40 RTC_DCHECK(!stopped_) << "Can not schedule frames after stopped.";
41 RTC_DCHECK(!scheduled_rtp_.has_value())
42 << "Can not schedule two frames for release at the same time.";
43 RTC_DCHECK(cb);
44 scheduled_rtp_ = rtp;
45
46 TimeDelta wait = std::max(
47 TimeDelta::Zero(), schedule.latest_decode_time - clock_->CurrentTime());
48 bookkeeping_queue_->PostDelayedHighPrecisionTask(
49 SafeTask(task_safety_.flag(),
50 [this, rtp, schedule, cb = std::move(cb)]() mutable {
51 RTC_DCHECK_RUN_ON(bookkeeping_queue_);
52 // If the next frame rtp has changed since this task was
53 // this scheduled release should be skipped.
54 if (scheduled_rtp_ != rtp)
55 return;
56 scheduled_rtp_ = absl::nullopt;
57 std::move(cb)(rtp, schedule.render_time);
58 }),
59 wait);
60 }
61
CancelOutstanding()62 void TaskQueueFrameDecodeScheduler::CancelOutstanding() {
63 scheduled_rtp_ = absl::nullopt;
64 }
65
66 absl::optional<uint32_t>
ScheduledRtpTimestamp()67 TaskQueueFrameDecodeScheduler::ScheduledRtpTimestamp() {
68 return scheduled_rtp_;
69 }
70
Stop()71 void TaskQueueFrameDecodeScheduler::Stop() {
72 CancelOutstanding();
73 stopped_ = true;
74 }
75
76 } // namespace webrtc
77