summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/media.gyp12
-rw-r--r--media/tools/scaler_bench/scaler_bench.cc205
2 files changed, 217 insertions, 0 deletions
diff --git a/media/media.gyp b/media/media.gyp
index 7190cf3..530cac5 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -252,6 +252,18 @@
],
},
{
+ 'target_name': 'scaler_bench',
+ 'type': 'executable',
+ 'dependencies': [
+ 'media',
+ '../base/base.gyp:base',
+ '../skia/skia.gyp:skia',
+ ],
+ 'sources': [
+ 'tools/scaler_bench/scaler_bench.cc',
+ ],
+ },
+ {
'target_name': 'ffmpeg_tests',
'type': 'executable',
'dependencies': [
diff --git a/media/tools/scaler_bench/scaler_bench.cc b/media/tools/scaler_bench/scaler_bench.cc
new file mode 100644
index 0000000..876b5e7
--- /dev/null
+++ b/media/tools/scaler_bench/scaler_bench.cc
@@ -0,0 +1,205 @@
+// 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 <time.h>
+#include <iostream>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/scoped_vector.h"
+#include "base/time.h"
+#include "skia/ext/platform_canvas.h"
+#include "media/base/yuv_convert.h"
+#include "media/base/video_frame.h"
+
+using std::vector;
+using base::TimeDelta;
+using media::VideoFrame;
+
+int source_width = 1280;
+int source_height = 720;
+int dest_width = 1600;
+int dest_height = 1000;
+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();
+
+ clock_t start = clock();
+
+ 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);
+ }
+
+ clock_t end = clock();
+ return static_cast<double>(end - start) * 1000.0 / num_frames /
+ CLOCKS_PER_SEC;
+}
+
+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);
+ }
+
+ clock_t start = clock();
+ 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);
+ }
+ clock_t end = clock();
+ return static_cast<double>(end - start) * 1000.0 / num_frames /
+ CLOCKS_PER_SEC;
+}
+
+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;
+}