summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-21 23:18:32 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-21 23:18:32 +0000
commitc0be5bcff5e3590335cf24926f612b3dc3777626 (patch)
tree5ace67041b8f76f0de1a0a1fd3fce9d84be571f1
parent16831246b6d9863fc128008230715ee6ba5d4a91 (diff)
downloadchromium_src-c0be5bcff5e3590335cf24926f612b3dc3777626.zip
chromium_src-c0be5bcff5e3590335cf24926f612b3dc3777626.tar.gz
chromium_src-c0be5bcff5e3590335cf24926f612b3dc3777626.tar.bz2
Merge 117748 - Linear sub-rectangle scaler for use in Chromoting.
This implementation re-uses the common row filter procedures, but is currently limited to a C horizontal interpolation procedure. There's also plenty of scope for optimizing the new sub-rectangle scaler routine. BUG=93451 TEST=media_unittests, remoting_unittests and manual verification of image quality of Chromoting sessions using fit-to-screen. Review URL: http://codereview.chromium.org/8954003 TBR=wez@chromium.org Review URL: https://chromiumcodereview.appspot.com/9142004 git-svn-id: svn://svn.chromium.org/chrome/branches/963/src@118629 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--media/base/simd/convert_yuv_to_rgb.h10
-rw-r--r--media/base/simd/convert_yuv_to_rgb_c.cc51
-rw-r--r--media/base/yuv_convert.cc154
-rw-r--r--media/base/yuv_convert.h21
-rw-r--r--media/base/yuv_convert_unittest.cc78
-rw-r--r--media/tools/scaler_bench/scaler_bench.cc45
-rw-r--r--remoting/base/decoder_vp8.cc26
-rw-r--r--remoting/base/util.cc35
8 files changed, 352 insertions, 68 deletions
diff --git a/media/base/simd/convert_yuv_to_rgb.h b/media/base/simd/convert_yuv_to_rgb.h
index ff7d8ec..164ad11 100644
--- a/media/base/simd/convert_yuv_to_rgb.h
+++ b/media/base/simd/convert_yuv_to_rgb.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -124,6 +124,14 @@ void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
int width,
int source_dx);
+void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
+ const uint8* u_buf,
+ const uint8* v_buf,
+ uint8* rgb_buf,
+ int dest_width,
+ int source_x,
+ int source_dx);
+
void LinearScaleYUVToRGB32Row_MMX(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
diff --git a/media/base/simd/convert_yuv_to_rgb_c.cc b/media/base/simd/convert_yuv_to_rgb_c.cc
index c403984..abd7bfc 100644
--- a/media/base/simd/convert_yuv_to_rgb_c.cc
+++ b/media/base/simd/convert_yuv_to_rgb_c.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -9,11 +9,10 @@
#define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \
(((x) + (y)) > 32767 ? 32767 : ((x) + (y))))
-static inline void YUVPixel(uint8 y,
- uint8 u,
- uint8 v,
- uint8* rgb_buf) {
-
+static inline void ConvertYUVToRGB32_C(uint8 y,
+ uint8 u,
+ uint8 v,
+ uint8* rgb_buf) {
int b = kCoefficientsRgbY[256+u][0];
int g = kCoefficientsRgbY[256+u][1];
int r = kCoefficientsRgbY[256+u][2];
@@ -40,6 +39,11 @@ static inline void YUVPixel(uint8 y,
(packuswb(a) << 24);
}
+// 16.16 fixed point arithmetic
+const int kFractionBits = 16;
+const int kFractionMax = 1 << kFractionBits;
+const int kFractionMask = ((1 << kFractionBits) - 1);
+
extern "C" {
void ConvertYUVToRGB32Row_C(const uint8* y_buf,
@@ -51,10 +55,10 @@ void ConvertYUVToRGB32Row_C(const uint8* y_buf,
uint8 u = u_buf[x >> 1];
uint8 v = v_buf[x >> 1];
uint8 y0 = y_buf[x];
- YUVPixel(y0, u, v, rgb_buf);
+ ConvertYUVToRGB32_C(y0, u, v, rgb_buf);
if ((x + 1) < width) {
uint8 y1 = y_buf[x + 1];
- YUVPixel(y1, u, v, rgb_buf + 4);
+ ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4);
}
rgb_buf += 8; // Advance 2 pixels.
}
@@ -75,11 +79,11 @@ void ScaleYUVToRGB32Row_C(const uint8* y_buf,
int y = y_buf[x >> 16];
int u = u_buf[(x >> 17)];
int v = v_buf[(x >> 17)];
- YUVPixel(y, u, v, rgb_buf);
+ ConvertYUVToRGB32_C(y, u, v, rgb_buf);
x += source_dx;
if ((i + 1) < width) {
y = y_buf[x >> 16];
- YUVPixel(y, u, v, rgb_buf+4);
+ ConvertYUVToRGB32_C(y, u, v, rgb_buf+4);
x += source_dx;
}
rgb_buf += 8;
@@ -92,11 +96,22 @@ void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
uint8* rgb_buf,
int width,
int source_dx) {
- int x = 0;
- if (source_dx >= 0x20000) {
- x = 32768;
- }
- for (int i = 0; i < width; i += 2) {
+ // Avoid point-sampling for down-scaling by > 2:1.
+ int source_x = 0;
+ if (source_dx >= 0x20000)
+ source_x += 0x8000;
+ LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width,
+ source_x, source_dx);
+}
+
+void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
+ const uint8* u_buf,
+ const uint8* v_buf,
+ uint8* rgb_buf,
+ int dest_width,
+ int x,
+ int source_dx) {
+ for (int i = 0; i < dest_width; i += 2) {
int y0 = y_buf[x >> 16];
int y1 = y_buf[(x >> 16) + 1];
int u0 = u_buf[(x >> 17)];
@@ -108,14 +123,14 @@ void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16;
int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16;
- YUVPixel(y, u, v, rgb_buf);
+ ConvertYUVToRGB32_C(y, u, v, rgb_buf);
x += source_dx;
- if ((i + 1) < width) {
+ if ((i + 1) < dest_width) {
y0 = y_buf[x >> 16];
y1 = y_buf[(x >> 16) + 1];
y_frac = (x & 65535);
y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
- YUVPixel(y, u, v, rgb_buf+4);
+ ConvertYUVToRGB32_C(y, u, v, rgb_buf+4);
x += source_dx;
}
rgb_buf += 8;
diff --git a/media/base/yuv_convert.cc b/media/base/yuv_convert.cc
index 93af853..8d5073b 100644
--- a/media/base/yuv_convert.cc
+++ b/media/base/yuv_convert.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -18,6 +18,7 @@
#include "media/base/yuv_convert.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "media/base/cpu_features.h"
#include "media/base/simd/convert_rgb_to_yuv.h"
@@ -277,6 +278,157 @@ void ScaleYUVToRGB32(const uint8* y_buf,
EmptyRegisterState();
}
+// Scale a frame of YV12 to 32 bit ARGB for a specific rectangle.
+void ScaleYUVToRGB32WithRect(const uint8* y_buf,
+ const uint8* u_buf,
+ const uint8* v_buf,
+ uint8* rgb_buf,
+ int source_width,
+ int source_height,
+ int dest_width,
+ int dest_height,
+ int dest_rect_left,
+ int dest_rect_top,
+ int dest_rect_right,
+ int dest_rect_bottom,
+ int y_pitch,
+ int uv_pitch,
+ int rgb_pitch) {
+ static FilterYUVRowsProc filter_proc = NULL;
+ if (!filter_proc)
+ filter_proc = ChooseFilterYUVRowsProc();
+
+ // This routine doesn't currently support up-scaling.
+ CHECK(dest_width <= source_width && dest_height <= source_height);
+
+ // Sanity-check the destination rectangle.
+ DCHECK(dest_rect_left >= 0 && dest_rect_right <= dest_width);
+ DCHECK(dest_rect_top >= 0 && dest_rect_bottom <= dest_height);
+ DCHECK(dest_rect_right > dest_rect_left);
+ DCHECK(dest_rect_bottom > dest_rect_top);
+
+ // Fixed-point value of vertical and horizontal scale down factor.
+ // Values are in the format 16.16.
+ int y_step = kFractionMax * source_height / dest_height;
+ int x_step = kFractionMax * source_width / dest_width;
+
+ // Determine the coordinates of the rectangle in 16.16 coords.
+ // NB: Our origin is the *center* of the top/left pixel, NOT its top/left.
+ // If we're down-scaling by more than a factor of two, we start with a 50%
+ // fraction to avoid degenerating to point-sampling - we should really just
+ // fix the fraction at 50% for all pixels in that case.
+ int source_left = dest_rect_left * x_step;
+ int source_right = (dest_rect_right - 1) * x_step;
+ if (x_step < kFractionMax * 2) {
+ source_left += ((x_step - kFractionMax) / 2);
+ source_right += ((x_step - kFractionMax) / 2);
+ } else {
+ source_left += kFractionMax / 2;
+ source_right += kFractionMax / 2;
+ }
+ int source_top = dest_rect_top * y_step;
+ if (y_step < kFractionMax * 2) {
+ source_top += ((y_step - kFractionMax) / 2);
+ } else {
+ source_top += kFractionMax / 2;
+ }
+
+ // Determine the parts of the Y, U and V buffers to interpolate.
+ int source_y_left = source_left >> kFractionBits;
+ int source_y_right = (source_right >> kFractionBits) + 2;
+ DCHECK(source_y_right <= source_width);
+
+ int source_uv_left = source_y_left / 2;
+ int source_uv_right = std::min(
+ (source_right >> (kFractionBits + 1)) + 2,
+ (source_width + 1) / 2);
+
+ int source_y_width = source_y_right - source_y_left;
+ int source_uv_width = source_uv_right - source_uv_left;
+
+ // Determine number of pixels in each output row.
+ int dest_rect_width = dest_rect_right - dest_rect_left;
+
+ // Intermediate buffer for vertical interpolation.
+ // 4096 bytes allows 3 buffers to fit in 12k, which fits in a 16K L1 cache,
+ // and is bigger than most users will generally need.
+ // The buffer is 16-byte aligned and padded with 16 extra bytes; some of the
+ // FilterYUVRowProcs have alignment requirements, and the SSE version can
+ // write up to 16 bytes past the end of the buffer.
+ const int kFilterBufferSize = 4096;
+ if (source_width > kFilterBufferSize)
+ filter_proc = NULL;
+ uint8 yuv_temp[16 + kFilterBufferSize * 3 + 16];
+ uint8* y_temp =
+ reinterpret_cast<uint8*>(
+ reinterpret_cast<uintptr_t>(yuv_temp + 15) & ~15);
+ uint8* u_temp = y_temp + kFilterBufferSize;
+ uint8* v_temp = u_temp + kFilterBufferSize;
+
+ // Move to the top-left pixel of output.
+ rgb_buf += dest_rect_top * rgb_pitch;
+ rgb_buf += dest_rect_left * 4;
+
+ // For each destination row perform interpolation and color space
+ // conversion to produce the output.
+ for (int row = dest_rect_top; row < dest_rect_bottom; ++row) {
+ // Round the fixed-point y position to get the current row.
+ int source_row = source_top >> kFractionBits;
+ int source_uv_row = source_row / 2;
+ DCHECK(source_row < source_height);
+
+ // Locate the first row for each plane for interpolation.
+ const uint8* y0_ptr = y_buf + y_pitch * source_row + source_y_left;
+ const uint8* u0_ptr = u_buf + uv_pitch * source_uv_row + source_uv_left;
+ const uint8* v0_ptr = v_buf + uv_pitch * source_uv_row + source_uv_left;
+ const uint8* y1_ptr = NULL;
+ const uint8* u1_ptr = NULL;
+ const uint8* v1_ptr = NULL;
+
+ // Locate the second row for interpolation, being careful not to overrun.
+ if (source_row + 1 >= source_height) {
+ y1_ptr = y0_ptr;
+ } else {
+ y1_ptr = y0_ptr + y_pitch;
+ }
+ if (source_uv_row + 1 >= (source_height + 1) / 2) {
+ u1_ptr = u0_ptr;
+ v1_ptr = v0_ptr;
+ } else {
+ u1_ptr = u0_ptr + uv_pitch;
+ v1_ptr = v0_ptr + uv_pitch;
+ }
+
+ if (filter_proc) {
+ // Vertical scaler uses 16.8 fixed point.
+ int fraction = (source_top & kFractionMask) >> 8;
+ filter_proc(y_temp + source_y_left, y0_ptr, y1_ptr,
+ source_y_width, fraction);
+ filter_proc(u_temp + source_uv_left, u0_ptr, u1_ptr,
+ source_uv_width, fraction);
+ filter_proc(v_temp + source_uv_left, v0_ptr, v1_ptr,
+ source_uv_width, fraction);
+
+ // Perform horizontal interpolation and color space conversion.
+ // TODO(hclam): Use the MMX version after more testing.
+ LinearScaleYUVToRGB32RowWithRange_C(
+ y_temp, u_temp, v_temp, rgb_buf,
+ dest_rect_width, source_left, x_step);
+ } else {
+ // If the frame is too large then we linear scale a single row.
+ LinearScaleYUVToRGB32RowWithRange_C(
+ y0_ptr, u0_ptr, v0_ptr, rgb_buf,
+ dest_rect_width, source_left, x_step);
+ }
+
+ // Advance vertically in the source and destination image.
+ source_top += y_step;
+ rgb_buf += rgb_pitch;
+ }
+
+ EmptyRegisterState();
+}
+
void ConvertRGB32ToYUV(const uint8* rgbframe,
uint8* yplane,
uint8* uplane,
diff --git a/media/base/yuv_convert.h b/media/base/yuv_convert.h
index 95b1780..aa1e3dc 100644
--- a/media/base/yuv_convert.h
+++ b/media/base/yuv_convert.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -67,6 +67,25 @@ void ScaleYUVToRGB32(const uint8* yplane,
Rotate view_rotate,
ScaleFilter filter);
+// Biliner Scale a frame of YV12 to 32 bits ARGB on a specified rectangle.
+// |yplane|, etc and |rgbframe| should point to the top-left pixels of the
+// source and destination buffers.
+void ScaleYUVToRGB32WithRect(const uint8* yplane,
+ const uint8* uplane,
+ const uint8* vplane,
+ uint8* rgbframe,
+ int source_width,
+ int source_height,
+ int dest_width,
+ int dest_height,
+ int dest_rect_left,
+ int dest_rect_top,
+ int dest_rect_right,
+ int dest_rect_bottom,
+ int ystride,
+ int uvstride,
+ int rgbstride);
+
void ConvertRGB32ToYUV(const uint8* rgbframe,
uint8* yplane,
uint8* uplane,
diff --git a/media/base/yuv_convert_unittest.cc b/media/base/yuv_convert_unittest.cc
index 9db998b..3a74bb2 100644
--- a/media/base/yuv_convert_unittest.cc
+++ b/media/base/yuv_convert_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -13,6 +13,7 @@
#include "media/base/simd/filter_yuv.h"
#include "media/base/yuv_convert.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/rect.h"
// Size of raw image.
static const int kSourceWidth = 640;
@@ -22,6 +23,8 @@ static const int kSourceUOffset = kSourceYSize;
static const int kSourceVOffset = kSourceYSize * 5 / 4;
static const int kScaledWidth = 1024;
static const int kScaledHeight = 768;
+static const int kDownScaledWidth = 512;
+static const int kDownScaledHeight = 320;
static const int kBpp = 4;
// Surface sizes for various test files.
@@ -379,6 +382,79 @@ TEST(YUVConvertTest, YUY2ToYUV) {
EXPECT_EQ(666823187u, yuy_hash);
}
+TEST(YUVConvertTest, DownScaleYUVToRGB32WithRect) {
+ // Read YUV reference data from file.
+ FilePath yuv_url;
+ EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &yuv_url));
+ yuv_url = yuv_url.Append(FILE_PATH_LITERAL("media"))
+ .Append(FILE_PATH_LITERAL("test"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .Append(FILE_PATH_LITERAL("bali_640x360_P420.yuv"));
+ const size_t size_of_yuv = kSourceYSize * 12 / 8; // 12 bpp.
+ scoped_array<uint8> yuv_bytes(new uint8[size_of_yuv]);
+ EXPECT_EQ(static_cast<int>(size_of_yuv),
+ file_util::ReadFile(yuv_url,
+ reinterpret_cast<char*>(yuv_bytes.get()),
+ static_cast<int>(size_of_yuv)));
+
+ // Scale the full frame of YUV to 32 bit ARGB.
+ // The API currently only supports down-scaling, so we don't test up-scaling.
+ const size_t size_of_rgb_scaled = kDownScaledWidth * kDownScaledHeight * kBpp;
+ scoped_array<uint8> rgb_scaled_bytes(new uint8[size_of_rgb_scaled]);
+ gfx::Rect sub_rect(0, 0, kDownScaledWidth, kDownScaledHeight);
+
+ // We can't compare with the full-frame scaler because it uses slightly
+ // different sampling coordinates.
+ media::ScaleYUVToRGB32WithRect(
+ yuv_bytes.get(), // Y
+ yuv_bytes.get() + kSourceUOffset, // U
+ yuv_bytes.get() + kSourceVOffset, // V
+ rgb_scaled_bytes.get(), // Rgb output
+ kSourceWidth, kSourceHeight, // Dimensions
+ kDownScaledWidth, kDownScaledHeight, // Dimensions
+ sub_rect.x(), sub_rect.y(), // Dest rect
+ sub_rect.right(), sub_rect.bottom(), // Dest rect
+ kSourceWidth, // YStride
+ kSourceWidth / 2, // UvStride
+ kDownScaledWidth * kBpp); // RgbStride
+
+ uint32 rgb_hash_full_rect = DJB2Hash(rgb_scaled_bytes.get(),
+ size_of_rgb_scaled,
+ kDJB2HashSeed);
+
+ // Re-scale sub-rectangles and verify the results are the same.
+ int next_sub_rect = 0;
+ while (!sub_rect.IsEmpty()) {
+ // Scale a partial rectangle.
+ media::ScaleYUVToRGB32WithRect(
+ yuv_bytes.get(), // Y
+ yuv_bytes.get() + kSourceUOffset, // U
+ yuv_bytes.get() + kSourceVOffset, // V
+ rgb_scaled_bytes.get(), // Rgb output
+ kSourceWidth, kSourceHeight, // Dimensions
+ kDownScaledWidth, kDownScaledHeight, // Dimensions
+ sub_rect.x(), sub_rect.y(), // Dest rect
+ sub_rect.right(), sub_rect.bottom(), // Dest rect
+ kSourceWidth, // YStride
+ kSourceWidth / 2, // UvStride
+ kDownScaledWidth * kBpp); // RgbStride
+ uint32 rgb_hash_sub_rect = DJB2Hash(rgb_scaled_bytes.get(),
+ size_of_rgb_scaled,
+ kDJB2HashSeed);
+
+ EXPECT_EQ(rgb_hash_full_rect, rgb_hash_sub_rect);
+
+ // Now pick choose a quarter rect of this sub-rect.
+ if (next_sub_rect & 1)
+ sub_rect.set_x(sub_rect.x() + sub_rect.width() / 2);
+ if (next_sub_rect & 2)
+ sub_rect.set_y(sub_rect.y() + sub_rect.height() / 2);
+ sub_rect.set_width(sub_rect.width() / 2);
+ sub_rect.set_height(sub_rect.height() / 2);
+ next_sub_rect++;
+ }
+}
+
#if !defined(ARCH_CPU_ARM_FAMILY)
TEST(YUVConvertTest, RGB32ToYUV_SSE2_MatchReference) {
if (!media::hasSSE2()) {
diff --git a/media/tools/scaler_bench/scaler_bench.cc b/media/tools/scaler_bench/scaler_bench.cc
index aa8e227..0aa0531 100644
--- a/media/tools/scaler_bench/scaler_bench.cc
+++ b/media/tools/scaler_bench/scaler_bench.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -152,6 +152,47 @@ static double BenchmarkFilter(media::ScaleFilter filter) {
return static_cast<double>((end - start).InMilliseconds()) / num_frames;
}
+static double BenchmarkScaleWithRect() {
+ std::vector<scoped_refptr<VideoFrame> > source_frames;
+ std::vector<scoped_refptr<VideoFrame> > dest_frames;
+
+ for (int i = 0; i < num_buffers; i++) {
+ source_frames.push_back(
+ VideoFrame::CreateBlackFrame(source_width, source_height));
+
+ dest_frames.push_back(
+ VideoFrame::CreateFrame(VideoFrame::RGB32,
+ dest_width,
+ dest_height,
+ TimeDelta::FromSeconds(0),
+ TimeDelta::FromSeconds(0)));
+ }
+
+ TimeTicks start = TimeTicks::HighResNow();
+ for (int i = 0; i < num_frames; i++) {
+ scoped_refptr<VideoFrame> source_frame = source_frames[i % num_buffers];
+ scoped_refptr<VideoFrame> dest_frame = dest_frames[i % num_buffers];
+
+ media::ScaleYUVToRGB32WithRect(
+ source_frame->data(VideoFrame::kYPlane),
+ source_frame->data(VideoFrame::kUPlane),
+ source_frame->data(VideoFrame::kVPlane),
+ dest_frame->data(0),
+ source_width,
+ source_height,
+ dest_width,
+ dest_height,
+ 0, 0,
+ dest_width,
+ dest_height,
+ source_frame->stride(VideoFrame::kYPlane),
+ source_frame->stride(VideoFrame::kUPlane),
+ dest_frame->stride(0));
+ }
+ TimeTicks end = TimeTicks::HighResNow();
+ return static_cast<double>((end - start).InMilliseconds()) / num_frames;
+}
+
int main(int argc, const char** argv) {
CommandLine::Init(argc, argv);
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
@@ -231,6 +272,8 @@ int main(int argc, const char** argv) {
<< "ms/frame" << std::endl;
std::cout << "Bilinear: " << BenchmarkFilter(media::FILTER_BILINEAR)
<< "ms/frame" << std::endl;
+ std::cout << "Bilinear with rect: " << BenchmarkScaleWithRect()
+ << "ms/frame" << std::endl;
return 0;
}
diff --git a/remoting/base/decoder_vp8.cc b/remoting/base/decoder_vp8.cc
index 8c8a205..869b32e9 100644
--- a/remoting/base/decoder_vp8.cc
+++ b/remoting/base/decoder_vp8.cc
@@ -230,16 +230,22 @@ void DecoderVp8::ScaleAndConvertRects(const RectVector& input_rects,
if (!output_rect.intersect(clip_rect))
continue;
- // The scaler will not read outside the input dimensions.
- ScaleYUVToRGB32WithRect(last_image_->planes[0],
- last_image_->planes[1],
- last_image_->planes[2],
- output_rgb_buf,
- input_rects[i],
- output_rect,
- last_image_->stride[0],
- last_image_->stride[1],
- output_stride);
+ // The scaler will not to read outside the input dimensions.
+ media::ScaleYUVToRGB32WithRect(last_image_->planes[0],
+ last_image_->planes[1],
+ last_image_->planes[2],
+ output_rgb_buf,
+ input_width,
+ input_height,
+ output_width,
+ output_height,
+ output_rect.x(),
+ output_rect.y(),
+ output_rect.right(),
+ output_rect.bottom(),
+ last_image_->stride[0],
+ last_image_->stride[1],
+ output_stride);
output_rects->push_back(output_rect);
}
}
diff --git a/remoting/base/util.cc b/remoting/base/util.cc
index 23af0ea..0bda6b1 100644
--- a/remoting/base/util.cc
+++ b/remoting/base/util.cc
@@ -77,41 +77,6 @@ void ConvertYUVToRGB32WithRect(const uint8* y_plane,
media::YV12);
}
-void ScaleYUVToRGB32WithRect(const uint8* y_plane,
- const uint8* u_plane,
- const uint8* v_plane,
- uint8* rgb_plane,
- const SkIRect& source_rect,
- const SkIRect& dest_rect,
- int y_stride,
- int uv_stride,
- int rgb_stride) {
- int rgb_offset = CalculateRGBOffset(dest_rect.fLeft,
- dest_rect.fTop,
- rgb_stride);
- int y_offset = CalculateYOffset(source_rect.fLeft,
- source_rect.fTop,
- y_stride);
- int uv_offset = CalculateUVOffset(source_rect.fLeft,
- source_rect.fTop,
- uv_stride);
-
- media::ScaleYUVToRGB32(y_plane + y_offset,
- u_plane + uv_offset,
- v_plane + uv_offset,
- rgb_plane + rgb_offset,
- source_rect.width(),
- source_rect.height(),
- dest_rect.width(),
- dest_rect.height(),
- y_stride,
- uv_stride,
- rgb_stride,
- media::YV12,
- media::ROTATE_0,
- media::FILTER_NONE);
-}
-
void ConvertRGB32ToYUVWithRect(const uint8* rgb_plane,
uint8* y_plane,
uint8* u_plane,