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

Side by Side Diff: media/base/simd/convert_rgb_to_yuv_unittest.cc

Issue 7003082: Implements RGB to YV12 conversion in YASM. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/scoped_ptr.h"
6 #include "base/stringprintf.h"
7 #include "media/base/cpu_features.h"
8 #include "media/base/simd/convert_rgb_to_yuv.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace {
12
13 // Reference code that converts RGB pixels to YUV pixels.
14 int ConvertRGBToY(const uint8* rgb) {
15 int y = 25 * rgb[0] + 129 * rgb[1] + 66 * rgb[2];
16 y = ((y + 128) >> 8) + 16;
17 return std::max(0, std::min(255, y));
18 }
19
20 int ConvertRGBToU(const uint8* rgb, int size, bool subsampling) {
21 int u = 0;
22 if (!subsampling) {
23 u = 112 * rgb[0] - 74 * rgb[1] - 38 * rgb[2];
24 } else {
25 int u0 = 112 * rgb[0] - 74 * rgb[1] - 38 * rgb[2];
26 int u1 = 112 * rgb[size] - 74 * rgb[size + 1] - 38 * rgb[size + 2];
27 u = (u0 + u1 + 1) / 2;
28 }
29 u = ((u + 128) >> 8) + 128;
30 return std::max(0, std::min(255, u));
31 }
32
33 int ConvertRGBToV(const uint8* rgb, int size, bool subsampling) {
34 int v = 0;
35 if (!subsampling) {
36 v = -18 * rgb[0] - 94 * rgb[1] + 112 * rgb[2];
37 } else {
38 int v0 = -18 * rgb[0] - 94 * rgb[1] + 112 * rgb[2];
39 int v1 = -18 * rgb[size] - 94 * rgb[size + 1] + 112 * rgb[size + 2];
40 v = (v0 + v1 + 1) / 2;
41 }
42 v = ((v + 128) >> 8) + 128;
43 return std::max(0, std::min(255, v));
44 }
45
46 } // namespace
47
48 // A side-by-side test that verifies our ASM functions that convert RGB pixels
49 // to YUV pixels can output the expected results. This test converts RGB pixels
50 // to YUV pixels with our ASM functions (which use SSE, SSE2, SSE3, and SSSE3)
51 // and compare the output YUV pixels with the ones calculated with out reference
52 // functions implemented in C++.
53 TEST(YUVConvertTest, SideBySideRGB) {
54 // We skip this test on PCs which does not support SSE3 because this test
55 // needs it.
56 if (!media::hasSSSE3())
57 return;
58
59 // This test checks a subset of all RGB values so this test does not take so
60 // long time.
61 const int kStep = 8;
62 const int kWidth = 256 / kStep;
63
64 #ifdef ENABLE_SUBSAMPLING
65 const bool kSubsampling = true;
66 #else
67 const bool kSubsampling = false;
68 #endif
69
70 for (int size = 3; size <= 4; ++size) {
71 // Create the output buffers.
72 scoped_array<uint8> rgb(new uint8[kWidth * size]);
73 scoped_array<uint8> y(new uint8[kWidth]);
74 scoped_array<uint8> u(new uint8[kWidth / 2]);
75 scoped_array<uint8> v(new uint8[kWidth / 2]);
76
77 // Choose the function that converts from RGB pixels to YUV ones.
78 void (*convert)(const uint8*, uint8*, uint8*, uint8*,
79 int, int, int, int, int) = NULL;
80 if (size == 3)
81 convert = media::ConvertRGB24ToYUV_SSSE3;
82 else
83 convert = media::ConvertRGB32ToYUV_SSSE3;
84
85 for (int r = 0; r < kWidth; ++r) {
86 for (int g = 0; g < kWidth; ++g) {
87
88 // Fill the input pixels.
89 for (int b = 0; b < kWidth; ++b) {
90 rgb[b * size + 0] = b * kStep;
91 rgb[b * size + 1] = g * kStep;
92 rgb[b * size + 2] = r * kStep;
93 if (size == 4)
94 rgb[b * size + 3] = 255;
95 }
96
97 // Convert the input RGB pixels to YUV ones.
98 convert(rgb.get(), y.get(), u.get(), v.get(), kWidth, 1, kWidth * size,
99 kWidth, kWidth / 2);
100
101 // Check the output Y pixels.
102 for (int i = 0; i < kWidth; ++i) {
103 const uint8* p = &rgb[i * size];
104 SCOPED_TRACE(base::StringPrintf("r=%d,g=%d,b=%d", p[2], p[1], p[0]));
105 EXPECT_EQ(ConvertRGBToY(p), y[i]);
106 }
107
108 // Check the output U pixels.
109 for (int i = 0; i < kWidth / 2; ++i) {
110 const uint8* p = &rgb[i * 2 * size];
111 SCOPED_TRACE(base::StringPrintf("r=%d,g=%d,b=%d", p[2], p[1], p[0]));
112 EXPECT_EQ(ConvertRGBToU(p, size, kSubsampling), u[i]);
113 }
114
115 // Check the output V pixels.
116 for (int i = 0; i < kWidth / 2; ++i) {
117 const uint8* p = &rgb[i * 2 * size];
118 SCOPED_TRACE(base::StringPrintf("r=%d,g=%d,b=%d", p[2], p[1], p[0]));
119 EXPECT_EQ(ConvertRGBToV(p, size, kSubsampling), v[i]);
120 }
121 }
122 }
123 }
124 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698