summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/video/decode_synchronizer.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/libwebrtc/video/decode_synchronizer.h
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/video/decode_synchronizer.h')
-rw-r--r--third_party/libwebrtc/video/decode_synchronizer.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/decode_synchronizer.h b/third_party/libwebrtc/video/decode_synchronizer.h
new file mode 100644
index 0000000000..c6f8efdb29
--- /dev/null
+++ b/third_party/libwebrtc/video/decode_synchronizer.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VIDEO_DECODE_SYNCHRONIZER_H_
+#define VIDEO_DECODE_SYNCHRONIZER_H_
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <set>
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "api/metronome/metronome.h"
+#include "api/sequence_checker.h"
+#include "api/task_queue/task_queue_base.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/thread_annotations.h"
+#include "video/frame_decode_scheduler.h"
+#include "video/frame_decode_timing.h"
+
+namespace webrtc {
+
+// DecodeSynchronizer synchronizes the frame scheduling by coalescing decoding
+// on the metronome.
+//
+// A video receive stream can use the DecodeSynchronizer by receiving a
+// FrameDecodeScheduler instance with `CreateSynchronizedFrameScheduler()`.
+// This instance implements FrameDecodeScheduler and can be used as a normal
+// scheduler. This instance is owned by the receive stream, and is borrowed by
+// the DecodeSynchronizer. The DecodeSynchronizer will stop borrowing the
+// instance when `FrameDecodeScheduler::Stop()` is called, after which the
+// scheduler may be destroyed by the receive stream.
+//
+// When a frame is scheduled for decode by a receive stream using the
+// DecodeSynchronizer, it will instead be executed on the metronome during the
+// tick interval where `max_decode_time` occurs. For example, if a frame is
+// scheduled for decode in 50ms and the tick interval is 20ms, then the frame
+// will be released for decoding in 2 ticks. See below for illustration,
+//
+// In the case where the decode time is in the past, or must occur before the
+// next metronome tick then the frame will be released right away, allowing a
+// delayed stream to catch up quickly.
+//
+// DecodeSynchronizer is single threaded - all method calls must run on the
+// `worker_queue_`.
+class DecodeSynchronizer {
+ public:
+ DecodeSynchronizer(Clock* clock,
+ Metronome* metronome,
+ TaskQueueBase* worker_queue);
+ ~DecodeSynchronizer();
+ DecodeSynchronizer(const DecodeSynchronizer&) = delete;
+ DecodeSynchronizer& operator=(const DecodeSynchronizer&) = delete;
+
+ std::unique_ptr<FrameDecodeScheduler> CreateSynchronizedFrameScheduler();
+
+ private:
+ class ScheduledFrame {
+ public:
+ ScheduledFrame(uint32_t rtp_timestamp,
+ FrameDecodeTiming::FrameSchedule schedule,
+ FrameDecodeScheduler::FrameReleaseCallback callback);
+
+ // Disallow copy since `callback` should only be moved.
+ ScheduledFrame(const ScheduledFrame&) = delete;
+ ScheduledFrame& operator=(const ScheduledFrame&) = delete;
+ ScheduledFrame(ScheduledFrame&&) = default;
+ ScheduledFrame& operator=(ScheduledFrame&&) = default;
+
+ // Executes `callback_`.
+ void RunFrameReleaseCallback() &&;
+
+ uint32_t rtp_timestamp() const { return rtp_timestamp_; }
+ Timestamp LatestDecodeTime() const;
+
+ private:
+ uint32_t rtp_timestamp_;
+ FrameDecodeTiming::FrameSchedule schedule_;
+ FrameDecodeScheduler::FrameReleaseCallback callback_;
+ };
+
+ class SynchronizedFrameDecodeScheduler : public FrameDecodeScheduler {
+ public:
+ explicit SynchronizedFrameDecodeScheduler(DecodeSynchronizer* sync);
+ ~SynchronizedFrameDecodeScheduler() override;
+
+ // Releases the outstanding frame for decoding. This invalidates
+ // `next_frame_`. There must be a frame scheduled.
+ ScheduledFrame ReleaseNextFrame();
+
+ // Returns `next_frame_.schedule.max_decode_time`. There must be a frame
+ // scheduled when this is called.
+ Timestamp LatestDecodeTime();
+
+ // FrameDecodeScheduler implementation.
+ absl::optional<uint32_t> ScheduledRtpTimestamp() override;
+ void ScheduleFrame(uint32_t rtp,
+ FrameDecodeTiming::FrameSchedule schedule,
+ FrameReleaseCallback cb) override;
+ void CancelOutstanding() override;
+ void Stop() override;
+
+ private:
+ DecodeSynchronizer* sync_;
+ absl::optional<ScheduledFrame> next_frame_;
+ bool stopped_ = false;
+ };
+
+ void OnFrameScheduled(SynchronizedFrameDecodeScheduler* scheduler);
+ void RemoveFrameScheduler(SynchronizedFrameDecodeScheduler* scheduler);
+
+ void ScheduleNextTick();
+ void OnTick();
+
+ Clock* const clock_;
+ TaskQueueBase* const worker_queue_;
+ Metronome* const metronome_;
+
+ Timestamp expected_next_tick_ = Timestamp::PlusInfinity();
+ std::set<SynchronizedFrameDecodeScheduler*> schedulers_
+ RTC_GUARDED_BY(worker_queue_);
+ ScopedTaskSafetyDetached safety_;
+};
+
+} // namespace webrtc
+
+#endif // VIDEO_DECODE_SYNCHRONIZER_H_