• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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