Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(538)

Unified Diff: webrtc/test/frame_generator_capturer.cc

Issue 2716643002: Add framerate to VideoSinkWants and ability to signal on overuse (Closed)
Patch Set: Comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/test/frame_generator_capturer.h ('k') | webrtc/test/vcm_capturer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/test/frame_generator_capturer.cc
diff --git a/webrtc/test/frame_generator_capturer.cc b/webrtc/test/frame_generator_capturer.cc
index 9e74e40d18bf072b85ab23c2283ded7a2660bc6c..d16d8c836fac1a1b12250a18fc4f69b80130386c 100644
--- a/webrtc/test/frame_generator_capturer.cc
+++ b/webrtc/test/frame_generator_capturer.cc
@@ -37,30 +37,47 @@ class FrameGeneratorCapturer::InsertFrameTask : public rtc::QueuedTask {
private:
bool Run() override {
+ bool task_completed = true;
if (repeat_interval_ms_ > 0) {
- int64_t delay_ms;
- int64_t time_now_ms = rtc::TimeMillis();
- if (intended_run_time_ms_ > 0) {
- delay_ms = time_now_ms - intended_run_time_ms_;
- } else {
- delay_ms = 0;
- intended_run_time_ms_ = time_now_ms;
- }
- intended_run_time_ms_ += repeat_interval_ms_;
- if (delay_ms < repeat_interval_ms_) {
+ // This is not a one-off frame. Check if the frame interval for this
+ // task queue is the same same as the current configured frame rate.
+ uint32_t current_interval_ms =
+ 1000 / frame_generator_capturer_->GetCurrentConfiguredFramerate();
+ if (repeat_interval_ms_ != current_interval_ms) {
+ // Frame rate has changed since task was started, create a new instance.
rtc::TaskQueue::Current()->PostDelayedTask(
- std::unique_ptr<rtc::QueuedTask>(this),
- repeat_interval_ms_ - delay_ms);
+ std::unique_ptr<rtc::QueuedTask>(new InsertFrameTask(
+ frame_generator_capturer_, current_interval_ms)),
+ current_interval_ms);
} else {
- rtc::TaskQueue::Current()->PostDelayedTask(
- std::unique_ptr<rtc::QueuedTask>(this), 0);
- LOG(LS_ERROR)
- << "Frame Generator Capturer can't keep up with requested fps";
+ // Schedule the next frame capture event to happen at approximately the
+ // correct absolute time point.
+ int64_t delay_ms;
+ int64_t time_now_ms = rtc::TimeMillis();
+ if (intended_run_time_ms_ > 0) {
+ delay_ms = time_now_ms - intended_run_time_ms_;
+ } else {
+ delay_ms = 0;
+ intended_run_time_ms_ = time_now_ms;
+ }
+ intended_run_time_ms_ += repeat_interval_ms_;
+ if (delay_ms < repeat_interval_ms_) {
+ rtc::TaskQueue::Current()->PostDelayedTask(
+ std::unique_ptr<rtc::QueuedTask>(this),
+ repeat_interval_ms_ - delay_ms);
+ } else {
+ rtc::TaskQueue::Current()->PostDelayedTask(
+ std::unique_ptr<rtc::QueuedTask>(this), 0);
+ LOG(LS_ERROR)
+ << "Frame Generator Capturer can't keep up with requested fps";
+ }
+ // Repost of this instance, make sure it is not deleted.
+ task_completed = false;
}
}
frame_generator_capturer_->InsertFrame();
// Task should be deleted only if it's not repeating.
- return repeat_interval_ms_ == 0;
+ return task_completed;
}
webrtc::test::FrameGeneratorCapturer* const frame_generator_capturer_;
@@ -72,14 +89,12 @@ FrameGeneratorCapturer* FrameGeneratorCapturer::Create(int width,
int height,
int target_fps,
Clock* clock) {
- FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
- clock, FrameGenerator::CreateSquareGenerator(width, height), target_fps);
- if (!capturer->Init()) {
- delete capturer;
- return NULL;
- }
+ std::unique_ptr<FrameGeneratorCapturer> capturer(new FrameGeneratorCapturer(
+ clock, FrameGenerator::CreateSquareGenerator(width, height), target_fps));
+ if (!capturer->Init())
+ return nullptr;
- return capturer;
+ return capturer.release();
}
FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
@@ -88,16 +103,15 @@ FrameGeneratorCapturer* FrameGeneratorCapturer::CreateFromYuvFile(
size_t height,
int target_fps,
Clock* clock) {
- FrameGeneratorCapturer* capturer = new FrameGeneratorCapturer(
- clock, FrameGenerator::CreateFromYuvFile(
- std::vector<std::string>(1, file_name), width, height, 1),
- target_fps);
- if (!capturer->Init()) {
- delete capturer;
- return NULL;
- }
-
- return capturer;
+ std::unique_ptr<FrameGeneratorCapturer> capturer(new FrameGeneratorCapturer(
+ clock,
+ FrameGenerator::CreateFromYuvFile(std::vector<std::string>(1, file_name),
+ width, height, 1),
+ target_fps));
+ if (!capturer->Init())
+ return nullptr;
+
+ return capturer.release();
}
FrameGeneratorCapturer::FrameGeneratorCapturer(
@@ -129,29 +143,32 @@ void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) {
bool FrameGeneratorCapturer::Init() {
// This check is added because frame_generator_ might be file based and should
// not crash because a file moved.
- if (frame_generator_.get() == NULL)
+ if (frame_generator_.get() == nullptr)
return false;
+ int framerate_fps = GetCurrentConfiguredFramerate();
task_queue_.PostDelayedTask(
std::unique_ptr<rtc::QueuedTask>(
- new InsertFrameTask(this, 1000 / target_fps_)),
- 1000 / target_fps_);
+ new InsertFrameTask(this, 1000 / framerate_fps)),
+ 1000 / framerate_fps);
return true;
}
void FrameGeneratorCapturer::InsertFrame() {
- {
- rtc::CritScope cs(&lock_);
- if (sending_) {
- VideoFrame* frame = frame_generator_->NextFrame();
- frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds());
- frame->set_rotation(fake_rotation_);
- if (first_frame_capture_time_ == -1) {
- first_frame_capture_time_ = frame->ntp_time_ms();
- }
- if (sink_)
- sink_->OnFrame(*frame);
+ rtc::CritScope cs(&lock_);
+ if (sending_) {
+ VideoFrame* frame = frame_generator_->NextFrame();
+ frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds());
+ frame->set_rotation(fake_rotation_);
+ if (first_frame_capture_time_ == -1) {
+ first_frame_capture_time_ = frame->ntp_time_ms();
+ }
+
+ if (sink_) {
+ rtc::Optional<VideoFrame> out_frame = AdaptFrame(*frame);
+ if (out_frame)
+ sink_->OnFrame(*out_frame);
}
}
}
@@ -185,6 +202,19 @@ void FrameGeneratorCapturer::AddOrUpdateSink(
sink_ = sink;
if (sink_wants_observer_)
sink_wants_observer_->OnSinkWantsChanged(sink, wants);
+
+ // Handle framerate within this class, just pass on resolution for possible
+ // adaptation.
+ rtc::VideoSinkWants resolution_wants = wants;
+ resolution_wants.max_framerate_fps = std::numeric_limits<int>::max();
+ VideoCapturer::AddOrUpdateSink(sink, resolution_wants);
+
+ // Ignore any requests for framerate higher than initially configured.
+ if (wants.max_framerate_fps < target_fps_) {
+ wanted_fps_.emplace(wants.max_framerate_fps);
+ } else {
+ wanted_fps_.reset();
+ }
}
void FrameGeneratorCapturer::RemoveSink(
@@ -201,5 +231,12 @@ void FrameGeneratorCapturer::ForceFrame() {
std::unique_ptr<rtc::QueuedTask>(new InsertFrameTask(this, 0)));
}
+int FrameGeneratorCapturer::GetCurrentConfiguredFramerate() {
+ rtc::CritScope cs(&lock_);
+ if (wanted_fps_ && *wanted_fps_ < target_fps_)
+ return *wanted_fps_;
+ return target_fps_;
+}
+
} // namespace test
} // namespace webrtc
« no previous file with comments | « webrtc/test/frame_generator_capturer.h ('k') | webrtc/test/vcm_capturer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698