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

Unified Diff: media/base/yuv_convert_perftest.cc

Issue 238353008: Add perf tests for simd yuv->rgb conversion functions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@m
Patch Set: Created 6 years, 8 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 | « no previous file | media/media.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/yuv_convert_perftest.cc
diff --git a/media/base/yuv_convert_perftest.cc b/media/base/yuv_convert_perftest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8a7c076aa76f527356eba3dae0a90ea5c5307c37
--- /dev/null
+++ b/media/base/yuv_convert_perftest.cc
@@ -0,0 +1,269 @@
+// 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 "base/base_paths.h"
+#include "base/cpu.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/time/time.h"
+#include "media/base/djb2.h"
scherkus (not reviewing) 2014/04/22 18:10:56 this isn't used anywhere -- remove (might be wort
rileya (GONE FROM CHROMIUM) 2014/04/23 18:09:21 Whoops, yeah I grabbed this from yuv_convert_unitt
+#include "media/base/simd/convert_rgb_to_yuv.h"
+#include "media/base/simd/convert_yuv_to_rgb.h"
+#include "media/base/simd/filter_yuv.h"
+#include "media/base/yuv_convert.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+#include "ui/gfx/rect.h"
+
scherkus (not reviewing) 2014/04/22 18:10:56 namespace media should go here
rileya (GONE FROM CHROMIUM) 2014/04/23 18:09:21 Done.
+// Size of raw image.
+static const int kSourceWidth = 640;
+static const int kSourceHeight = 360;
+static const int kSourceYSize = kSourceWidth * kSourceHeight;
+static const int kSourceUOffset = kSourceYSize;
+static const int kSourceVOffset = kSourceYSize * 5 / 4;
+static const int kBpp = 4;
+
+// Width of the row to convert. Odd so that we exercise the ending
+// one-pixel-leftover case.
+static const int kWidth = 639;
+
+// Surface sizes for various test files.
+static const int kYUV12Size = kSourceYSize * 12 / 8;
+static const int kRGBSize = kSourceYSize * kBpp;
+
+static const int kPerfTestIterations = 2000;
+
+// Helper for reading test data into a scoped_ptr<uint8[]>.
+static void ReadData(const base::FilePath::CharType* filename,
+ int expected_size,
+ scoped_ptr<uint8[]>* data) {
+ data->reset(new uint8[expected_size]);
+
+ base::FilePath path;
+ CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &path));
+ path = path.Append(FILE_PATH_LITERAL("media"))
+ .Append(FILE_PATH_LITERAL("test"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .Append(filename);
+
+ // Verify file size is correct.
+ int64 actual_size = 0;
+ base::GetFileSize(path, &actual_size);
+ CHECK_EQ(actual_size, expected_size);
+
+ // Verify bytes read are correct.
+ int bytes_read = base::ReadFile(
+ path, reinterpret_cast<char*>(data->get()), expected_size);
+ CHECK_EQ(bytes_read, expected_size);
+}
+
+class YUVConvertPerfTest : public testing::Test {
+ public:
+ YUVConvertPerfTest()
+ : yuv_bytes_(new uint8[kYUV12Size]),
+ rgb_bytes_converted_(new uint8[kRGBSize]) {}
+
+ void InitYV12Data() {
+ ReadData(
scherkus (not reviewing) 2014/04/22 18:10:56 nit: is it worth having ReadData() if there's only
rileya (GONE FROM CHROMIUM) 2014/04/23 18:09:21 Removed.
+ FILE_PATH_LITERAL("bali_640x360_P420.yuv"), kYUV12Size, &yuv_bytes_);
+ }
+
+ scoped_ptr<uint8[]> yuv_bytes_;
+ scoped_ptr<uint8[]> rgb_bytes_converted_;
+};
scherkus (not reviewing) 2014/04/22 18:10:56 DISALLOW etc..
rileya (GONE FROM CHROMIUM) 2014/04/23 18:09:21 Added DISALLOW_COPY_AND_ASSIGN.
+
+namespace media {
+
+#if !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY)
+TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_MMX) {
+ base::CPU cpu;
+ if (!cpu.has_mmx()) {
scherkus (not reviewing) 2014/04/22 18:10:56 considering our minimum supported arch is SSE2 I'd
rileya (GONE FROM CHROMIUM) 2014/04/23 18:09:21 Probably not many, but I was following the convent
+ LOG(WARNING) << "System not supported. Test skipped.";
+ return;
+ }
+
+ InitYV12Data();
+
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ for (int i = 0; i < kPerfTestIterations; ++i) {
+ for (int row = 0; row < kSourceHeight; ++row) {
+ int chroma_row = row / 2;
+ ConvertYUVToRGB32Row_MMX(
+ yuv_bytes_.get() + row * kSourceWidth,
+ yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
+ yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
+ rgb_bytes_converted_.get(),
+ kWidth);
+ }
+ }
+ double total_time_seconds =
+ (base::TimeTicks::HighResNow() - start).InSecondsF();
+ perf_test::PrintResult(
+ "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_MMX",
+ kPerfTestIterations / total_time_seconds, "runs/s", true);
+
+ media::EmptyRegisterState();
+}
+
+TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_SSE) {
+ base::CPU cpu;
+ if (!cpu.has_sse()) {
+ LOG(WARNING) << "System not supported. Test skipped.";
+ return;
+ }
+
+ InitYV12Data();
scherkus (not reviewing) 2014/04/22 18:10:56 this is called every time -- move into ctor?
rileya (GONE FROM CHROMIUM) 2014/04/23 18:09:21 Done.
+
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ for (int i = 0; i < kPerfTestIterations; ++i) {
+ for (int row = 0; row < kSourceHeight; ++row) {
+ int chroma_row = row / 2;
+ ConvertYUVToRGB32Row_SSE(
+ yuv_bytes_.get() + row * kSourceWidth,
+ yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
+ yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
+ rgb_bytes_converted_.get(),
+ kWidth);
+ }
+ }
+ double total_time_seconds =
+ (base::TimeTicks::HighResNow() - start).InSecondsF();
+ perf_test::PrintResult(
+ "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_SSE",
+ kPerfTestIterations / total_time_seconds, "runs/s", true);
+ media::EmptyRegisterState();
+}
+
+TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_MMX) {
+ base::CPU cpu;
+ if (!cpu.has_mmx()) {
+ LOG(WARNING) << "System not supported. Test skipped.";
+ return;
+ }
+
+ InitYV12Data();
+
+ const int kSourceDx = 80000; // This value means a scale down.
+
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ for (int i = 0; i < kPerfTestIterations; ++i) {
+ for (int row = 0; row < kSourceHeight; ++row) {
+ int chroma_row = row / 2;
+ ScaleYUVToRGB32Row_MMX(
+ yuv_bytes_.get() + row * kSourceWidth,
+ yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
+ yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
+ rgb_bytes_converted_.get(),
+ kWidth,
+ kSourceDx);
+ }
+ }
+ double total_time_seconds =
+ (base::TimeTicks::HighResNow() - start).InSecondsF();
+ perf_test::PrintResult(
+ "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_MMX",
+ kPerfTestIterations / total_time_seconds, "runs/s", true);
+ media::EmptyRegisterState();
+}
+
+TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_SSE) {
+ base::CPU cpu;
+ if (!cpu.has_sse()) {
+ LOG(WARNING) << "System not supported. Test skipped.";
+ return;
+ }
+
+ InitYV12Data();
+
+ const int kSourceDx = 80000; // This value means a scale down.
+
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ for (int i = 0; i < kPerfTestIterations; ++i) {
+ for (int row = 0; row < kSourceHeight; ++row) {
+ int chroma_row = row / 2;
+ ScaleYUVToRGB32Row_SSE(
+ yuv_bytes_.get() + row * kSourceWidth,
+ yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
+ yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
+ rgb_bytes_converted_.get(),
+ kWidth,
+ kSourceDx);
+ }
+ }
+ double total_time_seconds =
+ (base::TimeTicks::HighResNow() - start).InSecondsF();
+ perf_test::PrintResult(
+ "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_SSE",
+ kPerfTestIterations / total_time_seconds, "runs/s", true);
+ media::EmptyRegisterState();
+}
+
+TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_MMX) {
+ base::CPU cpu;
+ if (!cpu.has_mmx()) {
+ LOG(WARNING) << "System not supported. Test skipped.";
+ return;
+ }
+
+ InitYV12Data();
+
+ const int kSourceDx = 80000; // This value means a scale down.
+
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ for (int i = 0; i < kPerfTestIterations; ++i) {
+ for (int row = 0; row < kSourceHeight; ++row) {
+ int chroma_row = row / 2;
+ LinearScaleYUVToRGB32Row_MMX(
+ yuv_bytes_.get() + row * kSourceWidth,
+ yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
+ yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
+ rgb_bytes_converted_.get(),
+ kWidth,
+ kSourceDx);
+ }
+ }
+ double total_time_seconds =
+ (base::TimeTicks::HighResNow() - start).InSecondsF();
+ perf_test::PrintResult(
+ "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_MMX",
+ kPerfTestIterations / total_time_seconds, "runs/s", true);
+ media::EmptyRegisterState();
+}
+
+TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_SSE) {
+ base::CPU cpu;
+ if (!cpu.has_sse()) {
+ LOG(WARNING) << "System not supported. Test skipped.";
+ return;
+ }
+
+ InitYV12Data();
+
+ const int kSourceDx = 80000; // This value means a scale down.
+
+ base::TimeTicks start = base::TimeTicks::HighResNow();
+ for (int i = 0; i < kPerfTestIterations; ++i) {
+ for (int row = 0; row < kSourceHeight; ++row) {
+ int chroma_row = row / 2;
+ LinearScaleYUVToRGB32Row_SSE(
+ yuv_bytes_.get() + row * kSourceWidth,
+ yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
+ yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
+ rgb_bytes_converted_.get(),
+ kWidth,
+ kSourceDx);
+ }
+ }
+ double total_time_seconds =
+ (base::TimeTicks::HighResNow() - start).InSecondsF();
+ perf_test::PrintResult(
+ "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_SSE",
+ kPerfTestIterations / total_time_seconds, "runs/s", true);
+ media::EmptyRegisterState();
+}
+
+#endif // !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY)
+
+} // namespace media
« no previous file with comments | « no previous file | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698