Reland of write frame generator capturer to use TaskQueue instead of EventTimeWrapper (patchset #1 id:1 of https://codereview.webrtc.org/2751063005/ )

Fix reduced frame-rate on Mac and Android.

Also enable huge full-stack test Largeroom_50thumbs on Windows.

BUG=webrtc:7301

Review-Url: https://codereview.webrtc.org/2760583003
Cr-Commit-Position: refs/heads/master@{#17288}
This commit is contained in:
ilnik 2017-03-17 05:55:25 -07:00 committed by Commit bot
parent 05e908b10b
commit baded15381
4 changed files with 73 additions and 26 deletions

View File

@ -478,7 +478,7 @@ TEST_F(CallPerfTest, ReceivesCpuOveruseAndUnderuse) {
LoadObserver()
: SendTest(kLongTimeoutMs),
expect_lower_resolution_wants_(true),
encoder_(Clock::GetRealTimeClock(), 35 /* delay_ms */) {}
encoder_(Clock::GetRealTimeClock(), 60 /* delay_ms */) {}
void OnFrameGeneratorCapturerCreated(
test::FrameGeneratorCapturer* frame_generator_capturer) override {

View File

@ -10,10 +10,14 @@
#include "webrtc/test/frame_generator_capturer.h"
#include <utility>
#include <vector>
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/platform_thread.h"
#include "webrtc/base/task_queue.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/sleep.h"
#include "webrtc/test/frame_generator.h"
#include "webrtc/video_send_stream.h"
@ -21,6 +25,49 @@
namespace webrtc {
namespace test {
class FrameGeneratorCapturer::InsertFrameTask : public rtc::QueuedTask {
public:
// Repeats in |repeat_interval_ms|. One-time if |repeat_interval_ms| == 0.
InsertFrameTask(
webrtc::test::FrameGeneratorCapturer* frame_generator_capturer,
uint32_t repeat_interval_ms)
: frame_generator_capturer_(frame_generator_capturer),
repeat_interval_ms_(repeat_interval_ms),
intended_run_time_ms_(-1) {}
private:
bool Run() override {
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_) {
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";
}
}
frame_generator_capturer_->InsertFrame();
// Task should be deleted only if it's not repeating.
return repeat_interval_ms_ == 0;
}
webrtc::test::FrameGeneratorCapturer* const frame_generator_capturer_;
const uint32_t repeat_interval_ms_;
int64_t intended_run_time_ms_;
};
FrameGeneratorCapturer* FrameGeneratorCapturer::Create(int width,
int height,
int target_fps,
@ -61,19 +108,17 @@ FrameGeneratorCapturer::FrameGeneratorCapturer(
sending_(false),
sink_(nullptr),
sink_wants_observer_(nullptr),
tick_(EventTimerWrapper::Create()),
thread_(FrameGeneratorCapturer::Run, this, "FrameGeneratorCapturer"),
frame_generator_(std::move(frame_generator)),
target_fps_(target_fps),
first_frame_capture_time_(-1) {
first_frame_capture_time_(-1),
task_queue_("FrameGenCapQ",
rtc::TaskQueue::Priority::HIGH) {
RTC_DCHECK(frame_generator_);
RTC_DCHECK_GT(target_fps, 0);
}
FrameGeneratorCapturer::~FrameGeneratorCapturer() {
Stop();
thread_.Stop();
}
void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) {
@ -87,15 +132,11 @@ bool FrameGeneratorCapturer::Init() {
if (frame_generator_.get() == NULL)
return false;
if (!tick_->StartTimer(true, 1000 / target_fps_))
return false;
thread_.Start();
thread_.SetPriority(rtc::kHighPriority);
return true;
}
task_queue_.PostDelayedTask(
std::unique_ptr<rtc::QueuedTask>(
new InsertFrameTask(this, 1000 / target_fps_)),
1000 / target_fps_);
bool FrameGeneratorCapturer::Run(void* obj) {
static_cast<FrameGeneratorCapturer*>(obj)->InsertFrame();
return true;
}
@ -113,7 +154,6 @@ void FrameGeneratorCapturer::InsertFrame() {
sink_->OnFrame(*frame);
}
}
tick_->Wait(WEBRTC_EVENT_INFINITE);
}
void FrameGeneratorCapturer::Start() {
@ -155,7 +195,11 @@ void FrameGeneratorCapturer::RemoveSink(
}
void FrameGeneratorCapturer::ForceFrame() {
tick_->Set();
// One-time non-repeating task,
// therefore repeat_interval_ms is 0 in InsertFrameTask()
task_queue_.PostTask(
std::unique_ptr<rtc::QueuedTask>(new InsertFrameTask(this, 0)));
}
} // test
} // webrtc
} // namespace test
} // namespace webrtc

View File

@ -15,7 +15,7 @@
#include "webrtc/api/video/video_frame.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/platform_thread.h"
#include "webrtc/base/task_queue.h"
#include "webrtc/test/video_capturer.h"
#include "webrtc/typedefs.h"
@ -74,6 +74,8 @@ class FrameGeneratorCapturer : public VideoCapturer {
bool Init();
private:
class InsertFrameTask;
void InsertFrame();
static bool Run(void* obj);
@ -82,17 +84,18 @@ class FrameGeneratorCapturer : public VideoCapturer {
rtc::VideoSinkInterface<VideoFrame>* sink_ GUARDED_BY(&lock_);
SinkWantsObserver* sink_wants_observer_ GUARDED_BY(&lock_);
std::unique_ptr<EventTimerWrapper> tick_;
rtc::CriticalSection lock_;
rtc::PlatformThread thread_;
std::unique_ptr<FrameGenerator> frame_generator_;
int target_fps_;
VideoRotation fake_rotation_ = kVideoRotation_0;
int64_t first_frame_capture_time_;
// Must be the last field, so it will be deconstructed first as tasks
// in the TaskQueue access other fields of the instance of this class.
rtc::TaskQueue task_queue_;
};
} // test
} // webrtc
} // namespace test
} // namespace webrtc
#endif // WEBRTC_TEST_FRAME_GENERATOR_CAPTURER_H_

View File

@ -534,8 +534,8 @@ TEST_F(FullStackTest, LargeRoomVP8_5thumb) {
RunTest(large_room);
}
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_WIN)
// Fails on Android and win:
#if defined(WEBRTC_ANDROID)
// Fails on Android:
// https://bugs.chromium.org/p/webrtc/issues/detail?id=7301
#define MAYBE_LargeRoomVP8_50thumb DISABLED_LargeRoomVP8_50thumb
#define MAYBE_LargeRoomVP8_15thumb DISABLED_LargeRoomVP8_15thumb