Adds support for frame rate control in FrameGeneratorCapturer.

Bug: webrtc:9510
Change-Id: Idb062978a856ead994fce7e72402effcd8c719cf
Reviewed-on: https://webrtc-review.googlesource.com/95148
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24499}
This commit is contained in:
Sebastian Jansson 2018-08-30 11:19:23 +02:00 committed by Commit Bot
parent 34ee419a23
commit ba3decfe00
2 changed files with 32 additions and 5 deletions

View file

@ -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<double>(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<double>(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

View file

@ -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<FrameGenerator> 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<int> wanted_fps_ RTC_GUARDED_BY(&lock_);
VideoRotation fake_rotation_ = kVideoRotation_0;