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