xref: /aosp_15_r20/external/webrtc/pc/test/fake_periodic_video_source.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2018 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 #ifndef PC_TEST_FAKE_PERIODIC_VIDEO_SOURCE_H_
12 #define PC_TEST_FAKE_PERIODIC_VIDEO_SOURCE_H_
13 
14 #include <memory>
15 
16 #include "api/video/video_source_interface.h"
17 #include "media/base/fake_frame_source.h"
18 #include "media/base/video_broadcaster.h"
19 #include "rtc_base/synchronization/mutex.h"
20 #include "rtc_base/task_queue_for_test.h"
21 #include "rtc_base/task_utils/repeating_task.h"
22 
23 namespace webrtc {
24 
25 class FakePeriodicVideoSource final
26     : public rtc::VideoSourceInterface<VideoFrame> {
27  public:
28   static constexpr int kDefaultFrameIntervalMs = 33;
29   static constexpr int kDefaultWidth = 640;
30   static constexpr int kDefaultHeight = 480;
31 
32   struct Config {
33     int width = kDefaultWidth;
34     int height = kDefaultHeight;
35     int frame_interval_ms = kDefaultFrameIntervalMs;
36     VideoRotation rotation = kVideoRotation_0;
37     int64_t timestamp_offset_ms = 0;
38   };
39 
FakePeriodicVideoSource()40   FakePeriodicVideoSource() : FakePeriodicVideoSource(Config()) {}
FakePeriodicVideoSource(Config config)41   explicit FakePeriodicVideoSource(Config config)
42       : frame_source_(
43             config.width,
44             config.height,
45             config.frame_interval_ms * rtc::kNumMicrosecsPerMillisec,
46             config.timestamp_offset_ms * rtc::kNumMicrosecsPerMillisec),
47         task_queue_(std::make_unique<TaskQueueForTest>(
48             "FakePeriodicVideoTrackSource")) {
49     thread_checker_.Detach();
50     frame_source_.SetRotation(config.rotation);
51 
52     TimeDelta frame_interval = TimeDelta::Millis(config.frame_interval_ms);
53     RepeatingTaskHandle::Start(task_queue_->Get(), [this, frame_interval] {
54       if (broadcaster_.wants().rotation_applied) {
55         broadcaster_.OnFrame(frame_source_.GetFrameRotationApplied());
56       } else {
57         broadcaster_.OnFrame(frame_source_.GetFrame());
58       }
59       return frame_interval;
60     });
61   }
62 
wants()63   rtc::VideoSinkWants wants() const {
64     MutexLock lock(&mutex_);
65     return wants_;
66   }
67 
RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame> * sink)68   void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override {
69     RTC_DCHECK(thread_checker_.IsCurrent());
70     broadcaster_.RemoveSink(sink);
71   }
72 
AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame> * sink,const rtc::VideoSinkWants & wants)73   void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
74                        const rtc::VideoSinkWants& wants) override {
75     RTC_DCHECK(thread_checker_.IsCurrent());
76     {
77       MutexLock lock(&mutex_);
78       wants_ = wants;
79     }
80     broadcaster_.AddOrUpdateSink(sink, wants);
81   }
82 
Stop()83   void Stop() {
84     RTC_DCHECK(task_queue_);
85     task_queue_.reset();
86   }
87 
88  private:
89   SequenceChecker thread_checker_;
90 
91   rtc::VideoBroadcaster broadcaster_;
92   cricket::FakeFrameSource frame_source_;
93   mutable Mutex mutex_;
94   rtc::VideoSinkWants wants_ RTC_GUARDED_BY(&mutex_);
95 
96   std::unique_ptr<TaskQueueForTest> task_queue_;
97 };
98 
99 }  // namespace webrtc
100 
101 #endif  // PC_TEST_FAKE_PERIODIC_VIDEO_SOURCE_H_
102