summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/base/cpu_features.h18
-rw-r--r--media/base/cpu_features_arm.cc13
-rw-r--r--media/base/cpu_features_x86.cc54
-rw-r--r--media/base/yuv_convert.cc34
-rw-r--r--media/base/yuv_convert_c.cc24
-rw-r--r--media/base/yuv_convert_internal.h39
-rw-r--r--media/base/yuv_convert_sse2.cc25
-rw-r--r--media/media.gyp75
8 files changed, 243 insertions, 39 deletions
diff --git a/media/base/cpu_features.h b/media/base/cpu_features.h
new file mode 100644
index 0000000..c5bdcd7
--- /dev/null
+++ b/media/base/cpu_features.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2011 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 file provide utility functions to check CPU features such as SSE2,
+// NEON.
+
+#ifndef MEDIA_BASE_CPU_FEATURES_H_
+#define MEDIA_BASE_CPU_FEATURES_H_
+
+namespace media {
+
+// Returns true if CPU has SSE2 support.
+bool hasSSE2();
+
+} // namespace media
+
+#endif // MEDIA_BASE_CPU_FEATURES_H_
diff --git a/media/base/cpu_features_arm.cc b/media/base/cpu_features_arm.cc
new file mode 100644
index 0000000..e86fc97
--- /dev/null
+++ b/media/base/cpu_features_arm.cc
@@ -0,0 +1,13 @@
+// Copyright (c) 2011 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 "media/base/cpu_features.h"
+
+namespace media {
+
+bool hasSSE2() {
+ return false;
+}
+
+} // namespace media
diff --git a/media/base/cpu_features_x86.cc b/media/base/cpu_features_x86.cc
new file mode 100644
index 0000000..98dfba1
--- /dev/null
+++ b/media/base/cpu_features_x86.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2011 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.
+
+// Code in this file is taked from
+// third_party/skia/src/opts/opts_check_SSE2.cpp.
+
+// Note that this file cannot be compiled with -msse2 in gcc.
+
+#include "build/build_config.h"
+#include "media/base/cpu_features.h"
+
+namespace media {
+
+#if defined(ARCH_CPU_X86_64)
+/* All x86_64 machines have SSE2, so don't even bother checking. */
+bool hasSSE2() {
+ return true;
+}
+#else
+#ifdef _MSC_VER
+static inline void getcpuid(int info_type, int info[4]) {
+ __asm {
+ mov eax, [info_type]
+ cpuid
+ mov edi, [info]
+ mov [edi], eax
+ mov [edi+4], ebx
+ mov [edi+8], ecx
+ mov [edi+12], edx
+ }
+}
+#else
+static inline void getcpuid(int info_type, int info[4]) {
+ // We save and restore ebx, so this code can be compatible with -fPIC
+ asm volatile (
+ "pushl %%ebx \n\t"
+ "cpuid \n\t"
+ "movl %%ebx, %1 \n\t"
+ "popl %%ebx \n\t"
+ : "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
+ : "a"(info_type)
+ );
+}
+#endif
+
+bool hasSSE2() {
+ int cpu_info[4] = { 0 };
+ getcpuid(1, cpu_info);
+ return (cpu_info[3] & (1<<26)) != 0;
+}
+#endif
+
+} // namespace media
diff --git a/media/base/yuv_convert.cc b/media/base/yuv_convert.cc
index bea0e50..f6e2857 100644
--- a/media/base/yuv_convert.cc
+++ b/media/base/yuv_convert.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -17,7 +17,8 @@
#include "media/base/yuv_convert.h"
-// Header for low level row functions.
+#include "media/base/cpu_features.h"
+#include "media/base/yuv_convert_internal.h"
#include "media/base/yuv_row.h"
#if USE_MMX
@@ -343,4 +344,33 @@ void ScaleYUVToRGB32(const uint8* y_buf,
EMMS();
}
+void ConvertRGB32ToYUV(const uint8* rgbframe,
+ uint8* yplane,
+ uint8* uplane,
+ uint8* vplane,
+ int width,
+ int height,
+ int rgbstride,
+ int ystride,
+ int uvstride) {
+ static void (*convert_proc)(const uint8*, uint8*, uint8*, uint8*,
+ int, int, int, int, int) = NULL;
+ if (!convert_proc) {
+#ifdef __arm__
+ // For ARM processors, always use C version.
+ // TODO(hclam): Implement a NEON version.
+ convert_proc = &ConvertRGB32ToYUV_C;
+#else
+ // For x86 processors, check if SSE2 is supported.
+ if (hasSSE2())
+ convert_proc = &ConvertRGB32ToYUV_SSE2;
+ else
+ convert_proc = &ConvertRGB32ToYUV_C;
+#endif
+ }
+
+ convert_proc(rgbframe, yplane, uplane, vplane, width, height,
+ rgbstride, ystride, uvstride);
+}
+
} // namespace media
diff --git a/media/base/yuv_convert_c.cc b/media/base/yuv_convert_c.cc
index 1744a7a..986bf8e 100644
--- a/media/base/yuv_convert_c.cc
+++ b/media/base/yuv_convert_c.cc
@@ -3,9 +3,7 @@
// found in the LICENSE file.
#include "media/base/yuv_convert.h"
-#include "media/base/yuv_row.h"
-
-#if !USE_SSE2
+#include "media/base/yuv_convert_internal.h"
namespace media {
@@ -18,15 +16,15 @@ static int clip_byte(int x) {
return x;
}
-void ConvertRGB32ToYUV(const uint8* rgbframe,
- uint8* yplane,
- uint8* uplane,
- uint8* vplane,
- int width,
- int height,
- int rgbstride,
- int ystride,
- int uvstride) {
+void ConvertRGB32ToYUV_C(const uint8* rgbframe,
+ uint8* yplane,
+ uint8* uplane,
+ uint8* vplane,
+ int width,
+ int height,
+ int rgbstride,
+ int ystride,
+ int uvstride) {
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
// Since the input pixel format is RGB32, there are 4 bytes per pixel.
@@ -51,5 +49,3 @@ void ConvertRGB32ToYUV(const uint8* rgbframe,
}
} // namespace media
-
-#endif
diff --git a/media/base/yuv_convert_internal.h b/media/base/yuv_convert_internal.h
new file mode 100644
index 0000000..7a8ee34
--- /dev/null
+++ b/media/base/yuv_convert_internal.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2011 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 file defines the YUV conversion functions for each specific
+// optimization.
+
+#ifndef MEDIA_BASE_YUV_CONVERT_INTERNAL_H_
+#define MEDIA_BASE_YUV_CONVERT_INTERNAL_H_
+
+#include "base/basictypes.h"
+
+namespace media {
+
+// SSE2 version of converting RGBA to YV12.
+extern void ConvertRGB32ToYUV_SSE2(const uint8* rgbframe,
+ uint8* yplane,
+ uint8* uplane,
+ uint8* vplane,
+ int width,
+ int height,
+ int rgbstride,
+ int ystride,
+ int uvstride);
+
+// C version of converting RGBA to YV12.
+void ConvertRGB32ToYUV_C(const uint8* rgbframe,
+ uint8* yplane,
+ uint8* uplane,
+ uint8* vplane,
+ int width,
+ int height,
+ int rgbstride,
+ int ystride,
+ int uvstride);
+
+} // namespace media
+
+#endif // MEDIA_BASE_YUV_CONVERT_INTERNAL_H_
diff --git a/media/base/yuv_convert_sse2.cc b/media/base/yuv_convert_sse2.cc
index 02ee33c..e2c62f57 100644
--- a/media/base/yuv_convert_sse2.cc
+++ b/media/base/yuv_convert_sse2.cc
@@ -3,11 +3,9 @@
// found in the LICENSE file.
#include "media/base/yuv_convert.h"
+#include "media/base/yuv_convert_internal.h"
#include "media/base/yuv_row.h"
-// TODO(hclam): Perform runtime check to enable SSE2 routines.
-#if USE_SSE2
-
#if defined(_MSC_VER)
#include <intrin.h>
#else
@@ -162,16 +160,15 @@ void FastConvertRGB32ToYUVRow(const uint8* rgb_buf_1,
}
}
-// TODO(hclam): Add code to do runtime SSE2 detection.
-void ConvertRGB32ToYUV(const uint8* rgbframe,
- uint8* yplane,
- uint8* uplane,
- uint8* vplane,
- int width,
- int height,
- int rgbstride,
- int ystride,
- int uvstride) {
+extern void ConvertRGB32ToYUV_SSE2(const uint8* rgbframe,
+ uint8* yplane,
+ uint8* uplane,
+ uint8* vplane,
+ int width,
+ int height,
+ int rgbstride,
+ int ystride,
+ int uvstride) {
// Make sure |width| is a multiple of 2.
width = (width / 2) * 2;
for (int i = 0; i < height; i += 2) {
@@ -190,5 +187,3 @@ void ConvertRGB32ToYUV(const uint8* rgbframe,
}
} // namespace media
-
-#endif
diff --git a/media/media.gyp b/media/media.gyp
index f33d191..b2d8990 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -12,6 +12,7 @@
'target_name': 'media',
'type': '<(library)',
'dependencies': [
+ 'yuv_convert',
'../base/base.gyp:base',
'../third_party/ffmpeg/ffmpeg.gyp:ffmpeg',
],
@@ -113,14 +114,6 @@
'base/state_matrix.h',
'base/video_frame.cc',
'base/video_frame.h',
- 'base/yuv_convert.cc',
- 'base/yuv_convert.h',
- 'base/yuv_convert_c.cc',
- 'base/yuv_convert_sse2.cc',
- 'base/yuv_row_win.cc',
- 'base/yuv_row_posix.cc',
- 'base/yuv_row_table.cc',
- 'base/yuv_row.h',
'ffmpeg/ffmpeg_common.cc',
'ffmpeg/ffmpeg_common.h',
'ffmpeg/ffmpeg_util.cc',
@@ -224,6 +217,72 @@
],
},
{
+ 'target_name': 'cpu_features',
+ 'type': '<(library)',
+ 'include_dirs': [
+ '..',
+ ],
+ 'conditions': [
+ [ 'target_arch == "ia32" or target_arch == "x64"', {
+ 'sources': [
+ 'base/cpu_features_x86.cc',
+ ],
+ }],
+ [ 'target_arch == "arm"', {
+ 'sources': [
+ 'base/cpu_features_arm.cc',
+ ],
+ }],
+ ],
+ 'sources': [
+ 'base/cpu_features.h',
+ ],
+ },
+ {
+ 'target_name': 'yuv_convert',
+ 'type': '<(library)',
+ 'include_dirs': [
+ '..',
+ ],
+ 'dependencies': [
+ 'cpu_features',
+ ],
+ 'conditions': [
+ [ 'target_arch == "ia32" or target_arch == "x64"', {
+ 'dependencies': [
+ 'yuv_convert_sse2',
+ ],
+ }],
+ ],
+ 'sources': [
+ 'base/yuv_convert.cc',
+ 'base/yuv_convert.h',
+ 'base/yuv_convert_internal.h',
+ 'base/yuv_convert_c.cc',
+ 'base/yuv_row_win.cc',
+ 'base/yuv_row_posix.cc',
+ 'base/yuv_row_table.cc',
+ 'base/yuv_row.h',
+ ],
+ },
+ {
+ 'target_name': 'yuv_convert_sse2',
+ 'type': '<(library)',
+ 'include_dirs': [
+ '..',
+ ],
+ 'conditions': [
+ [ 'OS == "linux" or OS == "freebsd" or OS == "openbsd"', {
+ 'cflags': [
+ '-msse2',
+ ],
+ }],
+ ],
+ 'sources': [
+ 'base/yuv_convert_sse2.cc',
+ ],
+ },
+ {
'target_name': 'ffmpeg_unittests',
'type': 'executable',
'dependencies': [