summaryrefslogtreecommitdiffstats
path: root/remoting/codec
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-01 06:44:34 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-01 06:44:34 +0000
commitc5a0f60156329f3870da1bb456167623d66776cd (patch)
treeb68d06589b658dc203ad8ebef7a8de413d92797b /remoting/codec
parent2640ab9b046b9397299197bb5150f6721c73d5e7 (diff)
downloadchromium_src-c5a0f60156329f3870da1bb456167623d66776cd.zip
chromium_src-c5a0f60156329f3870da1bb456167623d66776cd.tar.gz
chromium_src-c5a0f60156329f3870da1bb456167623d66776cd.tar.bz2
Add manual tests to benchmark VP8 & VP9 encode performance.
BUG=260879 Review URL: https://codereview.chromium.org/349223007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@280753 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/codec')
-rw-r--r--remoting/codec/codec_test.cc94
-rw-r--r--remoting/codec/codec_test.h13
-rw-r--r--remoting/codec/video_encoder_vpx_perftest.cc61
3 files changed, 144 insertions, 24 deletions
diff --git a/remoting/codec/codec_test.cc b/remoting/codec/codec_test.cc
index 8d1fd38..8b9511c 100644
--- a/remoting/codec/codec_test.cc
+++ b/remoting/codec/codec_test.cc
@@ -16,6 +16,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
+using webrtc::BasicDesktopFrame;
+using webrtc::DesktopFrame;
using webrtc::DesktopRect;
using webrtc::DesktopRegion;
using webrtc::DesktopSize;
@@ -64,7 +66,7 @@ class VideoDecoderTester {
view_size_.width() * view_size_.height() * kBytesPerPixel]);
EXPECT_TRUE(image_data_.get());
decoder_->Initialize(
- webrtc::DesktopSize(screen_size_.width(), screen_size_.height()));
+ DesktopSize(screen_size_.width(), screen_size_.height()));
}
void Reset() {
@@ -85,8 +87,8 @@ class VideoDecoderTester {
void RenderFrame() {
decoder_->RenderFrame(
- webrtc::DesktopSize(view_size_.width(), view_size_.height()),
- webrtc::DesktopRect::MakeWH(view_size_.width(), view_size_.height()),
+ DesktopSize(view_size_.width(), view_size_.height()),
+ DesktopRect::MakeWH(view_size_.width(), view_size_.height()),
image_data_.get(), view_size_.width() * kBytesPerPixel,
&update_region_);
}
@@ -99,7 +101,7 @@ class VideoDecoderTester {
strict_ = strict;
}
- void set_frame(webrtc::DesktopFrame* frame) {
+ void set_frame(DesktopFrame* frame) {
frame_ = frame;
}
@@ -109,7 +111,7 @@ class VideoDecoderTester {
}
}
- void AddRegion(const webrtc::DesktopRegion& region) {
+ void AddRegion(const DesktopRegion& region) {
expected_region_.AddRegion(region);
}
@@ -122,7 +124,7 @@ class VideoDecoderTester {
// Test the content of the update region.
EXPECT_TRUE(expected_region_.Equals(update_region_));
- for (webrtc::DesktopRegion::Iterator i(update_region_); !i.IsAtEnd();
+ for (DesktopRegion::Iterator i(update_region_); !i.IsAtEnd();
i.Advance()) {
const int stride = view_size_.width() * kBytesPerPixel;
EXPECT_EQ(stride, frame_->stride());
@@ -148,7 +150,7 @@ class VideoDecoderTester {
double max_error = 0.0;
double sum_error = 0.0;
int error_num = 0;
- for (webrtc::DesktopRegion::Iterator i(update_region_); !i.IsAtEnd();
+ for (DesktopRegion::Iterator i(update_region_); !i.IsAtEnd();
i.Advance()) {
const int stride = view_size_.width() * kBytesPerPixel;
const int offset = stride * i.rect().top() +
@@ -190,11 +192,11 @@ class VideoDecoderTester {
DesktopSize screen_size_;
DesktopSize view_size_;
bool strict_;
- webrtc::DesktopRegion expected_region_;
- webrtc::DesktopRegion update_region_;
+ DesktopRegion expected_region_;
+ DesktopRegion update_region_;
VideoDecoder* decoder_;
scoped_ptr<uint8[]> image_data_;
- webrtc::DesktopFrame* frame_;
+ DesktopFrame* frame_;
DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester);
};
@@ -231,8 +233,8 @@ class VideoEncoderTester {
DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester);
};
-scoped_ptr<webrtc::DesktopFrame> PrepareFrame(const DesktopSize& size) {
- scoped_ptr<webrtc::DesktopFrame> frame(new webrtc::BasicDesktopFrame(size));
+scoped_ptr<DesktopFrame> PrepareFrame(const DesktopSize& size) {
+ scoped_ptr<DesktopFrame> frame(new BasicDesktopFrame(size));
srand(0);
int memory_size = size.width() * size.height() * kBytesPerPixel;
@@ -280,7 +282,7 @@ void TestVideoEncoder(VideoEncoder* encoder, bool strict) {
static void TestEncodeDecodeRects(VideoEncoder* encoder,
VideoEncoderTester* encoder_tester,
VideoDecoderTester* decoder_tester,
- webrtc::DesktopFrame* frame,
+ DesktopFrame* frame,
const DesktopRect* rects, int count) {
frame->mutable_updated_region()->Clear();
for (int i = 0; i < count; ++i) {
@@ -292,10 +294,10 @@ static void TestEncodeDecodeRects(VideoEncoder* encoder,
srand(0);
for (int i = 0; i < count; ++i) {
const int row_size =
- webrtc::DesktopFrame::kBytesPerPixel * rects[i].width();
+ DesktopFrame::kBytesPerPixel * rects[i].width();
uint8* memory = frame->data() +
frame->stride() * rects[i].top() +
- webrtc::DesktopFrame::kBytesPerPixel * rects[i].left();
+ DesktopFrame::kBytesPerPixel * rects[i].left();
for (int y = 0; y < rects[i].height(); ++y) {
for (int x = 0; x < row_size; ++x)
memory[x] = rand() % 256;
@@ -315,7 +317,7 @@ void TestVideoEncoderDecoder(
VideoEncoderTester encoder_tester;
- scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(kSize);
+ scoped_ptr<DesktopFrame> frame = PrepareFrame(kSize);
VideoDecoderTester decoder_tester(decoder, kSize, kSize);
decoder_tester.set_strict(strict);
@@ -331,7 +333,7 @@ void TestVideoEncoderDecoder(
}
}
-static void FillWithGradient(webrtc::DesktopFrame* frame) {
+static void FillWithGradient(DesktopFrame* frame) {
for (int j = 0; j < frame->size().height(); ++j) {
uint8* p = frame->data() + j * frame->stride();
for (int i = 0; i < frame->size().width(); ++i) {
@@ -350,13 +352,13 @@ void TestVideoEncoderDecoderGradient(VideoEncoder* encoder,
const DesktopSize& view_size,
double max_error_limit,
double mean_error_limit) {
- scoped_ptr<webrtc::BasicDesktopFrame> frame(
- new webrtc::BasicDesktopFrame(screen_size));
+ scoped_ptr<BasicDesktopFrame> frame(
+ new BasicDesktopFrame(screen_size));
FillWithGradient(frame.get());
frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(screen_size));
- scoped_ptr<webrtc::BasicDesktopFrame> expected_result(
- new webrtc::BasicDesktopFrame(view_size));
+ scoped_ptr<BasicDesktopFrame> expected_result(
+ new BasicDesktopFrame(view_size));
FillWithGradient(expected_result.get());
VideoDecoderTester decoder_tester(decoder, screen_size, view_size);
@@ -373,12 +375,56 @@ void TestVideoEncoderDecoderGradient(VideoEncoder* encoder,
// invalidates the frame.
decoder_tester.ResetRenderedData();
decoder->Invalidate(
- webrtc::DesktopSize(view_size.width(), view_size.height()),
- webrtc::DesktopRegion(
- webrtc::DesktopRect::MakeWH(view_size.width(), view_size.height())));
+ DesktopSize(view_size.width(), view_size.height()),
+ DesktopRegion(
+ DesktopRect::MakeWH(view_size.width(), view_size.height())));
decoder_tester.RenderFrame();
decoder_tester.VerifyResultsApprox(expected_result->data(),
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/codec_test.h b/remoting/codec/codec_test.h
index e7e055f..9c9ec7b 100644
--- a/remoting/codec/codec_test.h
+++ b/remoting/codec/codec_test.h
@@ -5,9 +5,12 @@
#ifndef REMOTING_CODEC_CODEC_TEST_H_
#define REMOTING_CODEC_CODEC_TEST_H_
+#include <list>
+
#include "base/memory/ref_counted.h"
namespace webrtc {
+class DesktopFrame;
class DesktopSize;
}
@@ -40,6 +43,16 @@ void TestVideoEncoderDecoderGradient(VideoEncoder* encoder,
double max_error_limit,
double mean_error_limit);
+// Run sufficient encoding iterations to measure the FPS of the specified
+// encoder. The caller may supply one or more DesktopFrames to encode, which
+// will be cycled through until timing is complete. If the caller does not
+// supply any frames then a single full-frame of randomized pixels is used.
+float MeasureVideoEncoderFpsWithSize(VideoEncoder* encoder,
+ const webrtc::DesktopSize& size);
+float MeasureVideoEncoderFpsWithFrames(
+ VideoEncoder* encoder,
+ const std::list<webrtc::DesktopFrame*>& frames);
+
} // namespace remoting
#endif // REMOTING_CODEC_CODEC_TEST_H_
diff --git a/remoting/codec/video_encoder_vpx_perftest.cc b/remoting/codec/video_encoder_vpx_perftest.cc
new file mode 100644
index 0000000..3dc4ef1
--- /dev/null
+++ b/remoting/codec/video_encoder_vpx_perftest.cc
@@ -0,0 +1,61 @@
+// 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 <limits>
+#include <vector>
+
+#include "base/logging.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