VideoFrameScheduler.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "pch.h"
  2. #include <functional>
  3. #include <rtc_base/event.h>
  4. #include <rtc_base/task_utils/to_queued_task.h>
  5. #include "VideoFrameScheduler.h"
  6. namespace unity
  7. {
  8. namespace webrtc
  9. {
  10. constexpr TimeDelta kTimeout = TimeDelta::Millis(1000);
  11. VideoFrameScheduler::VideoFrameScheduler(TaskQueueBase* queue, Clock* clock)
  12. : maxFramerate_(30)
  13. , queue_(queue)
  14. , lastCaptureStartedTime_(Timestamp::Zero())
  15. , clock_(clock)
  16. {
  17. }
  18. VideoFrameScheduler::~VideoFrameScheduler()
  19. {
  20. rtc::Event done;
  21. // Waiting for stopping task.
  22. queue_->PostTask(ToQueuedTask(
  23. [task = std::move(task_), &done]() mutable
  24. {
  25. task.Stop();
  26. done.Set();
  27. }));
  28. done.Wait(kTimeout.ms());
  29. }
  30. void VideoFrameScheduler::Start(std::function<void()> callback)
  31. {
  32. callback_ = callback;
  33. lastCaptureStartedTime_ = clock_->CurrentTime();
  34. StartRepeatingTask();
  35. }
  36. void VideoFrameScheduler::Pause(bool pause)
  37. {
  38. paused_ = pause;
  39. if (paused_)
  40. {
  41. StopTask();
  42. }
  43. else
  44. {
  45. StartRepeatingTask();
  46. }
  47. }
  48. void VideoFrameScheduler::OnFrameCaptured(const VideoFrame* frame) { }
  49. void VideoFrameScheduler::SetMaxFramerateFps(int maxFramerate) { maxFramerate_ = maxFramerate; }
  50. absl::optional<TimeDelta> VideoFrameScheduler::ScheduleNextFrame()
  51. {
  52. if (paused_)
  53. {
  54. return absl::nullopt;
  55. }
  56. if (!callback_)
  57. {
  58. return absl::nullopt;
  59. }
  60. if (maxFramerate_ == 0)
  61. {
  62. return absl::nullopt;
  63. }
  64. Timestamp now = clock_->CurrentTime();
  65. TimeDelta interval = std::max(TimeDelta::Seconds(1) / maxFramerate_, TimeDelta::Millis(1));
  66. Timestamp target_capture_time = std::max(lastCaptureStartedTime_ + interval, now);
  67. return target_capture_time - now;
  68. }
  69. void VideoFrameScheduler::CaptureNextFrame()
  70. {
  71. lastCaptureStartedTime_ = clock_->CurrentTime();
  72. callback_();
  73. }
  74. void VideoFrameScheduler::StartRepeatingTask()
  75. {
  76. RTC_DCHECK(!paused_);
  77. RTC_DCHECK(!task_.Running());
  78. auto firstDelay = ScheduleNextFrame();
  79. RTC_DCHECK(firstDelay);
  80. task_ = RepeatingTaskHandle::DelayedStart(
  81. queue_,
  82. firstDelay.value(),
  83. [this]()
  84. {
  85. CaptureNextFrame();
  86. auto delay = ScheduleNextFrame();
  87. if (delay.has_value())
  88. return delay.value();
  89. return TimeDelta::PlusInfinity();
  90. });
  91. }
  92. void VideoFrameScheduler::StopTask()
  93. {
  94. RTC_DCHECK(task_.Running());
  95. task_.Stop();
  96. }
  97. }
  98. }