diff --git a/test/frame_generator_capturer.cc b/test/frame_generator_capturer.cc index 6a58a3fb0b..87e9bb3bcf 100644 --- a/test/frame_generator_capturer.cc +++ b/test/frame_generator_capturer.cc @@ -143,7 +143,8 @@ FrameGeneratorCapturer::FrameGeneratorCapturer( sink_(nullptr), sink_wants_observer_(nullptr), frame_generator_(std::move(frame_generator)), - target_fps_(target_fps), + source_fps_(target_fps), + target_capture_fps_(target_fps), first_frame_capture_time_(-1), task_queue_("FrameGenCapQ", rtc::TaskQueue::Priority::HIGH) { RTC_DCHECK(frame_generator_); @@ -178,6 +179,12 @@ void FrameGeneratorCapturer::InsertFrame() { rtc::CritScope cs(&lock_); if (sending_) { VideoFrame* frame = frame_generator_->NextFrame(); + // TODO(srte): Use more advanced frame rate control to allow arbritrary + // fractions. + int decimation = + std::round(static_cast(source_fps_) / target_capture_fps_); + for (int i = 1; i < decimation; ++i) + frame = frame_generator_->NextFrame(); frame->set_timestamp_us(clock_->TimeInMicroseconds()); frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds()); frame->set_rotation(fake_rotation_); @@ -208,6 +215,24 @@ void FrameGeneratorCapturer::ChangeResolution(size_t width, size_t height) { frame_generator_->ChangeResolution(width, height); } +void FrameGeneratorCapturer::ChangeFramerate(int target_framerate) { + rtc::CritScope cs(&lock_); + RTC_CHECK(target_capture_fps_ > 0); + if (target_framerate > source_fps_) + RTC_LOG(LS_WARNING) << "Target framerate clamped from " << target_framerate + << " to " << source_fps_; + if (source_fps_ % target_capture_fps_ != 0) { + int decimation = + std::round(static_cast(source_fps_) / target_capture_fps_); + int effective_rate = target_capture_fps_ / decimation; + RTC_LOG(LS_WARNING) << "Target framerate, " << target_framerate + << ", is an uneven fraction of the source rate, " + << source_fps_ + << ". The framerate will be :" << effective_rate; + } + target_capture_fps_ = std::min(source_fps_, target_framerate); +} + void FrameGeneratorCapturer::SetSinkWantsObserver(SinkWantsObserver* observer) { rtc::CritScope cs(&lock_); RTC_DCHECK(!sink_wants_observer_); @@ -230,7 +255,7 @@ void FrameGeneratorCapturer::AddOrUpdateSink( TestVideoCapturer::AddOrUpdateSink(sink, resolution_wants); // Ignore any requests for framerate higher than initially configured. - if (wants.max_framerate_fps < target_fps_) { + if (wants.max_framerate_fps < target_capture_fps_) { wanted_fps_.emplace(wants.max_framerate_fps); } else { wanted_fps_.reset(); @@ -253,9 +278,9 @@ void FrameGeneratorCapturer::ForceFrame() { int FrameGeneratorCapturer::GetCurrentConfiguredFramerate() { rtc::CritScope cs(&lock_); - if (wanted_fps_ && *wanted_fps_ < target_fps_) + if (wanted_fps_ && *wanted_fps_ < target_capture_fps_) return *wanted_fps_; - return target_fps_; + return target_capture_fps_; } } // namespace test diff --git a/test/frame_generator_capturer.h b/test/frame_generator_capturer.h index ac32fa45b4..6b2ed69bf0 100644 --- a/test/frame_generator_capturer.h +++ b/test/frame_generator_capturer.h @@ -64,6 +64,7 @@ class FrameGeneratorCapturer : public TestVideoCapturer { void Start() override; void Stop() override; void ChangeResolution(size_t width, size_t height); + void ChangeFramerate(int target_framerate); void SetSinkWantsObserver(SinkWantsObserver* observer); @@ -96,7 +97,8 @@ class FrameGeneratorCapturer : public TestVideoCapturer { rtc::CriticalSection lock_; std::unique_ptr frame_generator_; - int target_fps_ RTC_GUARDED_BY(&lock_); + int source_fps_ RTC_GUARDED_BY(&lock_); + int target_capture_fps_ RTC_GUARDED_BY(&lock_); absl::optional wanted_fps_ RTC_GUARDED_BY(&lock_); VideoRotation fake_rotation_ = kVideoRotation_0;