| Index: media/tools/scaler_bench/scaler_bench.cc
|
| diff --git a/media/tools/scaler_bench/scaler_bench.cc b/media/tools/scaler_bench/scaler_bench.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a50efa042c43205a03f56bfc310c890736b89b99
|
| --- /dev/null
|
| +++ b/media/tools/scaler_bench/scaler_bench.cc
|
| @@ -0,0 +1,207 @@
|
| +// Copyright (c) 2010 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 tool can be used to measure performace of video frame scaling
|
| +// code. It times performance of the scaler with and without filtering.
|
| +// It also measures performance of the Skia scaler for comparison.
|
| +
|
| +#include <iostream>
|
| +#include <vector>
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/scoped_vector.h"
|
| +#include "base/time.h"
|
| +#include "media/base/video_frame.h"
|
| +#include "media/base/yuv_convert.h"
|
| +#include "skia/ext/platform_canvas.h"
|
| +
|
| +using base::TimeDelta;
|
| +using base::TimeTicks;
|
| +using media::VideoFrame;
|
| +using std::vector;
|
| +
|
| +namespace {
|
| +
|
| +int source_width = 1280;
|
| +int source_height = 720;
|
| +int dest_width = 1366;
|
| +int dest_height = 768;
|
| +int num_frames = 500;
|
| +int num_buffers = 50;
|
| +
|
| +double BenchmarkSkia() {
|
| + vector< scoped_refptr<VideoFrame> > source_frames;
|
| + ScopedVector<SkBitmap> dest_frames;
|
| + for (int i = 0; i < num_buffers; i++) {
|
| + scoped_refptr<VideoFrame> source_frame;
|
| + VideoFrame::CreateBlackFrame(source_width, source_height, &source_frame);
|
| + source_frames.push_back(source_frame);
|
| +
|
| + SkBitmap* bitmap = new SkBitmap();
|
| + bitmap->setConfig(SkBitmap::kARGB_8888_Config,
|
| + dest_width, dest_height);
|
| + bitmap->allocPixels();
|
| + dest_frames.push_back(bitmap);
|
| + }
|
| +
|
| + SkBitmap bitmap;
|
| + bitmap.setConfig(SkBitmap::kARGB_8888_Config, source_width, source_height);
|
| + bitmap.allocPixels();
|
| +
|
| + TimeTicks start = TimeTicks::HighResNow();
|
| + for (int i = 0; i < num_frames; i++) {
|
| + scoped_refptr<VideoFrame> source_frame = source_frames[i % num_buffers];
|
| + SkBitmap* dest_bitmap = dest_frames[i % num_buffers];
|
| +
|
| + bitmap.lockPixels();
|
| + media::ConvertYUVToRGB32(source_frame->data(VideoFrame::kYPlane),
|
| + source_frame->data(VideoFrame::kUPlane),
|
| + source_frame->data(VideoFrame::kVPlane),
|
| + static_cast<uint8*>(bitmap.getPixels()),
|
| + source_width,
|
| + source_height,
|
| + source_frame->stride(VideoFrame::kYPlane),
|
| + source_frame->stride(VideoFrame::kUPlane),
|
| + bitmap.rowBytes(),
|
| + media::YV12);
|
| + bitmap.unlockPixels();
|
| +
|
| + SkCanvas canvas(*dest_bitmap);
|
| + SkRect rect;
|
| + rect.set(0, 0, SkIntToScalar(dest_width),
|
| + SkIntToScalar(dest_height));
|
| + canvas.clipRect(rect);
|
| + SkMatrix matrix;
|
| + matrix.reset();
|
| + matrix.preScale(SkIntToScalar(dest_width) /
|
| + SkIntToScalar(source_width),
|
| + SkIntToScalar(dest_height) /
|
| + SkIntToScalar(source_height));
|
| + SkPaint paint;
|
| + paint.setFlags(SkPaint::kFilterBitmap_Flag);
|
| + canvas.drawBitmapMatrix(bitmap, matrix, &paint);
|
| + }
|
| + TimeTicks end = TimeTicks::HighResNow();
|
| + return static_cast<double>((end - start).InMilliseconds()) / num_frames;
|
| +}
|
| +
|
| +double BenchmarkFilter(media::ScaleFilter filter) {
|
| + vector< scoped_refptr<VideoFrame> > source_frames;
|
| + vector< scoped_refptr<VideoFrame> > dest_frames;
|
| +
|
| + for (int i = 0; i < num_buffers; i++) {
|
| + scoped_refptr<VideoFrame> source_frame;
|
| + VideoFrame::CreateBlackFrame(source_width, source_height, &source_frame);
|
| + source_frames.push_back(source_frame);
|
| +
|
| + scoped_refptr<VideoFrame> dest_frame;
|
| + VideoFrame::CreateFrame(VideoFrame::RGB32,
|
| + dest_width,
|
| + dest_height,
|
| + TimeDelta::FromSeconds(0),
|
| + TimeDelta::FromSeconds(0),
|
| + &dest_frame);
|
| + dest_frames.push_back(dest_frame);
|
| + }
|
| +
|
| + 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::ScaleYUVToRGB32(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,
|
| + source_frame->stride(VideoFrame::kYPlane),
|
| + source_frame->stride(VideoFrame::kUPlane),
|
| + dest_frame->stride(0),
|
| + media::YV12,
|
| + media::ROTATE_0,
|
| + filter);
|
| + }
|
| + TimeTicks end = TimeTicks::HighResNow();
|
| + return static_cast<double>((end - start).InMilliseconds()) / num_frames;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +int main(int argc, const char** argv) {
|
| + CommandLine::Init(argc, argv);
|
| + const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
|
| +
|
| + if (!cmd_line->GetLooseValues().empty()) {
|
| + std::cerr << "Usage: " << argv[0] << " [OPTIONS]\n"
|
| + << " --frames=N "
|
| + << "Number of frames\n"
|
| + << " --buffers=N "
|
| + << "Number of buffers\n"
|
| + << " --src-w=N "
|
| + << "Width of the source image\n"
|
| + << " --src-h=N "
|
| + << "Height of the source image\n"
|
| + << " --dest-w=N "
|
| + << "Width of the destination image\n"
|
| + << " --dest-h=N "
|
| + << "Height of the destination image\n"
|
| + << std::endl;
|
| + return 1;
|
| + }
|
| +
|
| + std::string source_width_param(cmd_line->GetSwitchValueASCII("src-w"));
|
| + if (!source_width_param.empty() &&
|
| + !StringToInt(source_width_param, &source_width)) {
|
| + source_width = 0;
|
| + }
|
| +
|
| + std::string source_height_param(cmd_line->GetSwitchValueASCII("src-h"));
|
| + if (!source_height_param.empty() &&
|
| + !StringToInt(source_height_param, &source_height)) {
|
| + source_height = 0;
|
| + }
|
| +
|
| + std::string dest_width_param(cmd_line->GetSwitchValueASCII("dst-w"));
|
| + if (!dest_width_param.empty() &&
|
| + !StringToInt(dest_width_param, &dest_width)) {
|
| + dest_width = 0;
|
| + }
|
| +
|
| + std::string dest_height_param(cmd_line->GetSwitchValueASCII("dst-h"));
|
| + if (!dest_height_param.empty() &&
|
| + !StringToInt(dest_height_param, &dest_height)) {
|
| + dest_height = 0;
|
| + }
|
| +
|
| + std::string frames_param(cmd_line->GetSwitchValueASCII("frames"));
|
| + if (!frames_param.empty() &&
|
| + !StringToInt(frames_param, &num_frames)) {
|
| + num_frames = 0;
|
| + }
|
| +
|
| + std::string buffers_param(cmd_line->GetSwitchValueASCII("buffers"));
|
| + if (!buffers_param.empty() &&
|
| + !StringToInt(buffers_param, &num_buffers)) {
|
| + num_buffers = 0;
|
| + }
|
| +
|
| + std::cout << "Source image size: " << source_width
|
| + << "x" << source_height << std::endl;
|
| + std::cout << "Destination image size: " << dest_width
|
| + << "x" << dest_height << std::endl;
|
| + std::cout << "Number of frames: " << num_frames << std::endl;
|
| + std::cout << "Number of buffers: " << num_buffers << std::endl;
|
| +
|
| + std::cout << "Skia: " << BenchmarkSkia()
|
| + << "ms/frame" << std::endl;
|
| + std::cout << "No filtering: " << BenchmarkFilter(media::FILTER_NONE)
|
| + << "ms/frame" << std::endl;
|
| + std::cout << "Bilinear: " << BenchmarkFilter(media::FILTER_BILINEAR)
|
| + << "ms/frame" << std::endl;
|
| +
|
| + return 0;
|
| +}
|
|
|