diff options
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/BUILD.gn | 4 | ||||
-rw-r--r-- | remoting/codec/codec_test.cc | 44 | ||||
-rw-r--r-- | remoting/codec/video_encoder_vpx.cc | 13 | ||||
-rw-r--r-- | remoting/codec/video_encoder_vpx.h | 6 | ||||
-rw-r--r-- | remoting/codec/video_encoder_vpx_perftest.cc | 64 | ||||
-rw-r--r-- | remoting/remoting_test.gypi | 7 | ||||
-rw-r--r-- | remoting/test/BUILD.gn | 3 | ||||
-rw-r--r-- | remoting/test/DEPS | 1 | ||||
-rw-r--r-- | remoting/test/codec_perftest.cc | 158 | ||||
-rw-r--r-- | remoting/test/cyclic_frame_generator.cc | 119 | ||||
-rw-r--r-- | remoting/test/cyclic_frame_generator.h | 88 | ||||
-rwxr-xr-x | remoting/test/data/download.sh | 20 |
12 files changed, 409 insertions, 118 deletions
diff --git a/remoting/BUILD.gn b/remoting/BUILD.gn index c6360cd..d75e99e 100644 --- a/remoting/BUILD.gn +++ b/remoting/BUILD.gn @@ -164,9 +164,7 @@ if (!is_mac) { if (enable_remoting_host) { test("remoting_perftests") { sources = [ - "codec/codec_test.cc", - "codec/codec_test.h", - "codec/video_encoder_vpx_perftest.cc", + "test/codec_perftest.cc", "test/protocol_perftest.cc", ] diff --git a/remoting/codec/codec_test.cc b/remoting/codec/codec_test.cc index 0c4f431..3da3793 100644 --- a/remoting/codec/codec_test.cc +++ b/remoting/codec/codec_test.cc @@ -343,48 +343,4 @@ void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, decoder_tester.VerifyResultsApprox(max_error_limit, mean_error_limit); } -float MeasureVideoEncoderFpsWithSize(VideoEncoder* encoder, - const DesktopSize& size) { - scoped_ptr<DesktopFrame> frame(PrepareFrame(size)); - frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(size)); - std::list<DesktopFrame*> frames; - frames.push_back(frame.get()); - return MeasureVideoEncoderFpsWithFrames(encoder, frames); -} - -float MeasureVideoEncoderFpsWithFrames(VideoEncoder* encoder, - const std::list<DesktopFrame*>& frames) { - const base::TimeDelta kTestTime = base::TimeDelta::FromSeconds(1); - - // Encode some frames to "warm up" the encoder (i.e. to let it set up initial - // structures, establish a stable working set, etc), then encode at least - // kMinimumFrameCount frames to measure the encoder's performance. - const int kWarmUpFrameCount = 10; - const int kMinimumFrameCount = 10; - base::TimeTicks start_time; - base::TimeDelta elapsed; - std::list<DesktopFrame*> test_frames; - int frame_count; - for (frame_count = 0; - (frame_count < kMinimumFrameCount + kWarmUpFrameCount || - elapsed < kTestTime); - ++frame_count) { - if (frame_count == kWarmUpFrameCount) { - start_time = base::TimeTicks::Now(); - } - - if (test_frames.empty()) { - test_frames = frames; - } - scoped_ptr<VideoPacket> packet = encoder->Encode(*test_frames.front()); - test_frames.pop_front(); - - if (frame_count >= kWarmUpFrameCount) { - elapsed = base::TimeTicks::Now() - start_time; - } - } - - return (frame_count * base::TimeDelta::FromSeconds(1)) / elapsed; -} - } // namespace remoting diff --git a/remoting/codec/video_encoder_vpx.cc b/remoting/codec/video_encoder_vpx.cc index 57a1d5a..2a5894d 100644 --- a/remoting/codec/video_encoder_vpx.cc +++ b/remoting/codec/video_encoder_vpx.cc @@ -242,6 +242,10 @@ scoped_ptr<VideoEncoderVpx> VideoEncoderVpx::CreateForVP9() { VideoEncoderVpx::~VideoEncoderVpx() {} +void VideoEncoderVpx::SetTickClockForTests(base::TickClock* tick_clock) { + clock_ = tick_clock; +} + void VideoEncoderVpx::SetLosslessEncode(bool want_lossless) { if (use_vp9_ && (want_lossless != lossless_encode_)) { lossless_encode_ = want_lossless; @@ -296,7 +300,7 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( } // Do the actual encoding. - int timestamp = (base::TimeTicks::Now() - timestamp_base_).InMilliseconds(); + int timestamp = (clock_->NowTicks() - timestamp_base_).InMilliseconds(); vpx_codec_err_t ret = vpx_codec_encode( codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME); DCHECK_EQ(ret, VPX_CODEC_OK) @@ -345,8 +349,9 @@ scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( } VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) - : use_vp9_(use_vp9), encode_unchanged_frame_(false) { -} + : use_vp9_(use_vp9), + encode_unchanged_frame_(false), + clock_(&default_tick_clock_) {} void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { DCHECK(use_vp9_ || !lossless_color_); @@ -376,7 +381,7 @@ void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { // (Re)Set the base for frame timestamps if the codec is being (re)created. if (!codec_) { - timestamp_base_ = base::TimeTicks::Now(); + timestamp_base_ = clock_->NowTicks(); } // Fetch a default configuration for the desired codec. diff --git a/remoting/codec/video_encoder_vpx.h b/remoting/codec/video_encoder_vpx.h index 83c3549..35d5f67 100644 --- a/remoting/codec/video_encoder_vpx.h +++ b/remoting/codec/video_encoder_vpx.h @@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/time/default_tick_clock.h" #include "base/time/time.h" #include "remoting/codec/scoped_vpx_codec.h" #include "remoting/codec/video_encoder.h" @@ -31,6 +32,8 @@ class VideoEncoderVpx : public VideoEncoder { ~VideoEncoderVpx() override; + void SetTickClockForTests(base::TickClock* tick_clock); + // VideoEncoder interface. void SetLosslessEncode(bool want_lossless) override; void SetLosslessColor(bool want_lossless) override; @@ -84,6 +87,9 @@ class VideoEncoderVpx : public VideoEncoder { // Used to help initialize VideoPackets from DesktopFrames. VideoEncoderHelper helper_; + base::DefaultTickClock default_tick_clock_; + base::TickClock* clock_; + DISALLOW_COPY_AND_ASSIGN(VideoEncoderVpx); }; diff --git a/remoting/codec/video_encoder_vpx_perftest.cc b/remoting/codec/video_encoder_vpx_perftest.cc deleted file mode 100644 index 0c2cf7f..0000000 --- a/remoting/codec/video_encoder_vpx_perftest.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/codec/video_encoder_vpx.h" - -#include <stddef.h> - -#include <limits> -#include <vector> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "remoting/codec/codec_test.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" - -using webrtc::DesktopSize; - -namespace remoting { - -// Measure the performance of the VP8 encoder. -TEST(VideoEncoderVpxTest, MeasureVp8Fps) { - scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP8()); - - const DesktopSize kFrameSizes[] = { - DesktopSize(1280, 1024), DesktopSize(1920, 1200) - }; - - for (size_t i = 0; i < arraysize(kFrameSizes); ++i) { - float fps = - MeasureVideoEncoderFpsWithSize(encoder.get(), kFrameSizes[i]); - LOG(ERROR) << kFrameSizes[i].width() << "x" << kFrameSizes[i].height() - << ": " << fps << "fps"; - } -} - -// Measure the performance of the VP9 encoder. -TEST(VideoEncoderVpxTest, MeasureVp9Fps) { - const DesktopSize kFrameSizes[] = { - DesktopSize(1280, 1024), DesktopSize(1920, 1200) - }; - - for (int lossless_mode = 0; lossless_mode < 4; ++lossless_mode) { - bool lossless_color = lossless_mode & 1; - bool lossless_encode = lossless_mode & 2; - - scoped_ptr<VideoEncoderVpx> encoder(VideoEncoderVpx::CreateForVP9()); - encoder->SetLosslessColor(lossless_color); - encoder->SetLosslessEncode(lossless_encode); - - for (size_t i = 0; i < arraysize(kFrameSizes); ++i) { - float fps = - MeasureVideoEncoderFpsWithSize(encoder.get(), kFrameSizes[i]); - LOG(ERROR) << kFrameSizes[i].width() << "x" << kFrameSizes[i].height() - << "(" << (lossless_encode ? "lossless" : "lossy ") << ")" - << "(" << (lossless_color ? "I444" : "I420") << ")" - << ": " << fps << "fps"; - } - } -} - -} // namespace remoting diff --git a/remoting/remoting_test.gypi b/remoting/remoting_test.gypi index fe8edf4..56efae3 100644 --- a/remoting/remoting_test.gypi +++ b/remoting/remoting_test.gypi @@ -11,6 +11,7 @@ 'dependencies': [ '../base/base.gyp:base', '../net/net.gyp:net_test_support', + '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', 'remoting_base', @@ -65,6 +66,8 @@ 'test/connection_setup_info.h', 'test/connection_time_observer.cc', 'test/connection_time_observer.h', + 'test/cyclic_frame_generator.cc', + 'test/cyclic_frame_generator.h', 'test/fake_access_token_fetcher.cc', 'test/fake_access_token_fetcher.h', 'test/fake_app_remoting_report_issue_request.cc', @@ -557,9 +560,7 @@ ], 'sources': [ 'base/run_all_unittests.cc', - 'codec/codec_test.cc', - 'codec/codec_test.h', - 'codec/video_encoder_vpx_perftest.cc', + 'test/codec_perftest.cc', 'test/protocol_perftest.cc', ], 'conditions': [ diff --git a/remoting/test/BUILD.gn b/remoting/test/BUILD.gn index fd014ff..8bc132f 100644 --- a/remoting/test/BUILD.gn +++ b/remoting/test/BUILD.gn @@ -18,6 +18,8 @@ source_set("test_support") { "connection_setup_info.h", "connection_time_observer.cc", "connection_time_observer.h", + "cyclic_frame_generator.cc", + "cyclic_frame_generator.h", "fake_access_token_fetcher.cc", "fake_access_token_fetcher.h", "fake_app_remoting_report_issue_request.cc", @@ -76,6 +78,7 @@ source_set("test_support") { deps = [ "//google_apis", + "//skia", "//testing/gmock", "//testing/gtest", "//third_party/libjingle", diff --git a/remoting/test/DEPS b/remoting/test/DEPS index ef74945..485d290 100644 --- a/remoting/test/DEPS +++ b/remoting/test/DEPS @@ -8,4 +8,5 @@ include_rules = [ "+remoting/signaling", "+ui/gfx", "+ui/events/keycodes/dom", + "+third_party/skia", ] diff --git a/remoting/test/codec_perftest.cc b/remoting/test/codec_perftest.cc new file mode 100644 index 0000000..e157b88 --- /dev/null +++ b/remoting/test/codec_perftest.cc @@ -0,0 +1,158 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/simple_test_tick_clock.h" +#include "remoting/codec/video_encoder_vpx.h" +#include "remoting/proto/video.pb.h" +#include "remoting/test/cyclic_frame_generator.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" + +namespace remoting { +namespace test { + +static const int kIntervalBetweenFramesMs = 33; + +struct CodecParams { + CodecParams(bool use_vp9, bool lossless, bool lossless_color) + : use_vp9(use_vp9), lossless(lossless), lossless_color(lossless_color) {} + + bool use_vp9; + bool lossless; + bool lossless_color; +}; + +class CodecPerfTest : public testing::Test, + public testing::WithParamInterface<CodecParams> { + public: + void SetUp() override { + if (GetParam().use_vp9) { + encoder_ = VideoEncoderVpx::CreateForVP9(); + encoder_->SetLosslessEncode(GetParam().lossless); + encoder_->SetLosslessColor(GetParam().lossless_color); + } else { + encoder_ = VideoEncoderVpx::CreateForVP8(); + } + encoder_->SetTickClockForTests(&clock_); + + frame_generator_ = CyclicFrameGenerator::Create(); + frame_generator_->SetTickClock(&clock_); + } + + protected: + base::SimpleTestTickClock clock_; + scoped_refptr<CyclicFrameGenerator> frame_generator_; + scoped_ptr<VideoEncoderVpx> encoder_; +}; + +INSTANTIATE_TEST_CASE_P(VP8, + CodecPerfTest, + ::testing::Values(CodecParams(false, false, false))); +INSTANTIATE_TEST_CASE_P(VP9, + CodecPerfTest, + ::testing::Values(CodecParams(true, false, false))); +INSTANTIATE_TEST_CASE_P(VP9Lossless, + CodecPerfTest, + ::testing::Values(CodecParams(true, true, false))); +INSTANTIATE_TEST_CASE_P(VP9LosslessColor, + CodecPerfTest, + ::testing::Values(CodecParams(true, false, true))); + +TEST_P(CodecPerfTest, EncodeLatency) { + const int kTotalFrames = 300; + base::TimeDelta total_latency; + + base::TimeDelta total_latency_big_frames; + int big_frame_count = 0; + base::TimeDelta total_latency_small_frames; + int small_frame_count = 0; + base::TimeDelta total_latency_empty_frames; + int empty_frame_count = 0; + + int total_bytes = 0; + + for (int i = 0; i < kTotalFrames; ++i) { + scoped_ptr<webrtc::DesktopFrame> frame = + frame_generator_->GenerateFrame(nullptr); + base::TimeTicks started = base::TimeTicks::Now(); + + scoped_ptr<VideoPacket> packet = encoder_->Encode(*frame); + + base::TimeTicks ended = base::TimeTicks::Now(); + base::TimeDelta latency = ended - started; + + total_latency += latency; + if (packet) + total_bytes += packet->data().size(); + + switch (frame_generator_->last_frame_type()) { + case CyclicFrameGenerator::FrameType::EMPTY: + total_latency_empty_frames += latency; + ++empty_frame_count; + break; + case CyclicFrameGenerator::FrameType::FULL: + total_latency_big_frames += latency; + ++big_frame_count; + break; + case CyclicFrameGenerator::FrameType::CURSOR: + total_latency_small_frames += latency; + ++small_frame_count; + break; + } + + clock_.Advance(base::TimeDelta::FromMilliseconds(kIntervalBetweenFramesMs)); + } + + VLOG(0) << "Total time: " << total_latency.InMillisecondsF(); + VLOG(0) << "Average encode latency: " + << (total_latency / kTotalFrames).InMillisecondsF(); + + CHECK(big_frame_count); + VLOG(0) << "Average encode latency for big frames: " + << (total_latency_big_frames / big_frame_count).InMillisecondsF(); + + if (small_frame_count) { + VLOG(0) << "Average encode latency for small frames: " + << (total_latency_small_frames / small_frame_count) + .InMillisecondsF(); + } + + if (empty_frame_count) { + VLOG(0) << "Average encode latency for empty frames: " + << (total_latency_empty_frames / empty_frame_count) + .InMillisecondsF(); + } + + VLOG(0) << "Encoded bytes: " << total_bytes; +} + +TEST_P(CodecPerfTest, MaxFramerate) { + const int kTotalFrames = 100; + base::TimeDelta total_latency; + + // Update the whole screen on every frame. + frame_generator_->set_frame_cycle_period( + base::TimeDelta::FromMilliseconds(kIntervalBetweenFramesMs)); + + for (int i = 0; i < kTotalFrames; ++i) { + scoped_ptr<webrtc::DesktopFrame> frame = + frame_generator_->GenerateFrame(nullptr); + base::TimeTicks started = base::TimeTicks::Now(); + + scoped_ptr<VideoPacket> packet = encoder_->Encode(*frame); + + base::TimeTicks ended = base::TimeTicks::Now(); + base::TimeDelta latency = ended - started; + + total_latency += latency; + + clock_.Advance(base::TimeDelta::FromMilliseconds(kIntervalBetweenFramesMs)); + } + + VLOG(0) << "Max framerate: " + << (kTotalFrames * base::TimeDelta::FromSeconds(1) / total_latency); +} + +} // namespace test +} // namespace remoting diff --git a/remoting/test/cyclic_frame_generator.cc b/remoting/test/cyclic_frame_generator.cc new file mode 100644 index 0000000..2fb3753 --- /dev/null +++ b/remoting/test/cyclic_frame_generator.cc @@ -0,0 +1,119 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/test/cyclic_frame_generator.h" + +#include "base/base_paths.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/time/default_tick_clock.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" +#include "ui/gfx/codec/png_codec.h" + +namespace remoting { +namespace test { + +namespace { + +scoped_ptr<webrtc::DesktopFrame> LoadDesktopFrameFromPng( + const base::FilePath& file_path) { + std::string file_content; + if (!base::ReadFileToString(file_path, &file_content)) + LOG(FATAL) << "Failed to read " << file_path.MaybeAsASCII() + << ". Please run remoting/test/data/download.sh"; + SkBitmap bitmap; + gfx::PNGCodec::Decode(reinterpret_cast<const uint8_t*>(file_content.data()), + file_content.size(), &bitmap); + scoped_ptr<webrtc::DesktopFrame> frame(new webrtc::BasicDesktopFrame( + webrtc::DesktopSize(bitmap.width(), bitmap.height()))); + bitmap.copyPixelsTo(frame->data(), + frame->stride() * frame->size().height(), + frame->stride()); + return frame; +} + +} // namespace + +// static +scoped_refptr<CyclicFrameGenerator> CyclicFrameGenerator::Create() { + base::FilePath test_data_path; + PathService::Get(base::DIR_SOURCE_ROOT, &test_data_path); + test_data_path = test_data_path.Append(FILE_PATH_LITERAL("remoting")); + test_data_path = test_data_path.Append(FILE_PATH_LITERAL("test")); + test_data_path = test_data_path.Append(FILE_PATH_LITERAL("data")); + + std::vector<scoped_ptr<webrtc::DesktopFrame>> frames; + frames.push_back( + LoadDesktopFrameFromPng(test_data_path.AppendASCII("test_frame1.png"))); + frames.push_back( + LoadDesktopFrameFromPng(test_data_path.AppendASCII("test_frame2.png"))); + return new CyclicFrameGenerator(std::move(frames)); +} + +CyclicFrameGenerator::CyclicFrameGenerator( + std::vector<scoped_ptr<webrtc::DesktopFrame>> reference_frames) + : reference_frames_(std::move(reference_frames)), + clock_(&default_tick_clock_), + started_time_(clock_->NowTicks()) { + CHECK(!reference_frames_.empty()); + screen_size_ = reference_frames_[0]->size(); + for (const auto& frame : reference_frames_) { + CHECK(screen_size_.equals(frame->size())) + << "All reference frames should have the same size."; + } +} +CyclicFrameGenerator::~CyclicFrameGenerator() {} + +void CyclicFrameGenerator::SetTickClock(base::TickClock* tick_clock) { + clock_ = tick_clock; + started_time_ = clock_->NowTicks(); +} + +scoped_ptr<webrtc::DesktopFrame> CyclicFrameGenerator::GenerateFrame( + webrtc::DesktopCapturer::Callback* callback) { + base::TimeTicks now = clock_->NowTicks(); + int reference_frame = + ((now - started_time_) / frame_cycle_period_) % reference_frames_.size(); + bool cursor_state = ((now - started_time_) / cursor_blink_period_) % 2; + + scoped_ptr<webrtc::DesktopFrame> frame( + new webrtc::BasicDesktopFrame(screen_size_)); + frame->CopyPixelsFrom(*reference_frames_[reference_frame], + webrtc::DesktopVector(), + webrtc::DesktopRect::MakeSize(screen_size_)); + + // Render the cursor. + webrtc::DesktopRect cursor_rect = + webrtc::DesktopRect::MakeXYWH(20, 20, 2, 20); + if (cursor_state) { + for (int y = cursor_rect.top(); y < cursor_rect.bottom(); ++y) { + memset(frame->data() + y * frame->stride() + + cursor_rect.left() * webrtc::DesktopFrame::kBytesPerPixel, + 0, cursor_rect.width() * webrtc::DesktopFrame::kBytesPerPixel); + } + } + + if (last_reference_frame_ != reference_frame) { + // The whole frame has changed. + frame->mutable_updated_region()->AddRect( + webrtc::DesktopRect::MakeSize(screen_size_)); + last_frame_type_ = FrameType::FULL; + } else if (last_cursor_state_ != cursor_state) { + // Cursor state has changed. + frame->mutable_updated_region()->AddRect(cursor_rect); + last_frame_type_ = FrameType::CURSOR; + } else { + // No changes. + last_frame_type_ = FrameType::EMPTY; + } + last_reference_frame_ = reference_frame; + last_cursor_state_ = cursor_state; + + return frame; +} + +} // namespace test +} // namespace remoting diff --git a/remoting/test/cyclic_frame_generator.h b/remoting/test/cyclic_frame_generator.h new file mode 100644 index 0000000..50acad0 --- /dev/null +++ b/remoting/test/cyclic_frame_generator.h @@ -0,0 +1,88 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_TEST_CYCLIC_FRAME_GENERATOR_H_ +#define REMOTING_TEST_CYCLIC_FRAME_GENERATOR_H_ + +#include <vector> + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/time/default_tick_clock.h" +#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" + +namespace remoting { +namespace test { + +// CyclicFrameGenerator generates a sequence of frames that approximates +// properties of a real video stream when using a desktop applications. It +// loads a sequence of reference frames and switches between them with the +// specified frequency (every 2 seconds by default). Between reference frames it +// also generate frames with small changes which simulate a blinking cursor. +class CyclicFrameGenerator + : public base::RefCountedThreadSafe<CyclicFrameGenerator> { + public: + enum class FrameType { + // Frame had no changes. + EMPTY, + + // Whole screen changed. + FULL, + + // Cursor state has changed. + CURSOR, + }; + + static scoped_refptr<CyclicFrameGenerator> Create(); + + CyclicFrameGenerator( + std::vector<scoped_ptr<webrtc::DesktopFrame>> reference_frames); + + void set_frame_cycle_period(base::TimeDelta frame_cycle_period) { + frame_cycle_period_ = frame_cycle_period; + } + + void set_cursor_blink_period(base::TimeDelta cursor_blink_period) { + cursor_blink_period_ = cursor_blink_period; + } + + void SetTickClock(base::TickClock* tick_clock); + + scoped_ptr<webrtc::DesktopFrame> GenerateFrame( + webrtc::DesktopCapturer::Callback* callback); + + FrameType last_frame_type() { return last_frame_type_; } + + private: + ~CyclicFrameGenerator(); + friend class base::RefCountedThreadSafe<CyclicFrameGenerator>; + + std::vector<scoped_ptr<webrtc::DesktopFrame>> reference_frames_; + base::DefaultTickClock default_tick_clock_; + base::TickClock* clock_; + webrtc::DesktopSize screen_size_; + + // By default switch between reference frames every 2 seconds. + base::TimeDelta frame_cycle_period_ = base::TimeDelta::FromSeconds(2); + + // By default blink the cursor 4 times per seconds. + base::TimeDelta cursor_blink_period_ = base::TimeDelta::FromMilliseconds(250); + + // Index of the reference frame used to render the last generated frame. + int last_reference_frame_ = -1; + + // True if the cursor was rendered on the last generated frame. + bool last_cursor_state_ = false; + + FrameType last_frame_type_ = FrameType::EMPTY; + + base::TimeTicks started_time_; + + DISALLOW_COPY_AND_ASSIGN(CyclicFrameGenerator); +}; + +} // namespace test +} // namespace remoting + +#endif // REMOTING_TEST_CYCLIC_FRAME_GENERATOR_H_ diff --git a/remoting/test/data/download.sh b/remoting/test/data/download.sh new file mode 100755 index 0000000..106a883 --- /dev/null +++ b/remoting/test/data/download.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This script downloads test files used by some remoting perf tests.The files +# are stored on Google Cloud Storage. + +set -e + +SRC_DIR="$(readlink -f "$(dirname "$0")")" + +for file_index in 1 2; do + file_name=test_frame${file_index}.png + file_path="${SRC_DIR}/${file_name}" + if [ ! -e "${file_path}" ] ; then + curl -L "https://storage.googleapis.com/chromoting-test-data/${file_name}" \ + > "${file_path}" + fi +done |