This commit is contained in:
Mike Jerris 2016-09-27 13:08:00 -04:00
parent d6bf6705de
commit 93591e2f47
93 changed files with 3194 additions and 2023 deletions

View File

@ -53,6 +53,12 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
source/scale_neon.cc.neon
endif
ifeq ($(TARGET_ARCH_ABI),mips)
LOCAL_CFLAGS += -DLIBYUV_MSA
LOCAL_SRC_FILES += \
source/row_msa.cc
endif
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include

View File

@ -6,19 +6,20 @@
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
import("//build/config/arm.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("libyuv.gni")
import("//testing/test.gni")
config("libyuv_config") {
include_dirs = [
".",
"include",
]
include_dirs = [ "include" ]
if (is_android && current_cpu=="arm64") {
ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64" ]
}
if (is_android && current_cpu != "arm64") {
ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker" ]
}
}
use_neon = current_cpu == "arm64" || (current_cpu == "arm" && (arm_use_neon || arm_optionally_use_neon))
source_set("libyuv") {
static_library("libyuv") {
sources = [
# Headers
"include/libyuv.h",
@ -79,31 +80,24 @@ source_set("libyuv") {
"source/video_common.cc",
]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
public_configs = [ ":libyuv_config" ]
defines = []
deps = []
if (!is_ios) {
defines += [ "HAVE_JPEG" ]
deps += [ "//third_party:jpeg" ]
}
if (is_msan) {
# MemorySanitizer does not support assembly code yet.
# http://crbug.com/344505
defines += [ "LIBYUV_DISABLE_X86" ]
}
deps = [
"//third_party:jpeg",
]
if (use_neon) {
if (libyuv_use_neon) {
deps += [ ":libyuv_neon" ]
}
if (libyuv_use_msa) {
deps += [ ":libyuv_msa" ]
}
if (is_nacl) {
# Always enable optimization under NaCl to workaround crbug.com/538243 .
configs -= [ "//build/config/compiler:default_optimization" ]
@ -111,7 +105,7 @@ source_set("libyuv") {
}
}
if (use_neon) {
if (libyuv_use_neon) {
static_library("libyuv_neon") {
sources = [
# ARM Source Files
@ -133,3 +127,147 @@ if (use_neon) {
}
}
}
if (libyuv_use_msa) {
static_library("libyuv_msa") {
sources = [
# MSA Source Files
"source/row_msa.cc",
]
public_configs = [ ":libyuv_config" ]
}
}
if (libyuv_include_tests) {
config("libyuv_unittest_warnings_config") {
if (!is_win) {
cflags = [
# TODO(fbarchard): Fix sign and unused variable warnings.
"-Wno-sign-compare",
"-Wno-unused-variable"
]
}
if (is_win) {
cflags = [
"/wd4245", # signed/unsigned mismatch
"/wd4189", # local variable is initialized but not referenced
]
}
}
config("libyuv_unittest_config") {
defines = [ "GTEST_RELATIVE_PATH" ]
}
test("libyuv_unittest") {
testonly = true
sources = [
# headers
"unit_test/unit_test.h",
# sources
"unit_test/basictypes_test.cc",
"unit_test/compare_test.cc",
"unit_test/color_test.cc",
"unit_test/convert_test.cc",
"unit_test/cpu_test.cc",
"unit_test/math_test.cc",
"unit_test/planar_test.cc",
"unit_test/rotate_argb_test.cc",
"unit_test/rotate_test.cc",
"unit_test/scale_argb_test.cc",
"unit_test/scale_test.cc",
"unit_test/unit_test.cc",
"unit_test/video_common_test.cc",
]
deps = [
":libyuv",
"//testing/gtest",
"//third_party/gflags",
]
configs += [ ":libyuv_unittest_warnings_config" ]
public_deps = [ "//testing/gtest" ]
public_configs = [ ":libyuv_unittest_config" ]
defines = []
if (is_linux) {
cflags = [ "-fexceptions" ]
}
if (is_ios) {
configs -= [ "//build/config/compiler:default_symbols" ]
configs += [ "//build/config/compiler:symbols" ]
cflags = [ "-Wno-sometimes-uninitialized" ]
}
if (!is_ios && !libyuv_disable_jpeg) {
defines += [ "HAVE_JPEG" ]
}
if (is_android) {
deps += [ "//testing/android/native_test:native_test_native_code" ]
}
# TODO(YangZhang): These lines can be removed when high accuracy
# YUV to RGB to Neon is ported.
if ((target_cpu=="armv7" || target_cpu=="armv7s" ||
(target_cpu=="arm" && arm_version >= 7) || target_cpu=="arm64") &&
(arm_use_neon || arm_optionally_use_neon)) {
defines += [ "LIBYUV_NEON" ]
}
defines += [
# Enable the following 3 macros to turn off assembly for specified CPU.
# "LIBYUV_DISABLE_X86",
# "LIBYUV_DISABLE_NEON",
# "LIBYUV_DISABLE_MIPS",
# Enable the following macro to build libyuv as a shared library (dll).
# "LIBYUV_USING_SHARED_LIBRARY"
]
}
executable("compare") {
sources = [
# sources
"util/compare.cc"
]
deps = [ ":libyuv" ]
if (is_linux) {
cflags = [ "-fexceptions" ]
}
}
executable("convert") {
sources = [
# sources
"util/convert.cc"
]
deps = [ ":libyuv" ]
if (is_linux) {
cflags = [ "-fexceptions" ]
}
}
executable("psnr") {
sources = [
# sources
"util/psnr_main.cc",
"util/psnr.cc",
"util/ssim.cc"
]
deps = [ ":libyuv" ]
if (!is_ios && !libyuv_disable_jpeg) {
defines = [ "HAVE_JPEG" ]
}
}
executable("cpuid") {
sources = [
# sources
"util/cpuid.c"
]
deps = [ ":libyuv" ]
}
}

View File

@ -40,6 +40,7 @@ set(ly_source_files
${ly_src_dir}/row_any.cc
${ly_src_dir}/row_common.cc
${ly_src_dir}/row_mips.cc
${ly_src_dir}/row_msa.cc
${ly_src_dir}/row_neon.cc
${ly_src_dir}/row_neon64.cc
${ly_src_dir}/row_gcc.cc
@ -80,6 +81,7 @@ set(ly_header_files
${ly_inc_dir}/libyuv/convert_from.h
${ly_inc_dir}/libyuv/convert_from_argb.h
${ly_inc_dir}/libyuv/cpu_id.h
${ly_inc_dir}/libyuv/macros_msa.h
${ly_inc_dir}/libyuv/planar_functions.h
${ly_inc_dir}/libyuv/rotate.h
${ly_inc_dir}/libyuv/rotate_argb.h

View File

@ -7,14 +7,14 @@ vars = {
# Roll the Chromium Git hash to pick up newer versions of all the
# dependencies and tools linked to in setup_links.py.
'chromium_revision': '1d144ca7f86e0c684c67d6c1b6d5414ca9074615',
'chromium_revision': '941118827f5240dedb40082cffb1ead6c6d621cc',
}
# NOTE: Prefer revision numbers to tags for svn deps. Use http rather than
# https; the latter can cause problems for users behind proxies.
# NOTE: Use http rather than https; the latter can cause problems for users
# behind proxies.
deps = {
Var('root_dir') + '/third_party/gflags/src':
Var('chromium_git') + '/external/gflags/src@e7390f9185c75f8d902c05ed7d20bb94eb914d0c', # from svn revision 82
Var('chromium_git') + '/external/github.com/gflags/gflags@03bebcb065c83beff83d50ae025a55a4bf94dfca',
}
# Define rules for which include paths are allowed in our source.

View File

@ -28,6 +28,9 @@ def GetPreferredTryMasters(project, change):
'win_x64_rel',
'win_x64_gn',
'win_x64_gn_rel',
'win_clang',
'win_clang_rel',
'win_x64_clang_rel',
'mac',
'mac_rel',
'mac_gn',
@ -51,6 +54,9 @@ def GetPreferredTryMasters(project, change):
'android_rel',
'android_clang',
'android_arm64',
'android_mips',
'android_x64',
'android_x86',
'android_gn',
'android_gn_rel',
]

View File

@ -1,6 +1,6 @@
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 1586
Version: 1620
License: BSD
License File: LICENSE

View File

@ -13,3 +13,10 @@
# remove this when Chromium drops 10.6 support and also requires 10.7.
mac_sdk_min_build_override = "10.11"
mac_deployment_target_build_override = "10.7"
# Variable that can be used to support multiple build scenarios, like having
# Chromium specific targets in a client project's GN file etc.
build_with_chromium = false
# Some non-Chromium builds don't support building java targets.
enable_java_templates = true

View File

@ -0,0 +1,19 @@
# Copyright (c) 2016 The LibYuv project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# Include support for registering main function in multi-process tests.
gtest_include_multiprocess = true
# Include support for platform-specific operations across unit tests.
gtest_include_platform_test = true
# Exclude support for testing Objective C code on OS X and iOS.
gtest_include_objc_support = true
# Exclude support for flushing coverage files on iOS.
gtest_include_ios_coverage = true

View File

@ -7,6 +7,5 @@ FORCE_HTTPS_COMMIT_URL: True
PROJECT: libyuv
TRY_ON_UPLOAD: False
TRYSERVER_ROOT: src
TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-libyuv
#GITCL_PREUPLOAD:
#GITCL_PREDCOMMIT:

View File

@ -22,7 +22,7 @@ By default the cpu is detected and the most advanced form of SIMD is used. But
# Test Width/Height/Repeat
The unittests default to a small image (32x18) to run fast. This can be set by environment variable to test a specific resolutions.
The unittests default to a small image (128x72) to run fast. This can be set by environment variable to test a specific resolutions.
You can also repeat the test a specified number of iterations, allowing benchmarking and profiling.
set LIBYUV_WIDTH=1280

View File

@ -102,6 +102,15 @@ The following is extracted from video_common.h as a complete list of formats sup
// 1 Auxiliary compressed YUV format set aside for capturer.
FOURCC_H264 = FOURCC('H', '2', '6', '4'),
# Planar YUV
The following formats contains a full size Y plane followed by 1 or 2
planes for UV: I420, I422, I444, I411, I400, NV21, NV12, I400
The size (subsampling) of the UV varies.
I420, NV12 and NV21 are half width, half height
I422, NV16 and NV61 are half width, full height
I444, NV24 and NV42 are full width, full height
I400 and J400 have no chroma channel.
# The ARGB FOURCC
There are 4 ARGB layouts - ARGB, BGRA, ABGR and RGBA. ARGB is most common by far, used for screen formats, and windows webcam drivers.

View File

@ -55,6 +55,7 @@ Then run:
gclient sync
Caveat: Theres an error with Google Play services updates. If you get the error "Your version of the Google Play services library is not up to date", run the following:
cd chromium/src
./build/android/play_services/update.py download
cd ../..
@ -64,6 +65,7 @@ For Windows the gclient sync must be done from an Administrator command prompt.
The sync will generate native build files for your environment using gyp (Windows: Visual Studio, OSX: XCode, Linux: make). This generation can also be forced manually: `gclient runhooks`
To get just the source (not buildable):
git clone https://chromium.googlesource.com/libyuv/libyuv
@ -82,8 +84,7 @@ To get just the source (not buildable):
ninja -C out\Release_x64
#### Building with clangcl
set GYP_DEFINES=clang=1 target_arch=ia32 libyuv_enable_svn=1
set LLVM_REPO_URL=svn://svn.chromium.org/llvm-project
set GYP_DEFINES=clang=1 target_arch=ia32
call python tools\clang\scripts\update.py
call python gyp_libyuv -fninja libyuv_test.gyp
ninja -C out\Debug
@ -138,29 +139,29 @@ Add to .gclient last line: `target_os=['android'];`
armv7
GYP_DEFINES="OS=android" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk
ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release yuv_unittest_apk
arm64
GYP_DEFINES="OS=android target_arch=arm64 target_subarch=arm64" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk
ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release yuv_unittest_apk
ia32
GYP_DEFINES="OS=android target_arch=ia32" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk
ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release yuv_unittest_apk
GYP_DEFINES="OS=android target_arch=ia32 android_full_debug=1" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Debug yuv_unittest_apk
mipsel
GYP_DEFINES="OS=android target_arch=mipsel" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk
ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release yuv_unittest_apk
arm32 disassembly:
@ -180,7 +181,7 @@ Running test as benchmark:
Running test with C code:
util/android/test_runner.py gtest -s libyuv_unittest -t 7200 --verbose --release --gtest_filter=* -a "--libyuv_width=1280 --libyuv_height=720 --libyuv_repeat=999 --libyuv_flags=0 --libyuv_cpu_info=0"
util/android/test_runner.py gtest -s libyuv_unittest -t 7200 --verbose --release --gtest_filter=* -a "--libyuv_width=1280 --libyuv_height=720 --libyuv_repeat=999 --libyuv_flags=1 --libyuv_cpu_info=1"
#### Building with GN
@ -194,6 +195,16 @@ Running test with C code:
gn gen out/Official "--args=is_debug=false is_official_build=true is_chrome_branded=true"
ninja -C out/Official
#### Building mips with GN
mipsel
gn gen out/Default "--args=is_debug=false target_cpu=\"mipsel\" target_os = \"android\" mips_arch_variant = \"r6\" mips_use_msa = true is_component_build = true is_clang = false"
ninja -C out/Default
mips64el
gn gen out/Default "--args=is_debug=false target_cpu=\"mips64el\" target_os = \"android\" mips_arch_variant = \"r6\" mips_use_msa = true is_component_build = true is_clang = false"
ninja -C out/Default
### Linux
GYP_DEFINES="target_arch=x64" ./gyp_libyuv

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_H_
#define INCLUDE_LIBYUV_H_
#include "libyuv/basic_types.h"
@ -29,4 +29,4 @@
#include "libyuv/version.h"
#include "libyuv/video_common.h"
#endif // INCLUDE_LIBYUV_H_ NOLINT
#endif // INCLUDE_LIBYUV_H_

View File

@ -8,12 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_
#define INCLUDE_LIBYUV_BASIC_TYPES_H_
#include <stddef.h> // for NULL, size_t
#if defined(__ANDROID__) || (defined(_MSC_VER) && (_MSC_VER < 1600))
#if defined(_MSC_VER) && (_MSC_VER < 1600)
#include <sys/types.h> // for uintptr_t on x86
#else
#include <stdint.h> // for uintptr_t
@ -115,4 +115,4 @@ typedef signed char int8;
#define LIBYUV_LITTLE_ENDIAN
#endif
#endif // INCLUDE_LIBYUV_BASIC_TYPES_H_ NOLINT
#endif // INCLUDE_LIBYUV_BASIC_TYPES_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_COMPARE_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_COMPARE_H_
#define INCLUDE_LIBYUV_COMPARE_H_
#include "libyuv/basic_types.h"
@ -75,4 +75,4 @@ double I420Ssim(const uint8* src_y_a, int stride_y_a,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_COMPARE_H_ NOLINT
#endif // INCLUDE_LIBYUV_COMPARE_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_COMPARE_ROW_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_COMPARE_ROW_H_
#define INCLUDE_LIBYUV_COMPARE_ROW_H_
#include "libyuv/basic_types.h"
@ -81,4 +81,4 @@ uint32 HashDjb2_AVX2(const uint8* src, int count, uint32 seed);
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_COMPARE_ROW_H_ NOLINT
#endif // INCLUDE_LIBYUV_COMPARE_ROW_H_

View File

@ -8,14 +8,17 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_CONVERT_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_CONVERT_H_
#define INCLUDE_LIBYUV_CONVERT_H_
#include "libyuv/basic_types.h"
// TODO(fbarchard): Remove the following headers includes.
#include "libyuv/convert_from.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
#include "libyuv/rotate.h" // For enum RotationMode.
// TODO(fbarchard): fix WebRTC source to include following libyuv headers:
#include "libyuv/convert_argb.h" // For WebRTC I420ToARGB. b/620
#include "libyuv/convert_from.h" // For WebRTC ConvertFromI420. b/620
#include "libyuv/planar_functions.h" // For WebRTC I420Rect, CopyPlane. b/618
#ifdef __cplusplus
namespace libyuv {
@ -115,6 +118,17 @@ int M420ToI420(const uint8* src_m420, int src_stride_m420,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert Android420 to I420.
LIBYUV_API
int Android420ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
int pixel_stride_uv,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// ARGB little endian (bgra in memory) to I420.
LIBYUV_API
int ARGBToI420(const uint8* src_frame, int src_stride_frame,
@ -242,4 +256,4 @@ int ConvertToI420(const uint8* src_frame, size_t src_size,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CONVERT_H_ NOLINT
#endif // INCLUDE_LIBYUV_CONVERT_H_

View File

@ -8,14 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_CONVERT_ARGB_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_CONVERT_ARGB_H_
#define INCLUDE_LIBYUV_CONVERT_ARGB_H_
#include "libyuv/basic_types.h"
// TODO(fbarchard): Remove the following headers includes
#include "libyuv/convert_from.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
#include "libyuv/rotate.h" // For enum RotationMode.
// TODO(fbarchard): This set of functions should exactly match convert.h
// TODO(fbarchard): Add tests. Create random content of right size and convert
@ -44,6 +42,14 @@ int I420ToARGB(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Duplicate prototype for function in convert_from.h for remoting.
LIBYUV_API
int I420ToABGR(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert I422 to ARGB.
LIBYUV_API
int I422ToARGB(const uint8* src_y, int src_stride_y,
@ -310,4 +316,4 @@ int ConvertToARGB(const uint8* src_frame, size_t src_size,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CONVERT_ARGB_H_ NOLINT
#endif // INCLUDE_LIBYUV_CONVERT_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_CONVERT_FROM_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_CONVERT_FROM_H_
#define INCLUDE_LIBYUV_CONVERT_FROM_H_
#include "libyuv/basic_types.h"
@ -56,8 +56,6 @@ int I400Copy(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
int width, int height);
// TODO(fbarchard): I420ToM420
LIBYUV_API
int I420ToNV12(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
@ -178,4 +176,4 @@ int ConvertFromI420(const uint8* y, int y_stride,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CONVERT_FROM_H_ NOLINT
#endif // INCLUDE_LIBYUV_CONVERT_FROM_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_
#define INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_
#include "libyuv/basic_types.h"
@ -187,4 +187,4 @@ int ARGBToUYVY(const uint8* src_argb, int src_stride_argb,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ NOLINT
#endif // INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_CPU_ID_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_CPU_ID_H_
#define INCLUDE_LIBYUV_CPU_ID_H_
#include "libyuv/basic_types.h"
@ -42,6 +42,7 @@ static const int kCpuHasAVX3 = 0x2000;
// These flags are only valid on MIPS processors.
static const int kCpuHasMIPS = 0x10000;
static const int kCpuHasDSPR2 = 0x20000;
static const int kCpuHasMSA = 0x40000;
// Internal function used to auto-init.
LIBYUV_API
@ -62,7 +63,7 @@ static __inline int TestCpuFlag(int test_flag) {
// For testing, allow CPU flags to be disabled.
// ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3.
// MaskCpuFlags(-1) to enable all cpu specific optimizations.
// MaskCpuFlags(0) to disable all cpu specific optimizations.
// MaskCpuFlags(1) to disable all cpu specific optimizations.
LIBYUV_API
void MaskCpuFlags(int enable_flags);
@ -77,4 +78,4 @@ void CpuId(uint32 eax, uint32 ecx, uint32* cpu_info);
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CPU_ID_H_ NOLINT
#endif // INCLUDE_LIBYUV_CPU_ID_H_

View File

@ -0,0 +1,76 @@
/*
* Copyright 2016 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_MACROS_MSA_H_
#define INCLUDE_LIBYUV_MACROS_MSA_H_
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#include <stdint.h>
#include <msa.h>
#define LD_B(RTYPE, psrc) *((RTYPE*)(psrc)) /* NOLINT */
#define LD_UB(...) LD_B(v16u8, __VA_ARGS__)
#define ST_B(RTYPE, in, pdst) *((RTYPE*)(pdst)) = (in) /* NOLINT */
#define ST_UB(...) ST_B(v16u8, __VA_ARGS__)
/* Description : Load two vectors with 16 'byte' sized elements
Arguments : Inputs - psrc, stride
Outputs - out0, out1
Return Type - as per RTYPE
Details : Load 16 byte elements in 'out0' from (psrc)
Load 16 byte elements in 'out1' from (psrc + stride)
*/
#define LD_B2(RTYPE, psrc, stride, out0, out1) { \
out0 = LD_B(RTYPE, (psrc)); \
out1 = LD_B(RTYPE, (psrc) + stride); \
}
#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__)
#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) { \
LD_B2(RTYPE, (psrc), stride, out0, out1); \
LD_B2(RTYPE, (psrc) + 2 * stride , stride, out2, out3); \
}
#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__)
/* Description : Store two vectors with stride each having 16 'byte' sized
elements
Arguments : Inputs - in0, in1, pdst, stride
Details : Store 16 byte elements from 'in0' to (pdst)
Store 16 byte elements from 'in1' to (pdst + stride)
*/
#define ST_B2(RTYPE, in0, in1, pdst, stride) { \
ST_B(RTYPE, in0, (pdst)); \
ST_B(RTYPE, in1, (pdst) + stride); \
}
#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__)
#
#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) { \
ST_B2(RTYPE, in0, in1, (pdst), stride); \
ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \
}
#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__)
#
/* Description : Shuffle byte vector elements as per mask vector
Arguments : Inputs - in0, in1, in2, in3, mask0, mask1
Outputs - out0, out1
Return Type - as per RTYPE
Details : Byte elements from 'in0' & 'in1' are copied selectively to
'out0' as per control vector 'mask0'
*/
#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) { \
out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0); \
out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2); \
}
#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
#endif /* !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) */
#endif // INCLUDE_LIBYUV_MACROS_MSA_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_
#define INCLUDE_LIBYUV_MJPEG_DECODER_H_
#include "libyuv/basic_types.h"
@ -189,4 +189,4 @@ class LIBYUV_API MJpegDecoder {
} // namespace libyuv
#endif // __cplusplus
#endif // INCLUDE_LIBYUV_MJPEG_DECODER_H_ NOLINT
#endif // INCLUDE_LIBYUV_MJPEG_DECODER_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
#define INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
#include "libyuv/basic_types.h"
@ -39,6 +39,20 @@ void SetPlane(uint8* dst_y, int dst_stride_y,
int width, int height,
uint32 value);
// Split interleaved UV plane into separate U and V planes.
LIBYUV_API
void SplitUVPlane(const uint8* src_uv, int src_stride_uv,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Merge separate U and V planes into one interleaved UV plane.
LIBYUV_API
void MergeUVPlane(const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint8* dst_uv, int dst_stride_uv,
int width, int height);
// Copy I400. Supports inverting.
LIBYUV_API
int I400ToI400(const uint8* src_y, int src_stride_y,
@ -288,6 +302,12 @@ int ARGBCopyAlpha(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Extract the alpha channel from ARGB.
LIBYUV_API
int ARGBExtractAlpha(const uint8* src_argb, int src_stride_argb,
uint8* dst_a, int dst_stride_a,
int width, int height);
// Copy Y channel to Alpha of ARGB.
LIBYUV_API
int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,
@ -498,4 +518,4 @@ int ARGBSobelXY(const uint8* src_argb, int src_stride_argb,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ NOLINT
#endif // INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_ROTATE_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_ROTATE_H_
#define INCLUDE_LIBYUV_ROTATE_H_
#include "libyuv/basic_types.h"
@ -114,4 +114,4 @@ void TransposeUV(const uint8* src, int src_stride,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROTATE_H_ NOLINT
#endif // INCLUDE_LIBYUV_ROTATE_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_
#define INCLUDE_LIBYUV_ROTATE_ARGB_H_
#include "libyuv/basic_types.h"
@ -30,4 +30,4 @@ int ARGBRotate(const uint8* src_argb, int src_stride_argb,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_ NOLINT
#endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_ROTATE_ROW_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_ROTATE_ROW_H_
#define INCLUDE_LIBYUV_ROTATE_ROW_H_
#include "libyuv/basic_types.h"
@ -118,4 +118,4 @@ void TransposeUVWx8_Any_DSPR2(const uint8* src, int src_stride,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROTATE_ROW_H_ NOLINT
#endif // INCLUDE_LIBYUV_ROTATE_ROW_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_ROW_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_ROW_H_
#define INCLUDE_LIBYUV_ROW_H_
#include <stdlib.h> // For malloc.
@ -22,16 +22,9 @@ extern "C" {
#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1)))
#ifdef __cplusplus
#define align_buffer_64(var, size) \
uint8* var##_mem = reinterpret_cast<uint8*>(malloc((size) + 63)); \
uint8* var = reinterpret_cast<uint8*> \
((reinterpret_cast<intptr_t>(var##_mem) + 63) & ~63)
#else
#define align_buffer_64(var, size) \
uint8* var##_mem = (uint8*)(malloc((size) + 63)); /* NOLINT */ \
uint8* var = (uint8*)(((intptr_t)(var##_mem) + 63) & ~63) /* NOLINT */
#endif
#define free_aligned_buffer_64(var) \
free(var##_mem); \
@ -104,6 +97,7 @@ extern "C" {
#define HAS_ARGBTOUVROW_SSSE3
#define HAS_ARGBTOYJROW_SSSE3
#define HAS_ARGBTOYROW_SSSE3
#define HAS_ARGBEXTRACTALPHAROW_SSE2
#define HAS_BGRATOUVROW_SSSE3
#define HAS_BGRATOYROW_SSSE3
#define HAS_COPYROW_ERMS
@ -261,7 +255,7 @@ extern "C" {
#endif
// The following are also available on x64 Visual C.
#if !defined(LIBYUV_DISABLE_X86) && defined (_M_X64) && \
#if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && defined(_M_X64) && \
(!defined(__clang__) || defined(__SSSE3__))
#define HAS_I422ALPHATOARGBROW_SSSE3
#define HAS_I422TOARGBROW_SSSE3
@ -291,6 +285,7 @@ extern "C" {
#define HAS_ARGBTOUVROW_NEON
#define HAS_ARGBTOYJROW_NEON
#define HAS_ARGBTOYROW_NEON
#define HAS_ARGBEXTRACTALPHAROW_NEON
#define HAS_BGRATOUVROW_NEON
#define HAS_BGRATOYROW_NEON
#define HAS_COPYROW_NEON
@ -370,9 +365,17 @@ extern "C" {
#endif
#endif
#if defined(_MSC_VER) && !defined(__CLR_VER)
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#define HAS_MIRRORROW_MSA
#define HAS_ARGBMIRRORROW_MSA
#endif
#if defined(_MSC_VER) && !defined(__CLR_VER) && !defined(__clang__)
#if defined(VISUALC_HAS_AVX2)
#define SIMD_ALIGNED(var) __declspec(align(32)) var
#else
#define SIMD_ALIGNED(var) __declspec(align(16)) var
#define SIMD_ALIGNED32(var) __declspec(align(64)) var
#endif
typedef __declspec(align(16)) int16 vec16[8];
typedef __declspec(align(16)) int32 vec32[4];
typedef __declspec(align(16)) int8 vec8[16];
@ -385,10 +388,13 @@ typedef __declspec(align(32)) int8 lvec8[32];
typedef __declspec(align(32)) uint16 ulvec16[16];
typedef __declspec(align(32)) uint32 ulvec32[8];
typedef __declspec(align(32)) uint8 ulvec8[32];
#elif defined(__GNUC__) && !defined(__pnacl__)
#elif !defined(__pnacl__) && (defined(__GNUC__) || defined(__clang__))
// Caveat GCC 4.2 to 4.7 have a known issue using vectors with const.
#if defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2)
#define SIMD_ALIGNED(var) var __attribute__((aligned(32)))
#else
#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
#define SIMD_ALIGNED32(var) var __attribute__((aligned(64)))
#endif
typedef int16 __attribute__((vector_size(16))) vec16;
typedef int32 __attribute__((vector_size(16))) vec32;
typedef int8 __attribute__((vector_size(16))) vec8;
@ -403,7 +409,6 @@ typedef uint32 __attribute__((vector_size(32))) ulvec32;
typedef uint8 __attribute__((vector_size(32))) ulvec8;
#else
#define SIMD_ALIGNED(var) var
#define SIMD_ALIGNED32(var) var
typedef int16 vec16[8];
typedef int32 vec32[4];
typedef int8 vec8[16];
@ -439,13 +444,13 @@ struct YuvConstants {
#else
// This struct is for Intel color conversion.
struct YuvConstants {
lvec8 kUVToB;
lvec8 kUVToG;
lvec8 kUVToR;
lvec16 kUVBiasB;
lvec16 kUVBiasG;
lvec16 kUVBiasR;
lvec16 kYToRgb;
int8 kUVToB[32];
int8 kUVToG[32];
int8 kUVToR[32];
int16 kUVBiasB[16];
int16 kUVBiasG[16];
int16 kUVBiasR[16];
int16 kYToRgb[16];
};
// Offsets into YuvConstants structure
@ -459,14 +464,14 @@ struct YuvConstants {
#endif
// Conversion matrix for YUV to RGB
extern const struct YuvConstants kYuvI601Constants; // BT.601
extern const struct YuvConstants kYuvJPEGConstants; // JPeg color space
extern const struct YuvConstants kYuvH709Constants; // BT.709
extern const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants); // BT.601
extern const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants); // JPeg
extern const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants); // BT.709
// Conversion matrix for YVU to BGR
extern const struct YuvConstants kYvuI601Constants; // BT.601
extern const struct YuvConstants kYvuJPEGConstants; // JPeg color space
extern const struct YuvConstants kYvuH709Constants; // BT.709
extern const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants); // BT.601
extern const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants); // JPeg
extern const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants); // BT.709
#if defined(__APPLE__) || defined(__x86_64__) || defined(__llvm__)
#define OMITFP
@ -802,11 +807,13 @@ void MirrorRow_AVX2(const uint8* src, uint8* dst, int width);
void MirrorRow_SSSE3(const uint8* src, uint8* dst, int width);
void MirrorRow_NEON(const uint8* src, uint8* dst, int width);
void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width);
void MirrorRow_MSA(const uint8* src, uint8* dst, int width);
void MirrorRow_C(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_SSSE3(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_NEON(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_MSA(const uint8* src, uint8* dst, int width);
void MirrorUVRow_SSSE3(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width);
@ -819,10 +826,12 @@ void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width);
void ARGBMirrorRow_AVX2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_SSE2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_MSA(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_C(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_NEON(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_MSA(const uint8* src, uint8* dst, int width);
void SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width);
void SplitUVRow_SSE2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
@ -877,6 +886,14 @@ void ARGBCopyAlphaRow_Any_SSE2(const uint8* src_argb, uint8* dst_argb,
void ARGBCopyAlphaRow_Any_AVX2(const uint8* src_argb, uint8* dst_argb,
int width);
void ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width);
void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width);
void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width);
void ARGBExtractAlphaRow_Any_SSE2(const uint8* src_argb, uint8* dst_a,
int width);
void ARGBExtractAlphaRow_Any_NEON(const uint8* src_argb, uint8* dst_a,
int width);
void ARGBCopyYToAlphaRow_C(const uint8* src_y, uint8* dst_argb, int width);
void ARGBCopyYToAlphaRow_SSE2(const uint8* src_y, uint8* dst_argb, int width);
void ARGBCopyYToAlphaRow_AVX2(const uint8* src_y, uint8* dst_argb, int width);
@ -1926,4 +1943,4 @@ void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, uint8* dst_argb,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROW_H_ NOLINT
#endif // INCLUDE_LIBYUV_ROW_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_SCALE_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_SCALE_H_
#define INCLUDE_LIBYUV_SCALE_H_
#include "libyuv/basic_types.h"
@ -100,4 +100,4 @@ void SetUseReferenceImpl(LIBYUV_BOOL use);
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_SCALE_H_ NOLINT
#endif // INCLUDE_LIBYUV_SCALE_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_SCALE_ARGB_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_SCALE_ARGB_H_
#define INCLUDE_LIBYUV_SCALE_ARGB_H_
#include "libyuv/basic_types.h"
@ -53,4 +53,4 @@ int YUVToARGBScaleClip(const uint8* src_y, int src_stride_y,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_SCALE_ARGB_H_ NOLINT
#endif // INCLUDE_LIBYUV_SCALE_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_SCALE_ROW_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_SCALE_ROW_H_
#define INCLUDE_LIBYUV_SCALE_ROW_H_
#include "libyuv/basic_types.h"
@ -500,4 +500,4 @@ void ScaleRowDown38_3_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_SCALE_ROW_H_ NOLINT
#endif // INCLUDE_LIBYUV_SCALE_ROW_H_

View File

@ -8,9 +8,9 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1586
#define LIBYUV_VERSION 1620
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
#endif // INCLUDE_LIBYUV_VERSION_H_

View File

@ -10,7 +10,7 @@
// Common definitions for video, including fourcc and VideoFormat.
#ifndef INCLUDE_LIBYUV_VIDEO_COMMON_H_ // NOLINT
#ifndef INCLUDE_LIBYUV_VIDEO_COMMON_H_
#define INCLUDE_LIBYUV_VIDEO_COMMON_H_
#include "libyuv/basic_types.h"
@ -181,4 +181,4 @@ LIBYUV_API uint32 CanonicalFourCC(uint32 fourcc);
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_VIDEO_COMMON_H_ NOLINT
#endif // INCLUDE_LIBYUV_VIDEO_COMMON_H_

20
libs/libyuv/libyuv.gni Normal file
View File

@ -0,0 +1,20 @@
# Copyright 2016 The LibYuv Project Authors. All rights reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
import("//build_overrides/build.gni")
import("//build/config/arm.gni")
import("//build/config/mips.gni")
declare_args() {
libyuv_include_tests = !build_with_chromium
libyuv_disable_jpeg = false
libyuv_use_neon = (current_cpu == "arm64" ||
(current_cpu == "arm" && (arm_use_neon || arm_optionally_use_neon)))
libyuv_use_msa = (current_cpu == "mips64el" || current_cpu == "mipsel") &&
mips_use_msa
}

View File

@ -25,14 +25,20 @@
'clang%': 0,
# Link-Time Optimizations.
'use_lto%': 0,
'mips_msa%': 0, # Default to msa off.
'build_neon': 0,
'build_msa': 0,
'conditions': [
['(target_arch == "armv7" or target_arch == "armv7s" or \
(target_arch == "arm" and arm_version >= 7) or target_arch == "arm64")\
and (arm_neon == 1 or arm_neon_optional == 1)',
{
and (arm_neon == 1 or arm_neon_optional == 1)', {
'build_neon': 1,
}],
['(target_arch == "mipsel" or target_arch == "mips64el")\
and (mips_msa == 1)',
{
'build_msa': 1,
}],
],
},
@ -61,6 +67,7 @@
'-mfpu=vfp',
'-mfpu=vfpv3',
'-mfpu=vfpv3-d16',
# '-mthumb', # arm32 not thumb
],
'conditions': [
# Disable LTO in libyuv_neon target due to gcc 4.9 compiler bug.
@ -74,10 +81,16 @@
['target_arch != "arm64"', {
'cflags': [
'-mfpu=neon',
# '-marm', # arm32 not thumb
],
}],
],
}],
['build_msa != 0', {
'defines': [
'LIBYUV_MSA',
],
}],
['OS != "ios" and libyuv_disable_jpeg != 1', {
'defines': [
'HAVE_JPEG'

View File

@ -18,6 +18,7 @@
'include/libyuv/convert_from.h',
'include/libyuv/convert_from_argb.h',
'include/libyuv/cpu_id.h',
'include/libyuv/macros_msa.h',
'include/libyuv/mjpeg_decoder.h',
'include/libyuv/planar_functions.h',
'include/libyuv/rotate.h',
@ -61,6 +62,7 @@
'source/row_common.cc',
'source/row_gcc.cc',
'source/row_mips.cc',
'source/row_msa.cc',
'source/row_neon.cc',
'source/row_neon64.cc',
'source/row_win.cc',

View File

@ -9,6 +9,7 @@
{
'variables': {
'libyuv_disable_jpeg%': 0,
'mips_msa%': 0, # Default to msa off.
},
'targets': [
{
@ -52,11 +53,6 @@
'-fexceptions',
],
}],
[ 'OS == "ios" and target_subarch == 64', {
'defines': [
'LIBYUV_DISABLE_NEON'
],
}],
[ 'OS == "ios"', {
'xcode_settings': {
'DEBUGGING_SYMBOLS': 'YES',
@ -91,6 +87,12 @@
'LIBYUV_NEON'
],
}],
[ '(target_arch == "mipsel" or target_arch == "mips64el") \
and (mips_msa == 1)', {
'defines': [
'LIBYUV_MSA'
],
}],
], # conditions
'defines': [
# Enable the following 3 macros to turn off assembly for specified CPU.
@ -151,12 +153,6 @@
'libyuv.gyp:libyuv',
],
'conditions': [
[ 'OS == "ios" and target_subarch == 64', {
'defines': [
'LIBYUV_DISABLE_NEON'
],
}],
[ 'OS != "ios" and libyuv_disable_jpeg != 1', {
'defines': [
'HAVE_JPEG',
@ -181,30 +177,16 @@
['OS=="android"', {
'targets': [
{
# TODO(kjellander): Figure out what to change in build/apk_test.gypi
# to it can be used instead of the copied code below. Using it in its
# current version was not possible, since the target starts with 'lib',
# which somewhere confuses the variables.
'target_name': 'libyuv_unittest_apk',
'target_name': 'yuv_unittest_apk',
'type': 'none',
'variables': {
# These are used to configure java_apk.gypi included below.
'test_type': 'gtest',
'apk_name': 'libyuv_unittest',
'intermediate_dir': '<(PRODUCT_DIR)/libyuv_unittest_apk',
'final_apk_path': '<(intermediate_dir)/libyuv_unittest-debug.apk',
'java_in_dir': '<(DEPTH)/testing/android/native_test/java',
'native_lib_target': 'libyuv_unittest',
'gyp_managed_install': 0,
'test_suite_name': 'yuv_unittest',
'input_shlib_path': '<(SHARED_LIB_DIR)/(SHARED_LIB_PREFIX)libyuv_unittest<(SHARED_LIB_SUFFIX)',
},
'includes': [ 'build/java_apk.gypi' ],
'includes': [
'build/apk_test.gypi',
],
'dependencies': [
'<(DEPTH)/base/base.gyp:base_java',
'<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
'<(DEPTH)/build/android/pylib/remote/device/dummy/dummy.gyp:remote_device_dummy_apk',
'<(DEPTH)/testing/android/appurify_support.gyp:appurify_support_java',
'<(DEPTH)/testing/android/on_device_instrumentation.gyp:reporter_java',
'<(DEPTH)/tools/android/android_tools.gyp:android_tools',
'libyuv_unittest',
],
},

View File

@ -74,6 +74,8 @@ psnr: util/psnr.cc
$(CXX) $(CXXFLAGS) -Iutil/ -o $@ util/psnr.cc util/psnr_main.cc util/ssim.cc
# A C test utility that uses libyuv conversion from C.
# gcc 4.4 and older require -fno-exceptions to avoid link error on __gxx_personality_v0
# CC=gcc-4.4 CXXFLAGS=-fno-exceptions CXX=g++-4.4 make -f linux.mk
cpuid: util/cpuid.c libyuv.a
$(CC) $(CFLAGS) -o $@ util/cpuid.c libyuv.a

View File

@ -13,9 +13,6 @@ WebRTC standalone shares a lot of dependencies and build tools with Chromium.
To do this, many of the paths of a Chromium checkout is emulated by creating
symlinks to files and directories. This script handles the setup of symlinks to
achieve this.
It also handles cleanup of the legacy Subversion-based approach that was used
before Chrome switched over their master repo from Subversion to Git.
"""
@ -34,43 +31,25 @@ import textwrap
DIRECTORIES = [
'build',
'buildtools',
'google_apis', # Needed by build/common.gypi.
'mojo', # TODO(kjellander): Remove, see webrtc:5629.
'native_client',
'net',
'testing',
'third_party/binutils',
'third_party/boringssl',
'third_party/colorama',
'third_party/drmemory',
'third_party/expat',
'third_party/icu',
'third_party/instrumented_libraries',
'third_party/jsoncpp',
'third_party/libjpeg',
'third_party/libjpeg_turbo',
'third_party/libsrtp',
'third_party/libudev',
'third_party/libvpx',
'third_party/libyuv',
'third_party/llvm-build',
'third_party/lss',
'third_party/nss',
'third_party/ocmock',
'third_party/openmax_dl',
'third_party/opus',
'third_party/proguard',
'third_party/protobuf',
'third_party/sqlite',
'third_party/syzygy',
'third_party/usrsctp',
'third_party/tcmalloc',
'third_party/yasm',
'third_party/zlib',
'third_party/WebKit', # TODO(kjellander): Remove, see webrtc:5629.
'tools/clang',
'tools/generate_library_loader',
'tools/gn',
'tools/gyp',
'tools/memory',
'tools/protoc_wrapper',
'tools/python',
'tools/swarming_client',
'tools/valgrind',
@ -83,31 +62,40 @@ target_os = get_target_os_list()
if 'android' in target_os:
DIRECTORIES += [
'base',
'third_party/accessibility_test_framework',
'third_party/android_platform',
'third_party/android_testrunner',
'third_party/android_tools',
'third_party/apache_velocity',
'third_party/appurify-python',
'third_party/ashmem',
'third_party/bouncycastle',
'third_party/catapult',
'third_party/ced',
'third_party/closure_compiler',
'third_party/guava',
'third_party/hamcrest',
'third_party/icu',
'third_party/icu4j',
'third_party/ijar',
'third_party/intellij',
'third_party/jsr-305',
'third_party/junit',
'third_party/libevent',
'third_party/libxml',
'third_party/mockito',
'third_party/modp_b64',
'third_party/ow2_asm',
'third_party/protobuf',
'third_party/requests',
'third_party/robolectric',
'third_party/sqlite4java',
'third_party/zlib',
'tools/android',
'tools/grit',
'tools/relocation_packer',
'tools/telemetry',
]
if 'ios' in target_os:
DIRECTORIES.append('third_party/class-dump')
FILES = {
'tools/find_depot_tools.py': None,
'tools/isolate_driver.py': None,
'third_party/BUILD.gn': None,
}
@ -201,7 +189,7 @@ class Rmtree(Action):
def doit(self, _):
if sys.platform.startswith('win'):
# shutil.rmtree() doesn't work on Windows if any of the directories are
# read-only, which svn repositories are.
# read-only.
subprocess.check_call(['rd', '/q', '/s', self._path], shell=True)
else:
shutil.rmtree(self._path)
@ -257,15 +245,16 @@ class LinkError(IOError):
pass
# Handles symlink creation on the different platforms.
# Use junctions instead of symlinks on the Windows platform.
if sys.platform.startswith('win'):
def symlink(source_path, link_path):
flag = 1 if os.path.isdir(source_path) else 0
if not ctypes.windll.kernel32.CreateSymbolicLinkW(
unicode(link_path), unicode(source_path), flag):
raise OSError('Failed to create symlink to %s. Notice that only NTFS '
'version 5.0 and up has all the needed APIs for '
'creating symlinks.' % source_path)
if os.path.isdir(source_path):
subprocess.check_call(['cmd.exe', '/c', 'mklink', '/J', link_path,
source_path])
else:
# Don't create symlinks to files on Windows, just copy the file instead
# (there's no way to create a link without administrator's privileges).
shutil.copy(source_path, link_path)
os.symlink = symlink
@ -317,18 +306,10 @@ class WebRTCLinkSetup(object):
A C T I O N R E Q I R E D
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Because chromium/src is transitioning to Git (from SVN), we needed to
change the way that the WebRTC standalone checkout works. Instead of
individually syncing subdirectories of Chromium in SVN, we're now
syncing Chromium (and all of its DEPS, as defined by its own DEPS file),
into the `chromium/src` directory.
As such, all Chromium directories which are currently pulled by DEPS are
now replaced with a symlink into the full Chromium checkout.
To avoid disrupting developers, we've chosen to not delete your
directories forcibly, in case you have some work in progress in one of
them :).
Setting up the checkout requires creating symlinks to directories in the
Chromium checkout inside chromium/src.
To avoid disrupting developers, we've chosen to not delete directories
forcibly, in case you have some work in progress in one of them :)
ACTION REQUIRED:
Before running `gclient sync|runhooks` again, you must run:
@ -336,7 +317,7 @@ class WebRTCLinkSetup(object):
Which will replace all directories which now must be symlinks, after
prompting with a summary of the work-to-be-done.
"""), 'python ' if sys.platform.startswith('win') else '', sys.argv[0])
"""), 'python ' if sys.platform.startswith('win') else '', __file__)
sys.exit(1)
elif self._prompt:
if not query_yes_no('Would you like to perform the above plan?'):
@ -374,8 +355,9 @@ class WebRTCLinkSetup(object):
check_msg=None):
"""Create zero or more Actions to link to a file or directory.
This will be a symlink on POSIX platforms. On Windows this requires
that NTFS is version 5.0 or higher (Vista or newer).
This will be a symlink on POSIX platforms. On Windows it will result in:
* a junction for directories
* a copied file for single files.
Args:
source_path: Path relative to the Chromium checkout root.
@ -405,8 +387,8 @@ class WebRTCLinkSetup(object):
source_path = fix_separators(source_path)
source_path = os.path.join(CHROMIUM_CHECKOUT, source_path)
if os.path.exists(source_path) and not check_fn:
raise LinkError('_LinkChromiumPath can only be used to link to %s: '
'Tried to link to: %s' % (check_msg, source_path))
raise LinkError('Can only to link to %s: tried to link to: %s' %
(check_msg, source_path))
if not os.path.exists(source_path):
logging.debug('Silently ignoring missing source: %s. This is to avoid '
@ -489,12 +471,9 @@ def main():
return os.getuid() == 0
except AttributeError:
return ctypes.windll.shell32.IsUserAnAdmin() != 0
if not is_admin():
logging.error('On Windows, you now need to have administrator '
'privileges for the shell running %s (or '
'`gclient sync|runhooks`).\nPlease start another command '
'prompt as Administrator and try again.', sys.argv[0])
return 1
if is_admin():
logging.warning('WARNING: On Windows, you no longer need run as '
'administrator. Please run with user account privileges.')
if not os.path.exists(CHROMIUM_CHECKOUT):
logging.error('Cannot find a Chromium checkout at %s. Did you run "gclient '

View File

@ -40,13 +40,14 @@ static int I4xxToI420(const uint8* src_y, int src_stride_y,
const int dst_y_height = Abs(src_y_height);
const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1);
const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1);
if (src_y_width == 0 || src_y_height == 0 ||
src_uv_width == 0 || src_uv_height == 0) {
if (src_uv_width == 0 || src_uv_height == 0) {
return -1;
}
ScalePlane(src_y, src_stride_y, src_y_width, src_y_height,
dst_y, dst_stride_y, dst_y_width, dst_y_height,
kFilterBilinear);
if (dst_y) {
ScalePlane(src_y, src_stride_y, src_y_width, src_y_height,
dst_y, dst_stride_y, dst_y_width, dst_y_height,
kFilterBilinear);
}
ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height,
dst_u, dst_stride_u, dst_uv_width, dst_uv_height,
kFilterBilinear);
@ -69,8 +70,8 @@ int I420Copy(const uint8* src_y, int src_stride_y,
int width, int height) {
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
if (!src_y || !src_u || !src_v ||
!dst_y || !dst_u || !dst_v ||
if (!src_u || !src_v ||
!dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
@ -166,7 +167,7 @@ int I400ToI420(const uint8* src_y, int src_stride_y,
int width, int height) {
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
if (!src_y || !dst_y || !dst_u || !dst_v ||
if (!dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
@ -177,7 +178,9 @@ int I400ToI420(const uint8* src_y, int src_stride_y,
src_y = src_y + (height - 1) * src_stride_y;
src_stride_y = -src_stride_y;
}
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
SetPlane(dst_u, dst_stride_u, halfwidth, halfheight, 128);
SetPlane(dst_v, dst_stride_v, halfwidth, halfheight, 128);
return 0;
@ -242,13 +245,9 @@ static int X420ToI420(const uint8* src_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) = SplitUVRow_C;
if (!src_y || !src_uv ||
!dst_y || !dst_u || !dst_v ||
if (!src_uv || !dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
@ -256,7 +255,9 @@ static int X420ToI420(const uint8* src_y,
if (height < 0) {
height = -height;
halfheight = (height + 1) >> 1;
dst_y = dst_y + (height - 1) * dst_stride_y;
if (dst_y) {
dst_y = dst_y + (height - 1) * dst_stride_y;
}
dst_u = dst_u + (halfheight - 1) * dst_stride_u;
dst_v = dst_v + (halfheight - 1) * dst_stride_v;
dst_stride_y = -dst_stride_y;
@ -279,41 +280,6 @@ static int X420ToI420(const uint8* src_y,
halfheight = 1;
src_stride_uv = dst_stride_u = dst_stride_v = 0;
}
#if defined(HAS_SPLITUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SplitUVRow = SplitUVRow_Any_SSE2;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_SSE2;
}
}
#endif
#if defined(HAS_SPLITUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
SplitUVRow = SplitUVRow_Any_AVX2;
if (IS_ALIGNED(halfwidth, 32)) {
SplitUVRow = SplitUVRow_AVX2;
}
}
#endif
#if defined(HAS_SPLITUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SplitUVRow = SplitUVRow_Any_NEON;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_NEON;
}
}
#endif
#if defined(HAS_SPLITUVROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src_uv, 4) && IS_ALIGNED(src_stride_uv, 4) &&
IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) &&
IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) {
SplitUVRow = SplitUVRow_Any_DSPR2;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_DSPR2;
}
}
#endif
if (dst_y) {
if (src_stride_y0 == src_stride_y1) {
@ -324,13 +290,10 @@ static int X420ToI420(const uint8* src_y,
}
}
for (y = 0; y < halfheight; ++y) {
// Copy a row of UV.
SplitUVRow(src_uv, dst_u, dst_v, halfwidth);
dst_u += dst_stride_u;
dst_v += dst_stride_v;
src_uv += src_stride_uv;
}
// Split UV plane - NV12 / NV21
SplitUVPlane(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, dst_stride_v,
halfwidth, halfheight);
return 0;
}
@ -1383,6 +1346,81 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444,
return 0;
}
static void SplitPixels(const uint8* src_u, int src_pixel_stride_uv,
uint8* dst_u, int width) {
int i;
for (i = 0; i < width; ++i) {
*dst_u = *src_u;
++dst_u;
src_u += src_pixel_stride_uv;
}
}
// Convert Android420 to I420.
LIBYUV_API
int Android420ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
int src_pixel_stride_uv,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
const int vu_off = src_v - src_u;
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
if (!src_u || !src_v ||
!dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
halfheight = (height + 1) >> 1;
src_y = src_y + (height - 1) * src_stride_y;
src_u = src_u + (halfheight - 1) * src_stride_u;
src_v = src_v + (halfheight - 1) * src_stride_v;
src_stride_y = -src_stride_y;
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
// Copy UV planes as is - I420
if (src_pixel_stride_uv == 1) {
CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight);
CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight);
return 0;
// Split UV planes - NV21
} else if (src_pixel_stride_uv == 2 && vu_off == -1 &&
src_stride_u == src_stride_v) {
SplitUVPlane(src_v, src_stride_v, dst_v, dst_stride_v, dst_u, dst_stride_u,
halfwidth, halfheight);
return 0;
// Split UV planes - NV12
} else if (src_pixel_stride_uv == 2 && vu_off == 1 &&
src_stride_u == src_stride_v) {
SplitUVPlane(src_u, src_stride_u, dst_u, dst_stride_u, dst_v, dst_stride_v,
halfwidth, halfheight);
return 0;
}
for (y = 0; y < halfheight; ++y) {
SplitPixels(src_u, src_pixel_stride_uv, dst_u, halfwidth);
SplitPixels(src_v, src_pixel_stride_uv, dst_v, halfwidth);
src_u += src_stride_u;
src_v += src_stride_v;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
return 0;
}
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv

View File

@ -14,6 +14,7 @@
#ifdef HAVE_JPEG
#include "libyuv/mjpeg_decoder.h"
#endif
#include "libyuv/planar_functions.h" // For CopyPlane and ARGBShuffle.
#include "libyuv/rotate_argb.h"
#include "libyuv/row.h"
#include "libyuv/video_common.h"

View File

@ -46,9 +46,11 @@ static int I420ToI4xx(const uint8* src_y, int src_stride_y,
dst_uv_width <= 0 || dst_uv_height <= 0) {
return -1;
}
ScalePlane(src_y, src_stride_y, src_y_width, src_y_height,
dst_y, dst_stride_y, dst_y_width, dst_y_height,
kFilterBilinear);
if (dst_y) {
ScalePlane(src_y, src_stride_y, src_y_width, src_y_height,
dst_y, dst_stride_y, dst_y_width, dst_y_height,
kFilterBilinear);
}
ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height,
dst_u, dst_stride_u, dst_uv_width, dst_uv_height,
kFilterBilinear);
@ -359,6 +361,7 @@ int I420ToUYVY(const uint8* src_y, int src_stride_y,
return 0;
}
// TODO(fbarchard): test negative height for invert.
LIBYUV_API
int I420ToNV12(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
@ -366,72 +369,19 @@ int I420ToNV12(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
uint8* dst_uv, int dst_stride_uv,
int width, int height) {
int y;
void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width) = MergeUVRow_C;
// Coalesce rows.
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
if (!src_y || !src_u || !src_v || !dst_y || !dst_uv ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
halfheight = (height + 1) >> 1;
dst_y = dst_y + (height - 1) * dst_stride_y;
dst_uv = dst_uv + (halfheight - 1) * dst_stride_uv;
dst_stride_y = -dst_stride_y;
dst_stride_uv = -dst_stride_uv;
}
if (src_stride_y == width &&
dst_stride_y == width) {
width *= height;
height = 1;
src_stride_y = dst_stride_y = 0;
}
// Coalesce rows.
if (src_stride_u == halfwidth &&
src_stride_v == halfwidth &&
dst_stride_uv == halfwidth * 2) {
halfwidth *= halfheight;
halfheight = 1;
src_stride_u = src_stride_v = dst_stride_uv = 0;
}
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
MergeUVRow_ = MergeUVRow_Any_SSE2;
if (IS_ALIGNED(halfwidth, 16)) {
MergeUVRow_ = MergeUVRow_SSE2;
}
}
#endif
#if defined(HAS_MERGEUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
MergeUVRow_ = MergeUVRow_Any_AVX2;
if (IS_ALIGNED(halfwidth, 32)) {
MergeUVRow_ = MergeUVRow_AVX2;
}
}
#endif
#if defined(HAS_MERGEUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
MergeUVRow_ = MergeUVRow_Any_NEON;
if (IS_ALIGNED(halfwidth, 16)) {
MergeUVRow_ = MergeUVRow_NEON;
}
}
#endif
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
for (y = 0; y < halfheight; ++y) {
// Merge a row of U and V into a row of UV.
MergeUVRow_(src_u, src_v, dst_uv, halfwidth);
src_u += src_stride_u;
src_v += src_stride_v;
dst_uv += dst_stride_uv;
int halfwidth = (width + 1) / 2;
int halfheight = height > 0 ? (height + 1) / 2 : (height - 1) / 2;
if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
MergeUVPlane(src_u, src_stride_u,
src_v, src_stride_v,
dst_uv, dst_stride_uv,
halfwidth, halfheight);
return 0;
}
@ -1077,7 +1027,6 @@ int ConvertFromI420(const uint8* y, int y_stride,
// Triplanar formats
// TODO(fbarchard): halfstride instead of halfwidth
case FOURCC_I420:
case FOURCC_YU12:
case FOURCC_YV12: {
int halfwidth = (width + 1) / 2;
int halfheight = (height + 1) / 2;

View File

@ -9,6 +9,7 @@
*/
#include "libyuv/convert.h"
#include "libyuv/convert_argb.h"
#ifdef HAVE_JPEG
#include "libyuv/mjpeg_decoder.h"

View File

@ -176,7 +176,6 @@ int ConvertToARGB(const uint8* sample, size_t sample_size,
break;
// Triplanar formats
case FOURCC_I420:
case FOURCC_YU12:
case FOURCC_YV12: {
const uint8* src_y = sample + (src_width * crop_y + crop_x);
const uint8* src_u;

View File

@ -39,12 +39,13 @@ int ConvertToI420(const uint8* sample,
int aligned_src_width = (src_width + 1) & ~1;
const uint8* src;
const uint8* src_uv;
int abs_src_height = (src_height < 0) ? -src_height : src_height;
int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height;
const int abs_src_height = (src_height < 0) ? -src_height : src_height;
// TODO(nisse): Why allow crop_height < 0?
const int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height;
int r = 0;
LIBYUV_BOOL need_buf = (rotation && format != FOURCC_I420 &&
format != FOURCC_NV12 && format != FOURCC_NV21 &&
format != FOURCC_YU12 && format != FOURCC_YV12) || y == sample;
format != FOURCC_YV12) || y == sample;
uint8* tmp_y = y;
uint8* tmp_u = u;
uint8* tmp_v = v;
@ -52,16 +53,14 @@ int ConvertToI420(const uint8* sample,
int tmp_u_stride = u_stride;
int tmp_v_stride = v_stride;
uint8* rotate_buffer = NULL;
int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height;
const int inv_crop_height =
(src_height < 0) ? -abs_crop_height : abs_crop_height;
if (!y || !u || !v || !sample ||
src_width <= 0 || crop_width <= 0 ||
src_height == 0 || crop_height == 0) {
return -1;
}
if (src_height < 0) {
inv_crop_height = -inv_crop_height;
}
// One pass rotation is available for some formats. For the rest, convert
// to I420 (with optional vertical flipping) into a temporary I420 buffer,
@ -214,7 +213,6 @@ int ConvertToI420(const uint8* sample,
break;
// Triplanar formats
case FOURCC_I420:
case FOURCC_YU12:
case FOURCC_YV12: {
const uint8* src_y = sample + (src_width * crop_y + crop_x);
const uint8* src_u;

View File

@ -161,6 +161,38 @@ int ArmCpuCaps(const char* cpuinfo_name) {
return 0;
}
LIBYUV_API SAFEBUFFERS
int MipsCpuCaps(const char* cpuinfo_name, const char ase[]) {
char cpuinfo_line[512];
int len = (int)strlen(ase);
FILE* f = fopen(cpuinfo_name, "r");
if (!f) {
// ase enabled if /proc/cpuinfo is unavailable.
if (strcmp(ase, " msa") == 0) {
return kCpuHasMSA;
}
if (strcmp(ase, " dspr2") == 0) {
return kCpuHasDSPR2;
}
}
while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) {
if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) {
char* p = strstr(cpuinfo_line, ase);
if (p && (p[len] == ' ' || p[len] == '\n')) {
fclose(f);
if (strcmp(ase, " msa") == 0) {
return kCpuHasMSA;
}
if (strcmp(ase, " dspr2") == 0) {
return kCpuHasDSPR2;
}
}
}
}
fclose(f);
return 0;
}
// CPU detect function for SIMD instruction sets.
LIBYUV_API
int cpu_info_ = 0; // cpu_info is not initialized yet.
@ -253,11 +285,17 @@ int InitCpuFlags(void) {
#if defined(__mips__) && defined(__linux__)
#if defined(__mips_dspr2)
cpu_info |= kCpuHasDSPR2;
#endif
#if defined(__mips_msa)
cpu_info = MipsCpuCaps("/proc/cpuinfo", " msa");
#endif
cpu_info |= kCpuHasMIPS;
if (getenv("LIBYUV_DISABLE_DSPR2")) {
cpu_info &= ~kCpuHasDSPR2;
}
if (getenv("LIBYUV_DISABLE_MSA")) {
cpu_info &= ~kCpuHasMSA;
}
#endif
#if defined(__arm__) || defined(__aarch64__)
// gcc -mfpu=neon defines __ARM_NEON__

View File

@ -62,6 +62,7 @@ void init_source(jpeg_decompress_struct* cinfo);
void skip_input_data(jpeg_decompress_struct* cinfo, long num_bytes); // NOLINT
void term_source(jpeg_decompress_struct* cinfo);
void ErrorHandler(jpeg_common_struct* cinfo);
void OutputHandler(jpeg_common_struct* cinfo);
MJpegDecoder::MJpegDecoder()
: has_scanline_padding_(LIBYUV_FALSE),
@ -77,6 +78,7 @@ MJpegDecoder::MJpegDecoder()
decompress_struct_->err = jpeg_std_error(&error_mgr_->base);
// Override standard exit()-based error handler.
error_mgr_->base.error_exit = &ErrorHandler;
error_mgr_->base.output_message = &OutputHandler;
#endif
decompress_struct_->client_data = NULL;
source_mgr_->init_source = &init_source;
@ -456,7 +458,12 @@ void ErrorHandler(j_common_ptr cinfo) {
// and causes it to return (for a second time) with value 1.
longjmp(mgr->setjmp_buffer, 1);
}
#endif
void OutputHandler(j_common_ptr cinfo) {
// Suppress fprintf warnings.
}
#endif // HAVE_SETJMP
void MJpegDecoder::AllocOutputBuffers(int num_outbufs) {
if (num_outbufs != num_outbufs_) {

View File

@ -31,6 +31,12 @@ void CopyPlane(const uint8* src_y, int src_stride_y,
int width, int height) {
int y;
void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_y = dst_y + (height - 1) * dst_stride_y;
dst_stride_y = -dst_stride_y;
}
// Coalesce rows.
if (src_stride_y == width &&
dst_stride_y == width) {
@ -76,6 +82,7 @@ void CopyPlane(const uint8* src_y, int src_stride_y,
}
}
// TODO(fbarchard): Consider support for negative height.
LIBYUV_API
void CopyPlane_16(const uint16* src_y, int src_stride_y,
uint16* dst_y, int dst_stride_y,
@ -128,8 +135,8 @@ int I422Copy(const uint8* src_y, int src_stride_y,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int halfwidth = (width + 1) >> 1;
if (!src_y || !src_u || !src_v ||
!dst_y || !dst_u || !dst_v ||
if (!src_u || !src_v ||
!dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
@ -143,7 +150,10 @@ int I422Copy(const uint8* src_y, int src_stride_y,
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, height);
CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, height);
return 0;
@ -158,8 +168,8 @@ int I444Copy(const uint8* src_y, int src_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
if (!src_y || !src_u || !src_v ||
!dst_y || !dst_u || !dst_v ||
if (!src_u || !src_v ||
!dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
@ -174,7 +184,9 @@ int I444Copy(const uint8* src_y, int src_stride_y,
src_stride_v = -src_stride_v;
}
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height);
CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height);
return 0;
@ -214,10 +226,138 @@ int I420ToI400(const uint8* src_y, int src_stride_y,
src_y = src_y + (height - 1) * src_stride_y;
src_stride_y = -src_stride_y;
}
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
return 0;
}
// Support function for NV12 etc UV channels.
// Width and height are plane sizes (typically half pixel width).
LIBYUV_API
void SplitUVPlane(const uint8* src_uv, int src_stride_uv,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) = SplitUVRow_C;
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_u = dst_u + (height - 1) * dst_stride_u;
dst_v = dst_v + (height - 1) * dst_stride_v;
dst_stride_u = -dst_stride_u;
dst_stride_v = -dst_stride_v;
}
// Coalesce rows.
if (src_stride_uv == width * 2 &&
dst_stride_u == width &&
dst_stride_v == width) {
width *= height;
height = 1;
src_stride_uv = dst_stride_u = dst_stride_v = 0;
}
#if defined(HAS_SPLITUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SplitUVRow = SplitUVRow_Any_SSE2;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_SSE2;
}
}
#endif
#if defined(HAS_SPLITUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
SplitUVRow = SplitUVRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
SplitUVRow = SplitUVRow_AVX2;
}
}
#endif
#if defined(HAS_SPLITUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SplitUVRow = SplitUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_NEON;
}
}
#endif
#if defined(HAS_SPLITUVROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) &&
IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) {
SplitUVRow = SplitUVRow_Any_DSPR2;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_DSPR2;
}
}
#endif
for (y = 0; y < height; ++y) {
// Copy a row of UV.
SplitUVRow(src_uv, dst_u, dst_v, width);
dst_u += dst_stride_u;
dst_v += dst_stride_v;
src_uv += src_stride_uv;
}
}
LIBYUV_API
void MergeUVPlane(const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint8* dst_uv, int dst_stride_uv,
int width, int height) {
int y;
void (*MergeUVRow)(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width) = MergeUVRow_C;
// Coalesce rows.
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_uv = dst_uv + (height - 1) * dst_stride_uv;
dst_stride_uv = -dst_stride_uv;
}
// Coalesce rows.
if (src_stride_u == width &&
src_stride_v == width &&
dst_stride_uv == width * 2) {
width *= height;
height = 1;
src_stride_u = src_stride_v = dst_stride_uv = 0;
}
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
MergeUVRow = MergeUVRow_Any_SSE2;
if (IS_ALIGNED(width, 16)) {
MergeUVRow = MergeUVRow_SSE2;
}
}
#endif
#if defined(HAS_MERGEUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
MergeUVRow = MergeUVRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
MergeUVRow = MergeUVRow_AVX2;
}
}
#endif
#if defined(HAS_MERGEUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
MergeUVRow = MergeUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
MergeUVRow = MergeUVRow_NEON;
}
}
#endif
for (y = 0; y < height; ++y) {
// Merge a row of U and V into a row of UV.
MergeUVRow(src_u, src_v, dst_uv, width);
src_u += src_stride_u;
src_v += src_stride_v;
dst_uv += dst_stride_uv;
}
}
// Mirror a plane of data.
void MirrorPlane(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
@ -261,6 +401,14 @@ void MirrorPlane(const uint8* src_y, int src_stride_y,
IS_ALIGNED(dst_y, 4) && IS_ALIGNED(dst_stride_y, 4)) {
MirrorRow = MirrorRow_DSPR2;
}
#endif
#if defined(HAS_MIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
MirrorRow = MirrorRow_Any_MSA;
if (IS_ALIGNED(width, 64)) {
MirrorRow = MirrorRow_MSA;
}
}
#endif
// Mirror plane
@ -511,6 +659,14 @@ int ARGBMirror(const uint8* src_argb, int src_stride_argb,
}
}
#endif
#if defined(HAS_ARGBMIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBMirrorRow = ARGBMirrorRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBMirrorRow = ARGBMirrorRow_MSA;
}
}
#endif
// Mirror plane
for (y = 0; y < height; ++y) {
@ -2374,6 +2530,49 @@ int ARGBCopyAlpha(const uint8* src_argb, int src_stride_argb,
return 0;
}
// Extract just the alpha channel from ARGB.
LIBYUV_API
int ARGBExtractAlpha(const uint8* src_argb, int src_stride,
uint8* dst_a, int dst_stride,
int width, int height) {
if (!src_argb || !dst_a || width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_argb += (height - 1) * src_stride;
src_stride = -src_stride;
}
// Coalesce rows.
if (src_stride == width * 4 && dst_stride == width) {
width *= height;
height = 1;
src_stride = dst_stride = 0;
}
void (*ARGBExtractAlphaRow)(const uint8 *src_argb, uint8 *dst_a, int width) =
ARGBExtractAlphaRow_C;
#if defined(HAS_ARGBEXTRACTALPHAROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_SSE2
: ARGBExtractAlphaRow_Any_SSE2;
}
#endif
#if defined(HAS_ARGBEXTRACTALPHAROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_NEON
: ARGBExtractAlphaRow_Any_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
ARGBExtractAlphaRow(src_argb, dst_a, width);
src_argb += src_stride;
dst_a += dst_stride;
}
return 0;
}
// Copy a planar Y channel to the alpha channel of a destination ARGB image.
LIBYUV_API
int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,

View File

@ -141,6 +141,14 @@ void RotatePlane180(const uint8* src, int src_stride,
MirrorRow = MirrorRow_DSPR2;
}
#endif
#if defined(HAS_MIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
MirrorRow = MirrorRow_Any_MSA;
if (IS_ALIGNED(width, 64)) {
MirrorRow = MirrorRow_MSA;
}
}
#endif
#if defined(HAS_COPYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;

View File

@ -118,6 +118,14 @@ void ARGBRotate180(const uint8* src, int src_stride,
}
}
#endif
#if defined(HAS_ARGBMIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBMirrorRow = ARGBMirrorRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBMirrorRow = ARGBMirrorRow_MSA;
}
}
#endif
#if defined(HAS_COPYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
CopyRow = IS_ALIGNED(width * 4, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;

View File

@ -23,7 +23,7 @@ extern "C" {
(_MIPS_SIM == _MIPS_SIM_ABI32)
void TransposeWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width) {
uint8* dst, int dst_stride, int width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -107,7 +107,7 @@ void TransposeWx8_DSPR2(const uint8* src, int src_stride,
}
void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width) {
uint8* dst, int dst_stride, int width) {
__asm__ __volatile__ (
".set noat \n"
".set push \n"
@ -309,9 +309,9 @@ void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride,
}
void TransposeUVWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b,
int width) {
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b,
int width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"

View File

@ -466,38 +466,15 @@ ANY11(ARGBUnattenuateRow_Any_AVX2, ARGBUnattenuateRow_AVX2, 0, 4, 4, 7)
#ifdef HAS_ARGBATTENUATEROW_NEON
ANY11(ARGBAttenuateRow_Any_NEON, ARGBAttenuateRow_NEON, 0, 4, 4, 7)
#endif
#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2
ANY11(ARGBExtractAlphaRow_Any_SSE2, ARGBExtractAlphaRow_SSE2, 0, 4, 1, 7)
#endif
#ifdef HAS_ARGBEXTRACTALPHAROW_NEON
ANY11(ARGBExtractAlphaRow_Any_NEON, ARGBExtractAlphaRow_NEON, 0, 4, 1, 15)
#endif
#undef ANY11
// Any 1 to 1 with yuvconstants
#define ANY11C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \
void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, \
const struct YuvConstants* yuvconstants, int width) { \
SIMD_ALIGNED(uint8 temp[128 * 2]); \
memset(temp, 0, 128); /* for YUY2 and msan */ \
int r = width & MASK; \
int n = width & ~MASK; \
if (n > 0) { \
ANY_SIMD(src_ptr, dst_ptr, yuvconstants, n); \
} \
memcpy(temp, src_ptr + (n >> UVSHIFT) * SBPP, SS(r, UVSHIFT) * SBPP); \
ANY_SIMD(temp, temp + 128, yuvconstants, MASK + 1); \
memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \
}
#if defined(HAS_YUY2TOARGBROW_SSSE3)
ANY11C(YUY2ToARGBRow_Any_SSSE3, YUY2ToARGBRow_SSSE3, 1, 4, 4, 15)
ANY11C(UYVYToARGBRow_Any_SSSE3, UYVYToARGBRow_SSSE3, 1, 4, 4, 15)
#endif
#if defined(HAS_YUY2TOARGBROW_AVX2)
ANY11C(YUY2ToARGBRow_Any_AVX2, YUY2ToARGBRow_AVX2, 1, 4, 4, 31)
ANY11C(UYVYToARGBRow_Any_AVX2, UYVYToARGBRow_AVX2, 1, 4, 4, 31)
#endif
#if defined(HAS_YUY2TOARGBROW_NEON)
ANY11C(YUY2ToARGBRow_Any_NEON, YUY2ToARGBRow_NEON, 1, 4, 4, 7)
ANY11C(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, 1, 4, 4, 7)
#endif
#undef ANY11C
// Any 1 to 1 blended.
// Any 1 to 1 blended. Destination is read, modify, write.
#define ANY11B(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \
void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, int width) { \
SIMD_ALIGNED(uint8 temp[128 * 2]); \
@ -516,7 +493,7 @@ ANY11C(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, 1, 4, 4, 7)
#ifdef HAS_ARGBCOPYALPHAROW_AVX2
ANY11B(ARGBCopyAlphaRow_Any_AVX2, ARGBCopyAlphaRow_AVX2, 0, 4, 4, 15)
#endif
#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2
#ifdef HAS_ARGBCOPYALPHAROW_SSE2
ANY11B(ARGBCopyAlphaRow_Any_SSE2, ARGBCopyAlphaRow_SSE2, 0, 4, 4, 7)
#endif
#ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2
@ -569,6 +546,35 @@ ANY11P(ARGBShuffleRow_Any_NEON, ARGBShuffleRow_NEON, const uint8*, 4, 4, 3)
#endif
#undef ANY11P
// Any 1 to 1 with yuvconstants
#define ANY11C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \
void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, \
const struct YuvConstants* yuvconstants, int width) { \
SIMD_ALIGNED(uint8 temp[128 * 2]); \
memset(temp, 0, 128); /* for YUY2 and msan */ \
int r = width & MASK; \
int n = width & ~MASK; \
if (n > 0) { \
ANY_SIMD(src_ptr, dst_ptr, yuvconstants, n); \
} \
memcpy(temp, src_ptr + (n >> UVSHIFT) * SBPP, SS(r, UVSHIFT) * SBPP); \
ANY_SIMD(temp, temp + 128, yuvconstants, MASK + 1); \
memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \
}
#if defined(HAS_YUY2TOARGBROW_SSSE3)
ANY11C(YUY2ToARGBRow_Any_SSSE3, YUY2ToARGBRow_SSSE3, 1, 4, 4, 15)
ANY11C(UYVYToARGBRow_Any_SSSE3, UYVYToARGBRow_SSSE3, 1, 4, 4, 15)
#endif
#if defined(HAS_YUY2TOARGBROW_AVX2)
ANY11C(YUY2ToARGBRow_Any_AVX2, YUY2ToARGBRow_AVX2, 1, 4, 4, 31)
ANY11C(UYVYToARGBRow_Any_AVX2, UYVYToARGBRow_AVX2, 1, 4, 4, 31)
#endif
#if defined(HAS_YUY2TOARGBROW_NEON)
ANY11C(YUY2ToARGBRow_Any_NEON, YUY2ToARGBRow_NEON, 1, 4, 4, 7)
ANY11C(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, 1, 4, 4, 7)
#endif
#undef ANY11C
// Any 1 to 1 interpolate. Takes 2 rows of source via stride.
#define ANY11T(NAMEANY, ANY_SIMD, SBPP, BPP, MASK) \
void NAMEANY(uint8* dst_ptr, const uint8* src_ptr, \
@ -625,6 +631,9 @@ ANY11M(MirrorRow_Any_SSSE3, MirrorRow_SSSE3, 1, 15)
#ifdef HAS_MIRRORROW_NEON
ANY11M(MirrorRow_Any_NEON, MirrorRow_NEON, 1, 15)
#endif
#ifdef HAS_MIRRORROW_MSA
ANY11M(MirrorRow_Any_MSA, MirrorRow_MSA, 1, 63)
#endif
#ifdef HAS_ARGBMIRRORROW_AVX2
ANY11M(ARGBMirrorRow_Any_AVX2, ARGBMirrorRow_AVX2, 4, 7)
#endif
@ -634,6 +643,9 @@ ANY11M(ARGBMirrorRow_Any_SSE2, ARGBMirrorRow_SSE2, 4, 3)
#ifdef HAS_ARGBMIRRORROW_NEON
ANY11M(ARGBMirrorRow_Any_NEON, ARGBMirrorRow_NEON, 4, 3)
#endif
#ifdef HAS_ARGBMIRRORROW_MSA
ANY11M(ARGBMirrorRow_Any_MSA, ARGBMirrorRow_MSA, 4, 15)
#endif
#undef ANY11M
// Any 1 plane. (memset)

View File

@ -988,8 +988,8 @@ void J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
#define BG (UG * 128 + VG * 128 + YGB)
#define BR (VR * 128 + YGB)
#if defined(__aarch64__)
const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
#if defined(__aarch64__) // 64 bit arm
const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ UG, VG, UG, VG, UG, VG, UG, VG },
@ -997,7 +997,7 @@ const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ VG, UG, VG, UG, VG, UG, VG, UG },
@ -1005,21 +1005,21 @@ const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
#elif defined(__arm__)
const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
#elif defined(__arm__) // 32 bit arm
const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
#else
const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
@ -1031,7 +1031,7 @@ const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
};
const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
@ -1076,7 +1076,7 @@ const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
#define BR (VR * 128 + YGB)
#if defined(__aarch64__)
const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ UG, VG, UG, VG, UG, VG, UG, VG },
@ -1084,7 +1084,7 @@ const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ VG, UG, VG, UG, VG, UG, VG, UG },
@ -1093,20 +1093,20 @@ const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ 0x0101 * YG, 0, 0, 0 }
};
#elif defined(__arm__)
const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
#else
const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
@ -1118,7 +1118,7 @@ const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
};
const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
@ -1164,7 +1164,7 @@ const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
#define BR (VR * 128 + YGB)
#if defined(__aarch64__)
const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ UG, VG, UG, VG, UG, VG, UG, VG },
@ -1172,7 +1172,7 @@ const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ VG, UG, VG, UG, VG, UG, VG, UG },
@ -1181,20 +1181,20 @@ const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ 0x0101 * YG, 0, 0, 0 }
};
#elif defined(__arm__)
const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 }
};
#else
const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
@ -1206,7 +1206,7 @@ const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
};
const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
@ -1264,9 +1264,9 @@ static __inline void YuvPixel(uint8 y, uint8 u, uint8 v,
#endif
uint32 y1 = (uint32)(y * 0x0101 * yg) >> 16;
*b = Clamp((int32)(-(u * ub ) + y1 + bb) >> 6);
*b = Clamp((int32)(-(u * ub) + y1 + bb) >> 6);
*g = Clamp((int32)(-(u * ug + v * vg) + y1 + bg) >> 6);
*r = Clamp((int32)(-( v * vr) + y1 + br) >> 6);
*r = Clamp((int32) (-(v * vr) + y1 + br) >> 6);
}
// Y contribution to R,G,B. Scale and bias.
@ -2167,7 +2167,7 @@ static void HalfRow_16_C(const uint16* src_uv, ptrdiff_t src_uv_stride,
void InterpolateRow_C(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride,
int width, int source_y_fraction) {
int y1_fraction = source_y_fraction ;
int y1_fraction = source_y_fraction;
int y0_fraction = 256 - y1_fraction;
const uint8* src_ptr1 = src_ptr + src_stride;
int x;
@ -2381,6 +2381,19 @@ void ARGBCopyAlphaRow_C(const uint8* src, uint8* dst, int width) {
}
}
void ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width) {
int i;
for (i = 0; i < width - 1; i += 2) {
dst_a[0] = src_argb[3];
dst_a[1] = src_argb[7];
dst_a += 2;
src_argb += 8;
}
if (width & 1) {
dst_a[0] = src_argb[3];
}
}
void ARGBCopyYToAlphaRow_C(const uint8* src, uint8* dst, int width) {
int i;
for (i = 0; i < width - 1; i += 2) {
@ -2491,7 +2504,7 @@ void I422ToRGB565Row_AVX2(const uint8* src_y,
uint8* dst_rgb565,
const struct YuvConstants* yuvconstants,
int width) {
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]);
SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2517,7 +2530,7 @@ void I422ToARGB1555Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants,
int width) {
// Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]);
SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2543,7 +2556,7 @@ void I422ToARGB4444Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants,
int width) {
// Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]);
SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2569,7 +2582,7 @@ void I422ToRGB24Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants,
int width) {
// Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]);
SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2591,7 +2604,7 @@ void NV12ToRGB565Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants,
int width) {
// Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]);
SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
NV12ToARGBRow_AVX2(src_y, src_uv, row, yuvconstants, twidth);

View File

@ -2936,6 +2936,33 @@ void ARGBCopyAlphaRow_AVX2(const uint8* src, uint8* dst, int width) {
}
#endif // HAS_ARGBCOPYALPHAROW_AVX2
#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2
// width in pixels
void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width) {
asm volatile (
LABELALIGN
"1: \n"
"movdqu " MEMACCESS(0) ", %%xmm0 \n"
"movdqu " MEMACCESS2(0x10, 0) ", %%xmm1 \n"
"lea " MEMLEA(0x20, 0) ", %0 \n"
"psrld $0x18, %%xmm0 \n"
"psrld $0x18, %%xmm1 \n"
"packssdw %%xmm1, %%xmm0 \n"
"packuswb %%xmm0, %%xmm0 \n"
"movq %%xmm0," MEMACCESS(1) " \n"
"lea " MEMLEA(0x8, 1) ", %1 \n"
"sub $0x8, %2 \n"
"jg 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_a), // %1
"+rm"(width) // %2
:
: "memory", "cc"
, "xmm0", "xmm1"
);
}
#endif // HAS_ARGBEXTRACTALPHAROW_SSE2
#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2
// width in pixels
void ARGBCopyYToAlphaRow_SSE2(const uint8* src, uint8* dst, int width) {
@ -3569,7 +3596,7 @@ void BlendPlaneRow_SSSE3(const uint8* src0, const uint8* src1,
"+r"(src1), // %1
"+r"(alpha), // %2
"+r"(dst), // %3
"+r"(width) // %4
"+rm"(width) // %4
:: "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm5", "xmm6", "xmm7"
);
}
@ -3626,7 +3653,7 @@ void BlendPlaneRow_AVX2(const uint8* src0, const uint8* src1,
"+r"(src1), // %1
"+r"(alpha), // %2
"+r"(dst), // %3
"+r"(width) // %4
"+rm"(width) // %4
:: "memory", "cc", "eax",
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
);
@ -4909,9 +4936,9 @@ void InterpolateRow_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"jg 100b \n"
"99: \n"
: "+r"(dst_ptr), // %0
"+r"(src_ptr), // %1
"+r"(dst_width), // %2
: "+r"(dst_ptr), // %0
"+r"(src_ptr), // %1
"+rm"(dst_width), // %2
"+r"(source_y_fraction) // %3
: "r"((intptr_t)(src_stride)) // %4
: "memory", "cc", "eax", NACL_R14
@ -4987,7 +5014,7 @@ void InterpolateRow_AVX2(uint8* dst_ptr, const uint8* src_ptr,
"999: \n"
: "+D"(dst_ptr), // %0
"+S"(src_ptr), // %1
"+c"(dst_width), // %2
"+cm"(dst_width), // %2
"+r"(source_y_fraction) // %3
: "r"((intptr_t)(src_stride)) // %4
: "memory", "cc", "eax", NACL_R14

View File

@ -381,7 +381,7 @@ void CopyRow_MIPS(const uint8* src, uint8* dst, int count) {
(_MIPS_SIM == _MIPS_SIM_ABI32) && (__mips_isa_rev < 6)
void SplitUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) {
int width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -497,7 +497,7 @@ void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width) {
}
void MirrorUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) {
int width) {
int x;
int y;
__asm__ __volatile__ (
@ -654,11 +654,11 @@ void MirrorUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
// TODO(fbarchard): accept yuv conversion constants.
void I422ToARGBRow_DSPR2(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
const struct YuvConstants* yuvconstants,
int width) {
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
const struct YuvConstants* yuvconstants,
int width) {
__asm__ __volatile__ (
".set push \n"
".set noreorder \n"
@ -717,8 +717,8 @@ void I422ToARGBRow_DSPR2(const uint8* y_buf,
// Bilinear filter 8x2 -> 8x1
void InterpolateRow_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride, int dst_width,
int source_y_fraction) {
ptrdiff_t src_stride, int dst_width,
int source_y_fraction) {
int y0_fraction = 256 - source_y_fraction;
const uint8* src_ptr1 = src_ptr + src_stride;

View File

@ -0,0 +1,61 @@
/*
* Copyright 2016 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "libyuv/row.h"
// This module is for GCC MSA
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#include "libyuv/macros_msa.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
void MirrorRow_MSA(const uint8* src, uint8* dst, int width) {
int x;
v16u8 src0, src1, src2, src3;
v16u8 dst0, dst1, dst2, dst3;
v16i8 shuffler = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
src += width - 64;
for (x = 0; x < width; x += 64) {
LD_UB4(src, 16, src3, src2, src1, src0);
VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2);
VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0);
ST_UB4(dst0, dst1, dst2, dst3, dst, 16);
dst += 64;
src -= 64;
}
}
void ARGBMirrorRow_MSA(const uint8* src, uint8* dst, int width) {
int x;
v16u8 src0, src1, src2, src3;
v16u8 dst0, dst1, dst2, dst3;
v16i8 shuffler = { 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3 };
src += width * 4 - 64;
for (x = 0; x < width; x += 16) {
LD_UB4(src, 16, src3, src2, src1, src0);
VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2);
VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0);
ST_UB4(dst0, dst1, dst2, dst3, dst, 16);
dst += 64;
src -= 64;
}
}
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)

View File

@ -1298,6 +1298,24 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
);
}
void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) {
asm volatile (
"1: \n"
MEMACCESS(0)
"vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels
"vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels
"subs %2, %2, #16 \n" // 16 processed per loop
MEMACCESS(1)
"vst1.8 {q3}, [%1]! \n" // store 16 A's.
"bgt 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_a), // %1
"+r"(width) // %2
:
: "cc", "memory", "q0", "q1", "q2", "q3" // Clobber List
);
}
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
asm volatile (
"vmov.u8 d24, #15 \n" // B * 0.11400 coefficient
@ -2565,8 +2583,6 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
);
}
// TODO(fbarchard): fix vqshrun in ARGBMultiplyRow_NEON and reenable.
#ifdef HAS_ARGBMULTIPLYROW_NEON
// Multiply 2 rows of ARGB pixels together, 8 pixels at a time.
void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
@ -2598,7 +2614,6 @@ void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "q0", "q1", "q2", "q3"
);
}
#endif // HAS_ARGBMULTIPLYROW_NEON
// Add 2 rows of ARGB pixels together, 8 pixels at a time.
void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1,

View File

@ -127,7 +127,6 @@ extern "C" {
"sqshrun " #vG ".8b, " #vG ".8h, #6 \n" /* G */ \
"sqshrun " #vR ".8b, " #vR ".8h, #6 \n" /* R */ \
#ifdef HAS_I444TOARGBROW_NEON
void I444ToARGBRow_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -157,9 +156,7 @@ void I444ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I444TOARGBROW_NEON
#ifdef HAS_I422TOARGBROW_NEON
void I422ToARGBRow_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -189,9 +186,7 @@ void I422ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I422TOARGBROW_NEON
#ifdef HAS_I422ALPHATOARGBROW_NEON
void I422AlphaToARGBRow_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -224,9 +219,7 @@ void I422AlphaToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I422ALPHATOARGBROW_NEON
#ifdef HAS_I411TOARGBROW_NEON
void I411ToARGBRow_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -256,9 +249,7 @@ void I411ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I411TOARGBROW_NEON
#ifdef HAS_I422TORGBAROW_NEON
void I422ToRGBARow_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -288,9 +279,7 @@ void I422ToRGBARow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I422TORGBAROW_NEON
#ifdef HAS_I422TORGB24ROW_NEON
void I422ToRGB24Row_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -319,7 +308,6 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I422TORGB24ROW_NEON
#define ARGBTORGB565 \
"shll v0.8h, v22.8b, #8 \n" /* R */ \
@ -328,7 +316,6 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
"sri v0.8h, v21.8h, #5 \n" /* RG */ \
"sri v0.8h, v20.8h, #11 \n" /* RGB */
#ifdef HAS_I422TORGB565ROW_NEON
void I422ToRGB565Row_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -358,7 +345,6 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I422TORGB565ROW_NEON
#define ARGBTOARGB1555 \
"shll v0.8h, v23.8b, #8 \n" /* A */ \
@ -369,7 +355,6 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
"sri v0.8h, v21.8h, #6 \n" /* ARG */ \
"sri v0.8h, v20.8h, #11 \n" /* ARGB */
#ifdef HAS_I422TOARGB1555ROW_NEON
void I422ToARGB1555Row_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -400,7 +385,6 @@ void I422ToARGB1555Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I422TOARGB1555ROW_NEON
#define ARGBTOARGB4444 \
/* Input v20.8b<=B, v21.8b<=G, v22.8b<=R, v23.8b<=A, v4.8b<=0x0f */ \
@ -412,7 +396,6 @@ void I422ToARGB1555Row_NEON(const uint8* src_y,
"orr v1.8b, v22.8b, v23.8b \n" /* RA */ \
"zip1 v0.16b, v0.16b, v1.16b \n" /* BGRA */
#ifdef HAS_I422TOARGB4444ROW_NEON
void I422ToARGB4444Row_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -444,13 +427,10 @@ void I422ToARGB4444Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I422TOARGB4444ROW_NEON
#ifdef HAS_I400TOARGBROW_NEON
void I400ToARGBRow_NEON(const uint8* src_y,
uint8* dst_argb,
int width) {
int64 width64 = (int64)(width);
asm volatile (
YUVTORGB_SETUP
"movi v23.8b, #255 \n"
@ -463,7 +443,7 @@ void I400ToARGBRow_NEON(const uint8* src_y,
"b.gt 1b \n"
: "+r"(src_y), // %0
"+r"(dst_argb), // %1
"+r"(width64) // %2
"+r"(width) // %2
: [kUVToRB]"r"(&kYuvI601Constants.kUVToRB),
[kUVToG]"r"(&kYuvI601Constants.kUVToG),
[kUVBiasBGR]"r"(&kYuvI601Constants.kUVBiasBGR),
@ -472,9 +452,7 @@ void I400ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_I400TOARGBROW_NEON
#ifdef HAS_J400TOARGBROW_NEON
void J400ToARGBRow_NEON(const uint8* src_y,
uint8* dst_argb,
int width) {
@ -496,9 +474,7 @@ void J400ToARGBRow_NEON(const uint8* src_y,
: "cc", "memory", "v20", "v21", "v22", "v23"
);
}
#endif // HAS_J400TOARGBROW_NEON
#ifdef HAS_NV12TOARGBROW_NEON
void NV12ToARGBRow_NEON(const uint8* src_y,
const uint8* src_uv,
uint8* dst_argb,
@ -526,9 +502,7 @@ void NV12ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_NV12TOARGBROW_NEON
#ifdef HAS_NV12TOARGBROW_NEON
void NV21ToARGBRow_NEON(const uint8* src_y,
const uint8* src_vu,
uint8* dst_argb,
@ -556,9 +530,7 @@ void NV21ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_NV12TOARGBROW_NEON
#ifdef HAS_NV12TORGB565ROW_NEON
void NV12ToRGB565Row_NEON(const uint8* src_y,
const uint8* src_uv,
uint8* dst_rgb565,
@ -586,14 +558,11 @@ void NV12ToRGB565Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_NV12TORGB565ROW_NEON
#ifdef HAS_YUY2TOARGBROW_NEON
void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width) {
int64 width64 = (int64)(width);
asm volatile (
YUVTORGB_SETUP
"movi v23.8b, #255 \n"
@ -606,7 +575,7 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
"b.gt 1b \n"
: "+r"(src_yuy2), // %0
"+r"(dst_argb), // %1
"+r"(width64) // %2
"+r"(width) // %2
: [kUVToRB]"r"(&yuvconstants->kUVToRB),
[kUVToG]"r"(&yuvconstants->kUVToG),
[kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR),
@ -615,14 +584,11 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_YUY2TOARGBROW_NEON
#ifdef HAS_UYVYTOARGBROW_NEON
void UYVYToARGBRow_NEON(const uint8* src_uyvy,
uint8* dst_argb,
const struct YuvConstants* yuvconstants,
int width) {
int64 width64 = (int64)(width);
asm volatile (
YUVTORGB_SETUP
"movi v23.8b, #255 \n"
@ -635,7 +601,7 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy,
"b.gt 1b \n"
: "+r"(src_uyvy), // %0
"+r"(dst_argb), // %1
"+r"(width64) // %2
"+r"(width) // %2
: [kUVToRB]"r"(&yuvconstants->kUVToRB),
[kUVToG]"r"(&yuvconstants->kUVToG),
[kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR),
@ -644,10 +610,8 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
);
}
#endif // HAS_UYVYTOARGBROW_NEON
// Reads 16 pairs of UV and write even values to dst_u and odd to dst_v.
#ifdef HAS_SPLITUVROW_NEON
void SplitUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) {
asm volatile (
@ -668,10 +632,8 @@ void SplitUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
: "cc", "memory", "v0", "v1" // Clobber List
);
}
#endif // HAS_SPLITUVROW_NEON
// Reads 16 U's and V's and writes out 16 pairs of UV.
#ifdef HAS_MERGEUVROW_NEON
void MergeUVRow_NEON(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width) {
asm volatile (
@ -693,10 +655,8 @@ void MergeUVRow_NEON(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
: "cc", "memory", "v0", "v1" // Clobber List
);
}
#endif // HAS_MERGEUVROW_NEON
// Copy multiple of 32. vld4.8 allow unaligned and is fastest on a15.
#ifdef HAS_COPYROW_NEON
void CopyRow_NEON(const uint8* src, uint8* dst, int count) {
asm volatile (
"1: \n"
@ -713,17 +673,16 @@ void CopyRow_NEON(const uint8* src, uint8* dst, int count) {
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
#endif // HAS_COPYROW_NEON
// SetRow writes 'count' bytes using an 8 bit value repeated.
void SetRow_NEON(uint8* dst, uint8 v8, int count) {
asm volatile (
"dup v0.16b, %w2 \n" // duplicate 16 bytes
"1: \n"
"subs %w1, %w1, #16 \n" // 16 bytes per loop
"subs %w1, %w1, #16 \n" // 16 bytes per loop
MEMACCESS(0)
"st1 {v0.16b}, [%0], #16 \n" // store
"b.gt 1b \n"
"b.gt 1b \n"
: "+r"(dst), // %0
"+r"(count) // %1
: "r"(v8) // %2
@ -735,10 +694,10 @@ void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) {
asm volatile (
"dup v0.4s, %w2 \n" // duplicate 4 ints
"1: \n"
"subs %w1, %w1, #4 \n" // 4 ints per loop
"subs %w1, %w1, #4 \n" // 4 ints per loop
MEMACCESS(0)
"st1 {v0.16b}, [%0], #16 \n" // store
"b.gt 1b \n"
"b.gt 1b \n"
: "+r"(dst), // %0
"+r"(count) // %1
: "r"(v32) // %2
@ -746,18 +705,15 @@ void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) {
);
}
#ifdef HAS_MIRRORROW_NEON
void MirrorRow_NEON(const uint8* src, uint8* dst, int width) {
int64 width64 = (int64) width;
asm volatile (
// Start at end of source row.
"add %0, %0, %2 \n"
"add %0, %0, %w2, sxtw \n"
"sub %0, %0, #16 \n"
"1: \n"
MEMACCESS(0)
"ld1 {v0.16b}, [%0], %3 \n" // src -= 16
"subs %2, %2, #16 \n" // 16 pixels per loop.
"subs %w2, %w2, #16 \n" // 16 pixels per loop.
"rev64 v0.16b, v0.16b \n"
MEMACCESS(1)
"st1 {v0.D}[1], [%1], #8 \n" // dst += 16
@ -766,26 +722,22 @@ void MirrorRow_NEON(const uint8* src, uint8* dst, int width) {
"b.gt 1b \n"
: "+r"(src), // %0
"+r"(dst), // %1
"+r"(width64) // %2
"+r"(width) // %2
: "r"((ptrdiff_t)-16) // %3
: "cc", "memory", "v0"
);
}
#endif // HAS_MIRRORROW_NEON
#ifdef HAS_MIRRORUVROW_NEON
void MirrorUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) {
int64 width64 = (int64) width;
asm volatile (
// Start at end of source row.
"add %0, %0, %3, lsl #1 \n"
"add %0, %0, %w3, sxtw #1 \n"
"sub %0, %0, #16 \n"
"1: \n"
MEMACCESS(0)
"ld2 {v0.8b, v1.8b}, [%0], %4 \n" // src -= 16
"subs %3, %3, #8 \n" // 8 pixels per loop.
"subs %w3, %w3, #8 \n" // 8 pixels per loop.
"rev64 v0.8b, v0.8b \n"
"rev64 v1.8b, v1.8b \n"
MEMACCESS(1)
@ -796,25 +748,21 @@ void MirrorUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
: "+r"(src_uv), // %0
"+r"(dst_u), // %1
"+r"(dst_v), // %2
"+r"(width64) // %3
"+r"(width) // %3
: "r"((ptrdiff_t)-16) // %4
: "cc", "memory", "v0", "v1"
);
}
#endif // HAS_MIRRORUVROW_NEON
#ifdef HAS_ARGBMIRRORROW_NEON
void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) {
int64 width64 = (int64) width;
asm volatile (
// Start at end of source row.
"add %0, %0, %2, lsl #2 \n"
// Start at end of source row.
"add %0, %0, %w2, sxtw #2 \n"
"sub %0, %0, #16 \n"
"1: \n"
MEMACCESS(0)
"ld1 {v0.16b}, [%0], %3 \n" // src -= 16
"subs %2, %2, #4 \n" // 4 pixels per loop.
"subs %w2, %w2, #4 \n" // 4 pixels per loop.
"rev64 v0.4s, v0.4s \n"
MEMACCESS(1)
"st1 {v0.D}[1], [%1], #8 \n" // dst += 16
@ -823,14 +771,12 @@ void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) {
"b.gt 1b \n"
: "+r"(src), // %0
"+r"(dst), // %1
"+r"(width64) // %2
"+r"(width) // %2
: "r"((ptrdiff_t)-16) // %3
: "cc", "memory", "v0"
);
}
#endif // HAS_ARGBMIRRORROW_NEON
#ifdef HAS_RGB24TOARGBROW_NEON
void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) {
asm volatile (
"movi v4.8b, #255 \n" // Alpha
@ -843,14 +789,12 @@ void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) {
"b.gt 1b \n"
: "+r"(src_rgb24), // %0
"+r"(dst_argb), // %1
"+r"(width) // %2
"+r"(width) // %2
:
: "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List
);
}
#endif // HAS_RGB24TOARGBROW_NEON
#ifdef HAS_RAWTOARGBROW_NEON
void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) {
asm volatile (
"movi v5.8b, #255 \n" // Alpha
@ -865,12 +809,11 @@ void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) {
"b.gt 1b \n"
: "+r"(src_raw), // %0
"+r"(dst_argb), // %1
"+r"(width) // %2
"+r"(width) // %2
:
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5" // Clobber List
);
}
#endif // HAS_RAWTOARGBROW_NEON
void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) {
asm volatile (
@ -904,7 +847,6 @@ void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) {
"orr v0.16b, v0.16b, v2.16b \n" /* R,B */ \
"dup v2.2D, v0.D[1] \n" /* R */
#ifdef HAS_RGB565TOARGBROW_NEON
void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) {
asm volatile (
"movi v3.8b, #255 \n" // Alpha
@ -923,7 +865,6 @@ void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v6" // Clobber List
);
}
#endif // HAS_RGB565TOARGBROW_NEON
#define ARGB1555TOARGB \
"ushr v2.8h, v0.8h, #10 \n" /* R xxxRRRRR */ \
@ -962,7 +903,6 @@ void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) {
"orr v2.16b, v1.16b, v3.16b \n" /* R */ \
"dup v1.2D, v0.D[1] \n" /* G */ \
#ifdef HAS_ARGB1555TOARGBROW_NEON
void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb,
int width) {
asm volatile (
@ -982,7 +922,6 @@ void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
#endif // HAS_ARGB1555TOARGBROW_NEON
#define ARGB4444TOARGB \
"shrn v1.8b, v0.8h, #8 \n" /* v1(l) AR */ \
@ -996,7 +935,6 @@ void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb,
"dup v0.2D, v2.D[1] \n" \
"dup v1.2D, v3.D[1] \n"
#ifdef HAS_ARGB4444TOARGBROW_NEON
void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, uint8* dst_argb,
int width) {
asm volatile (
@ -1015,9 +953,7 @@ void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, uint8* dst_argb,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4" // Clobber List
);
}
#endif // HAS_ARGB4444TOARGBROW_NEON
#ifdef HAS_ARGBTORGB24ROW_NEON
void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) {
asm volatile (
"1: \n"
@ -1034,9 +970,7 @@ void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) {
: "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List
);
}
#endif // HAS_ARGBTORGB24ROW_NEON
#ifdef HAS_ARGBTORAWROW_NEON
void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) {
asm volatile (
"1: \n"
@ -1055,9 +989,7 @@ void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) {
: "cc", "memory", "v1", "v2", "v3", "v4", "v5" // Clobber List
);
}
#endif // HAS_ARGBTORAWROW_NEON
#ifdef HAS_YUY2TOYROW_NEON
void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) {
asm volatile (
"1: \n"
@ -1074,9 +1006,7 @@ void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1" // Clobber List
);
}
#endif // HAS_YUY2TOYROW_NEON
#ifdef HAS_UYVYTOYROW_NEON
void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) {
asm volatile (
"1: \n"
@ -1093,9 +1023,7 @@ void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1" // Clobber List
);
}
#endif // HAS_UYVYTOYROW_NEON
#ifdef HAS_YUY2TOUV422ROW_NEON
void YUY2ToUV422Row_NEON(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v,
int width) {
asm volatile (
@ -1116,9 +1044,7 @@ void YUY2ToUV422Row_NEON(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
#endif // HAS_YUY2TOUV422ROW_NEON
#ifdef HAS_UYVYTOUV422ROW_NEON
void UYVYToUV422Row_NEON(const uint8* src_uyvy, uint8* dst_u, uint8* dst_v,
int width) {
asm volatile (
@ -1139,9 +1065,7 @@ void UYVYToUV422Row_NEON(const uint8* src_uyvy, uint8* dst_u, uint8* dst_v,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
#endif // HAS_UYVYTOUV422ROW_NEON
#ifdef HAS_YUY2TOUVROW_NEON
void YUY2ToUVRow_NEON(const uint8* src_yuy2, int stride_yuy2,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_yuy2b = src_yuy2 + stride_yuy2;
@ -1169,9 +1093,7 @@ void YUY2ToUVRow_NEON(const uint8* src_yuy2, int stride_yuy2,
"v5", "v6", "v7" // Clobber List
);
}
#endif // HAS_YUY2TOUVROW_NEON
#ifdef HAS_UYVYTOUVROW_NEON
void UYVYToUVRow_NEON(const uint8* src_uyvy, int stride_uyvy,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_uyvyb = src_uyvy + stride_uyvy;
@ -1199,10 +1121,8 @@ void UYVYToUVRow_NEON(const uint8* src_uyvy, int stride_uyvy,
"v5", "v6", "v7" // Clobber List
);
}
#endif // HAS_UYVYTOUVROW_NEON
// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA.
#ifdef HAS_ARGBSHUFFLEROW_NEON
void ARGBShuffleRow_NEON(const uint8* src_argb, uint8* dst_argb,
const uint8* shuffler, int width) {
asm volatile (
@ -1223,9 +1143,7 @@ void ARGBShuffleRow_NEON(const uint8* src_argb, uint8* dst_argb,
: "cc", "memory", "v0", "v1", "v2" // Clobber List
);
}
#endif // HAS_ARGBSHUFFLEROW_NEON
#ifdef HAS_I422TOYUY2ROW_NEON
void I422ToYUY2Row_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -1252,9 +1170,7 @@ void I422ToYUY2Row_NEON(const uint8* src_y,
: "cc", "memory", "v0", "v1", "v2", "v3"
);
}
#endif // HAS_I422TOYUY2ROW_NEON
#ifdef HAS_I422TOUYVYROW_NEON
void I422ToUYVYRow_NEON(const uint8* src_y,
const uint8* src_u,
const uint8* src_v,
@ -1281,9 +1197,7 @@ void I422ToUYVYRow_NEON(const uint8* src_y,
: "cc", "memory", "v0", "v1", "v2", "v3"
);
}
#endif // HAS_I422TOUYVYROW_NEON
#ifdef HAS_ARGBTORGB565ROW_NEON
void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) {
asm volatile (
"1: \n"
@ -1301,9 +1215,7 @@ void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) {
: "cc", "memory", "v0", "v20", "v21", "v22", "v23"
);
}
#endif // HAS_ARGBTORGB565ROW_NEON
#ifdef HAS_ARGBTORGB565DITHERROW_NEON
void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, uint8* dst_rgb,
const uint32 dither4, int width) {
asm volatile (
@ -1326,9 +1238,7 @@ void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, uint8* dst_rgb,
: "cc", "memory", "v0", "v1", "v20", "v21", "v22", "v23"
);
}
#endif // HAS_ARGBTORGB565ROW_NEON
#ifdef HAS_ARGBTOARGB1555ROW_NEON
void ARGBToARGB1555Row_NEON(const uint8* src_argb, uint8* dst_argb1555,
int width) {
asm volatile (
@ -1347,9 +1257,7 @@ void ARGBToARGB1555Row_NEON(const uint8* src_argb, uint8* dst_argb1555,
: "cc", "memory", "v0", "v20", "v21", "v22", "v23"
);
}
#endif // HAS_ARGBTOARGB1555ROW_NEON
#ifdef HAS_ARGBTOARGB4444ROW_NEON
void ARGBToARGB4444Row_NEON(const uint8* src_argb, uint8* dst_argb4444,
int width) {
asm volatile (
@ -1369,9 +1277,7 @@ void ARGBToARGB4444Row_NEON(const uint8* src_argb, uint8* dst_argb4444,
: "cc", "memory", "v0", "v1", "v4", "v20", "v21", "v22", "v23"
);
}
#endif // HAS_ARGBTOARGB4444ROW_NEON
#ifdef HAS_ARGBTOYROW_NEON
void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -1397,9 +1303,24 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
);
}
#endif // HAS_ARGBTOYROW_NEON
#ifdef HAS_ARGBTOYJROW_NEON
void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) {
asm volatile (
"1: \n"
MEMACCESS(0)
"ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load row 16 pixels
"subs %w2, %w2, #16 \n" // 16 processed per loop
MEMACCESS(1)
"st1 {v3.16b}, [%1], #16 \n" // store 16 A's.
"b.gt 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_a), // %1
"+r"(width) // %2
:
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #15 \n" // B * 0.11400 coefficient
@ -1423,10 +1344,8 @@ void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"
);
}
#endif // HAS_ARGBTOYJROW_NEON
// 8x1 pixels.
#ifdef HAS_ARGBTOUV444ROW_NEON
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) {
asm volatile (
@ -1467,7 +1386,6 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
"v24", "v25", "v26", "v27", "v28", "v29"
);
}
#endif // HAS_ARGBTOUV444ROW_NEON
#define RGBTOUV_SETUP_REG \
"movi v20.8h, #56, lsl #0 \n" /* UB/VR coefficient (0.875) / 2 */ \
@ -1478,7 +1396,6 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
"movi v25.16b, #0x80 \n" /* 128.5 (0x8080 in 16-bit) */
// 32x1 pixels -> 8x1. width is number of argb pixels. e.g. 32.
#ifdef HAS_ARGBTOUV411ROW_NEON
void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) {
asm volatile (
@ -1528,7 +1445,6 @@ void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_ARGBTOUV411ROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#define RGBTOUV(QB, QG, QR) \
@ -1546,7 +1462,6 @@ void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
// TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr.
// TODO(fbarchard): consider ptrdiff_t for all strides.
#ifdef HAS_ARGBTOUVROW_NEON
void ARGBToUVRow_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb_1 = src_argb + src_stride_argb;
@ -1586,10 +1501,8 @@ void ARGBToUVRow_NEON(const uint8* src_argb, int src_stride_argb,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_ARGBTOUVROW_NEON
// TODO(fbarchard): Subsample match C code.
#ifdef HAS_ARGBTOUVJROW_NEON
void ARGBToUVJRow_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb_1 = src_argb + src_stride_argb;
@ -1633,9 +1546,7 @@ void ARGBToUVJRow_NEON(const uint8* src_argb, int src_stride_argb,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_ARGBTOUVJROW_NEON
#ifdef HAS_BGRATOUVROW_NEON
void BGRAToUVRow_NEON(const uint8* src_bgra, int src_stride_bgra,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_bgra_1 = src_bgra + src_stride_bgra;
@ -1674,9 +1585,7 @@ void BGRAToUVRow_NEON(const uint8* src_bgra, int src_stride_bgra,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_BGRATOUVROW_NEON
#ifdef HAS_ABGRTOUVROW_NEON
void ABGRToUVRow_NEON(const uint8* src_abgr, int src_stride_abgr,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_abgr_1 = src_abgr + src_stride_abgr;
@ -1715,9 +1624,7 @@ void ABGRToUVRow_NEON(const uint8* src_abgr, int src_stride_abgr,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_ABGRTOUVROW_NEON
#ifdef HAS_RGBATOUVROW_NEON
void RGBAToUVRow_NEON(const uint8* src_rgba, int src_stride_rgba,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_rgba_1 = src_rgba + src_stride_rgba;
@ -1756,9 +1663,7 @@ void RGBAToUVRow_NEON(const uint8* src_rgba, int src_stride_rgba,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_RGBATOUVROW_NEON
#ifdef HAS_RGB24TOUVROW_NEON
void RGB24ToUVRow_NEON(const uint8* src_rgb24, int src_stride_rgb24,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_rgb24_1 = src_rgb24 + src_stride_rgb24;
@ -1797,9 +1702,7 @@ void RGB24ToUVRow_NEON(const uint8* src_rgb24, int src_stride_rgb24,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_RGB24TOUVROW_NEON
#ifdef HAS_RAWTOUVROW_NEON
void RAWToUVRow_NEON(const uint8* src_raw, int src_stride_raw,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_raw_1 = src_raw + src_stride_raw;
@ -1838,10 +1741,8 @@ void RAWToUVRow_NEON(const uint8* src_raw, int src_stride_raw,
"v20", "v21", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_RAWTOUVROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#ifdef HAS_RGB565TOUVROW_NEON
void RGB565ToUVRow_NEON(const uint8* src_rgb565, int src_stride_rgb565,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_rgb565_1 = src_rgb565 + src_stride_rgb565;
@ -1914,10 +1815,8 @@ void RGB565ToUVRow_NEON(const uint8* src_rgb565, int src_stride_rgb565,
"v25", "v26", "v27"
);
}
#endif // HAS_RGB565TOUVROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#ifdef HAS_ARGB1555TOUVROW_NEON
void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, int src_stride_argb1555,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb1555_1 = src_argb1555 + src_stride_argb1555;
@ -1985,10 +1884,8 @@ void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, int src_stride_argb1555,
"v26", "v27", "v28"
);
}
#endif // HAS_ARGB1555TOUVROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#ifdef HAS_ARGB4444TOUVROW_NEON
void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, int src_stride_argb4444,
uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb4444_1 = src_argb4444 + src_stride_argb4444;
@ -2057,9 +1954,7 @@ void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, int src_stride_argb4444,
);
}
#endif // HAS_ARGB4444TOUVROW_NEON
#ifdef HAS_RGB565TOYROW_NEON
void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) {
asm volatile (
"movi v24.8b, #13 \n" // B * 0.1016 coefficient
@ -2087,9 +1982,7 @@ void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) {
"v24", "v25", "v26", "v27"
);
}
#endif // HAS_RGB565TOYROW_NEON
#ifdef HAS_ARGB1555TOYROW_NEON
void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -2116,9 +2009,7 @@ void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
);
}
#endif // HAS_ARGB1555TOYROW_NEON
#ifdef HAS_ARGB4444TOYROW_NEON
void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) {
asm volatile (
"movi v24.8b, #13 \n" // B * 0.1016 coefficient
@ -2145,9 +2036,7 @@ void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v24", "v25", "v26", "v27"
);
}
#endif // HAS_ARGB4444TOYROW_NEON
#ifdef HAS_BGRATOYROW_NEON
void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #33 \n" // R * 0.2578 coefficient
@ -2173,9 +2062,7 @@ void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
);
}
#endif // HAS_BGRATOYROW_NEON
#ifdef HAS_ABGRTOYROW_NEON
void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #33 \n" // R * 0.2578 coefficient
@ -2201,9 +2088,7 @@ void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
);
}
#endif // HAS_ABGRTOYROW_NEON
#ifdef HAS_RGBATOYROW_NEON
void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -2229,9 +2114,7 @@ void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
);
}
#endif // HAS_RGBATOYROW_NEON
#ifdef HAS_RGB24TOYROW_NEON
void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -2257,9 +2140,7 @@ void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
);
}
#endif // HAS_RGB24TOYROW_NEON
#ifdef HAS_RAWTOYROW_NEON
void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) {
asm volatile (
"movi v4.8b, #33 \n" // R * 0.2578 coefficient
@ -2285,10 +2166,8 @@ void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
);
}
#endif // HAS_RAWTOYROW_NEON
// Bilinear filter 16x2 -> 16x1
#ifdef HAS_INTERPOLATEROW_NEON
void InterpolateRow_NEON(uint8* dst_ptr,
const uint8* src_ptr, ptrdiff_t src_stride,
int dst_width, int source_y_fraction) {
@ -2354,10 +2233,8 @@ void InterpolateRow_NEON(uint8* dst_ptr,
: "cc", "memory", "v0", "v1", "v3", "v4", "v5"
);
}
#endif // HAS_INTERPOLATEROW_NEON
// dr * (256 - sa) / 256 + sr = dr - dr * sa / 256 + sr
#ifdef HAS_ARGBBLENDROW_NEON
void ARGBBlendRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
asm volatile (
@ -2426,10 +2303,8 @@ void ARGBBlendRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
"v16", "v17", "v18"
);
}
#endif // HAS_ARGBBLENDROW_NEON
// Attenuate 8 pixels at a time.
#ifdef HAS_ARGBATTENUATEROW_NEON
void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
asm volatile (
// Attenuate 8 pixels.
@ -2453,11 +2328,9 @@ void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"
);
}
#endif // HAS_ARGBATTENUATEROW_NEON
// Quantize 8 ARGB pixels (32 bytes).
// dst = (dst * scale >> 16) * interval_size + interval_offset;
#ifdef HAS_ARGBQUANTIZEROW_NEON
void ARGBQuantizeRow_NEON(uint8* dst_argb, int scale, int interval_size,
int interval_offset, int width) {
asm volatile (
@ -2497,12 +2370,10 @@ void ARGBQuantizeRow_NEON(uint8* dst_argb, int scale, int interval_size,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"
);
}
#endif // HAS_ARGBQUANTIZEROW_NEON
// Shade 8 pixels at a time by specified value.
// NOTE vqrdmulh.s16 q10, q10, d0[0] must use a scaler register from 0 to 8.
// Rounding in vqrdmulh does +1 to high if high bit of low s16 is set.
#ifdef HAS_ARGBSHADEROW_NEON
void ARGBShadeRow_NEON(const uint8* src_argb, uint8* dst_argb, int width,
uint32 value) {
asm volatile (
@ -2537,12 +2408,10 @@ void ARGBShadeRow_NEON(const uint8* src_argb, uint8* dst_argb, int width,
: "cc", "memory", "v0", "v4", "v5", "v6", "v7"
);
}
#endif // HAS_ARGBSHADEROW_NEON
// Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels
// Similar to ARGBToYJ but stores ARGB.
// C code is (15 * b + 75 * g + 38 * r + 64) >> 7;
#ifdef HAS_ARGBGRAYROW_NEON
void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
asm volatile (
"movi v24.8b, #15 \n" // B * 0.11400 coefficient
@ -2568,14 +2437,12 @@ void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v24", "v25", "v26"
);
}
#endif // HAS_ARGBGRAYROW_NEON
// Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels.
// b = (r * 35 + g * 68 + b * 17) >> 7
// g = (r * 45 + g * 88 + b * 22) >> 7
// r = (r * 50 + g * 98 + b * 24) >> 7
#ifdef HAS_ARGBSEPIAROW_NEON
void ARGBSepiaRow_NEON(uint8* dst_argb, int width) {
asm volatile (
"movi v20.8b, #17 \n" // BB coefficient
@ -2613,12 +2480,10 @@ void ARGBSepiaRow_NEON(uint8* dst_argb, int width) {
"v20", "v21", "v22", "v24", "v25", "v26", "v28", "v29", "v30"
);
}
#endif // HAS_ARGBSEPIAROW_NEON
// Tranform 8 ARGB pixels (32 bytes) with color matrix.
// TODO(fbarchard): Was same as Sepia except matrix is provided. This function
// needs to saturate. Consider doing a non-saturating version.
#ifdef HAS_ARGBCOLORMATRIXROW_NEON
void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
const int8* matrix_argb, int width) {
asm volatile (
@ -2678,11 +2543,9 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
"v18", "v19", "v22", "v23", "v24", "v25"
);
}
#endif // HAS_ARGBCOLORMATRIXROW_NEON
// TODO(fbarchard): fix vqshrun in ARGBMultiplyRow_NEON and reenable.
// Multiply 2 rows of ARGB pixels together, 8 pixels at a time.
#ifdef HAS_ARGBMULTIPLYROW_NEON
void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
asm volatile (
@ -2713,10 +2576,8 @@ void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
);
}
#endif // HAS_ARGBMULTIPLYROW_NEON
// Add 2 rows of ARGB pixels together, 8 pixels at a time.
#ifdef HAS_ARGBADDROW_NEON
void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
asm volatile (
@ -2743,10 +2604,8 @@ void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
);
}
#endif // HAS_ARGBADDROW_NEON
// Subtract 2 rows of ARGB pixels, 8 pixels at a time.
#ifdef HAS_ARGBSUBTRACTROW_NEON
void ARGBSubtractRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) {
asm volatile (
@ -2773,14 +2632,12 @@ void ARGBSubtractRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
);
}
#endif // HAS_ARGBSUBTRACTROW_NEON
// Adds Sobel X and Sobel Y and stores Sobel into ARGB.
// A = 255
// R = Sobel
// G = Sobel
// B = Sobel
#ifdef HAS_SOBELROW_NEON
void SobelRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) {
asm volatile (
@ -2806,10 +2663,8 @@ void SobelRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
: "cc", "memory", "v0", "v1", "v2", "v3"
);
}
#endif // HAS_SOBELROW_NEON
// Adds Sobel X and Sobel Y and stores Sobel into plane.
#ifdef HAS_SOBELTOPLANEROW_NEON
void SobelToPlaneRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_y, int width) {
asm volatile (
@ -2832,14 +2687,12 @@ void SobelToPlaneRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
: "cc", "memory", "v0", "v1"
);
}
#endif // HAS_SOBELTOPLANEROW_NEON
// Mixes Sobel X, Sobel Y and Sobel into ARGB.
// A = 255
// R = Sobel X
// G = Sobel
// B = Sobel Y
#ifdef HAS_SOBELXYROW_NEON
void SobelXYRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) {
asm volatile (
@ -2863,13 +2716,11 @@ void SobelXYRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
: "cc", "memory", "v0", "v1", "v2", "v3"
);
}
#endif // HAS_SOBELXYROW_NEON
// SobelX as a matrix is
// -1 0 1
// -2 0 2
// -1 0 1
#ifdef HAS_SOBELXROW_NEON
void SobelXRow_NEON(const uint8* src_y0, const uint8* src_y1,
const uint8* src_y2, uint8* dst_sobelx, int width) {
asm volatile (
@ -2908,13 +2759,11 @@ void SobelXRow_NEON(const uint8* src_y0, const uint8* src_y1,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
#endif // HAS_SOBELXROW_NEON
// SobelY as a matrix is
// -1 -2 -1
// 0 0 0
// 1 2 1
#ifdef HAS_SOBELYROW_NEON
void SobelYRow_NEON(const uint8* src_y0, const uint8* src_y1,
uint8* dst_sobely, int width) {
asm volatile (
@ -2952,7 +2801,6 @@ void SobelYRow_NEON(const uint8* src_y0, const uint8* src_y1,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
#endif // HAS_SOBELYROW_NEON
#endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__)
#ifdef __cplusplus

View File

@ -10,8 +10,11 @@
#include "libyuv/row.h"
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_X64) && \
defined(_MSC_VER) && !defined(__clang__)
// This module is for Visual C 32/64 bit and clangcl 32 bit
#if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && \
(defined(_M_IX86) || (defined(_M_X64) && !defined(__clang__)))
#if defined(_M_X64)
#include <emmintrin.h>
#include <tmmintrin.h> // For _mm_maddubs_epi16
#endif
@ -21,10 +24,6 @@ namespace libyuv {
extern "C" {
#endif
// This module is for Visual C 32/64 bit and clangcl 32 bit
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(_M_IX86) || (defined(_M_X64) && !defined(__clang__)))
// 64 bit
#if defined(_M_X64)
@ -3532,6 +3531,33 @@ void ARGBCopyAlphaRow_AVX2(const uint8* src, uint8* dst, int width) {
}
#endif // HAS_ARGBCOPYALPHAROW_AVX2
#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2
// width in pixels
__declspec(naked)
void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width) {
__asm {
mov eax, [esp + 4] // src_argb
mov edx, [esp + 8] // dst_a
mov ecx, [esp + 12] // width
extractloop:
movdqu xmm0, [eax]
movdqu xmm1, [eax + 16]
lea eax, [eax + 32]
psrld xmm0, 24
psrld xmm1, 24
packssdw xmm0, xmm1
packuswb xmm0, xmm0
movq qword ptr [edx], xmm0
lea edx, [edx + 8]
sub ecx, 8
jg extractloop
ret
}
}
#endif // HAS_ARGBEXTRACTALPHAROW_SSE2
#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2
// width in pixels
__declspec(naked)
@ -5248,6 +5274,7 @@ void SobelXYRow_SSE2(const uint8* src_sobelx, const uint8* src_sobely,
// dst points to pixel to store result to.
// count is number of averaged pixels to produce.
// Does 4 pixels at a time.
// This function requires alignment on accumulation buffer pointers.
void CumulativeSumToAverageRow_SSE2(const int32* topleft, const int32* botleft,
int width, int area, uint8* dst,
int count) {
@ -6233,9 +6260,10 @@ void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, uint8* dst_argb,
#endif // HAS_ARGBLUMACOLORTABLEROW_SSSE3
#endif // defined(_M_X64)
#endif // !defined(LIBYUV_DISABLE_X86) && (defined(_M_IX86) || defined(_M_X64))
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // !defined(LIBYUV_DISABLE_X86) && (defined(_M_IX86) || defined(_M_X64))

View File

@ -1411,8 +1411,7 @@ void ScalePlane(const uint8* src, int src_stride,
}
if (dst_width <= Abs(src_width) && dst_height <= src_height) {
// Scale down.
if (4 * dst_width == 3 * src_width &&
4 * dst_height == 3 * src_height) {
if (4 * dst_width == 3 * src_width && 4 * dst_height == 3 * src_height) {
// optimized, 3/4
ScalePlaneDown34(src_width, src_height, dst_width, dst_height,
src_stride, dst_stride, src, dst, filtering);
@ -1425,8 +1424,7 @@ void ScalePlane(const uint8* src, int src_stride,
return;
}
// 3/8 rounded up for odd sized chroma height.
if (8 * dst_width == 3 * src_width &&
dst_height == ((src_height * 3 + 7) / 8)) {
if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) {
// optimized, 3/8
ScalePlaneDown38(src_width, src_height, dst_width, dst_height,
src_stride, dst_stride, src, dst, filtering);
@ -1508,8 +1506,7 @@ void ScalePlane_16(const uint16* src, int src_stride,
return;
}
// 3/8 rounded up for odd sized chroma height.
if (8 * dst_width == 3 * src_width &&
dst_height == ((src_height * 3 + 7) / 8)) {
if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) {
// optimized, 3/8
ScalePlaneDown38_16(src_width, src_height, dst_width, dst_height,
src_stride, dst_stride, src, dst, filtering);

View File

@ -417,8 +417,14 @@ void ScaleColsUp2_16_C(uint16* dst_ptr, const uint16* src_ptr,
}
// (1-f)a + fb can be replaced with a + f(b-a)
#if defined(__arm__) || defined(__aarch64__)
#define BLENDER(a, b, f) (uint8)((int)(a) + \
((int)(f) * ((int)(b) - (int)(a)) >> 16))
((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
#else
// Intel uses 7 bit math with rounding.
#define BLENDER(a, b, f) (uint8)((int)(a) + \
(((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7))
#endif
void ScaleFilterCols_C(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) {
@ -470,8 +476,9 @@ void ScaleFilterCols64_C(uint8* dst_ptr, const uint8* src_ptr,
}
#undef BLENDER
// Same as 8 bit arm blender but return is cast to uint16
#define BLENDER(a, b, f) (uint16)((int)(a) + \
((int)(f) * ((int)(b) - (int)(a)) >> 16))
((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
void ScaleFilterCols_16_C(uint16* dst_ptr, const uint16* src_ptr,
int dst_width, int x, int dx) {
@ -809,6 +816,7 @@ void ScaleARGBColsUp2_C(uint8* dst_argb, const uint8* src_argb,
}
}
// TODO(fbarchard): Replace 0x7f ^ f with 128-f. bug=607.
// Mimics SSSE3 blender
#define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b) * f) >> 7
#define BLENDERC(a, b, f, s) (uint32)( \

View File

@ -821,6 +821,16 @@ void ScaleAddRow_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width) {
}
#endif // HAS_SCALEADDROW_AVX2
// Constant for making pixels signed to avoid pmaddubsw
// saturation.
static uvec8 kFsub80 =
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
// Constant for making pixels unsigned and adding .5 for rounding.
static uvec16 kFadd40 =
{ 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040 };
// Bilinear column filtering. SSSE3 version.
void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) {
@ -831,7 +841,10 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"movl $0x04040000,%k2 \n"
"movd %k2,%%xmm5 \n"
"pcmpeqb %%xmm6,%%xmm6 \n"
"psrlw $0x9,%%xmm6 \n"
"psrlw $0x9,%%xmm6 \n" // 0x007f007f
"pcmpeqb %%xmm7,%%xmm7 \n"
"psrlw $15,%%xmm7 \n" // 0x00010001
"pextrw $0x1,%%xmm2,%k3 \n"
"subl $0x2,%5 \n"
"jl 29f \n"
@ -853,16 +866,19 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"movd %k2,%%xmm4 \n"
"pshufb %%xmm5,%%xmm1 \n"
"punpcklwd %%xmm4,%%xmm0 \n"
"pxor %%xmm6,%%xmm1 \n"
"pmaddubsw %%xmm1,%%xmm0 \n"
"psubb %8,%%xmm0 \n" // make pixels signed.
"pxor %%xmm6,%%xmm1 \n" // 128 - f = (f ^ 127 ) + 1
"paddusb %%xmm7,%%xmm1 \n"
"pmaddubsw %%xmm0,%%xmm1 \n"
"pextrw $0x1,%%xmm2,%k3 \n"
"pextrw $0x3,%%xmm2,%k4 \n"
"psrlw $0x7,%%xmm0 \n"
"packuswb %%xmm0,%%xmm0 \n"
"movd %%xmm0,%k2 \n"
"paddw %9,%%xmm1 \n" // make pixels unsigned.
"psrlw $0x7,%%xmm1 \n"
"packuswb %%xmm1,%%xmm1 \n"
"movd %%xmm1,%k2 \n"
"mov %w2," MEMACCESS(0) " \n"
"lea " MEMLEA(0x2,0) ",%0 \n"
"sub $0x2,%5 \n"
"subl $0x2,%5 \n"
"jge 2b \n"
LABELALIGN
@ -873,11 +889,14 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"movd %k2,%%xmm0 \n"
"psrlw $0x9,%%xmm2 \n"
"pshufb %%xmm5,%%xmm2 \n"
"psubb %8,%%xmm0 \n" // make pixels signed.
"pxor %%xmm6,%%xmm2 \n"
"pmaddubsw %%xmm2,%%xmm0 \n"
"psrlw $0x7,%%xmm0 \n"
"packuswb %%xmm0,%%xmm0 \n"
"movd %%xmm0,%k2 \n"
"paddusb %%xmm7,%%xmm2 \n"
"pmaddubsw %%xmm0,%%xmm2 \n"
"paddw %9,%%xmm2 \n" // make pixels unsigned.
"psrlw $0x7,%%xmm2 \n"
"packuswb %%xmm2,%%xmm2 \n"
"movd %%xmm2,%k2 \n"
"mov %b2," MEMACCESS(0) " \n"
"99: \n"
: "+r"(dst_ptr), // %0
@ -885,11 +904,22 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"=&a"(temp_pixel), // %2
"=&r"(x0), // %3
"=&r"(x1), // %4
#if defined(__x86_64__)
"+rm"(dst_width) // %5
#else
"+m"(dst_width) // %5
#endif
: "rm"(x), // %6
"rm"(dx) // %7
"rm"(dx), // %7
#if defined(__x86_64__)
"x"(kFsub80), // %8
"x"(kFadd40) // %9
#else
"m"(kFsub80), // %8
"m"(kFadd40) // %9
#endif
: "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
);
}

View File

@ -572,6 +572,10 @@ void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
MEMACCESS(6) \
"vld2.8 {d6["#n"], d7["#n"]}, [%6] \n"
// The NEON version mimics this formula (from row_common.cc):
// #define BLENDER(a, b, f) (uint8)((int)(a) +
// ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) {
int dx_offset[4] = {0, 1, 2, 3};
@ -608,8 +612,8 @@ void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
"vmovl.u16 q10, d21 \n"
"vmul.s32 q11, q11, q13 \n"
"vmul.s32 q12, q12, q10 \n"
"vshrn.s32 d18, q11, #16 \n"
"vshrn.s32 d19, q12, #16 \n"
"vrshrn.s32 d18, q11, #16 \n"
"vrshrn.s32 d19, q12, #16 \n"
"vadd.s16 q8, q8, q9 \n"
"vmovn.s16 d6, q8 \n"

View File

@ -587,6 +587,10 @@ void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
MEMACCESS(6) \
"ld2 {v4.b, v5.b}["#n"], [%6] \n"
// The NEON version mimics this formula (from row_common.cc):
// #define BLENDER(a, b, f) (uint8)((int)(a) +
// ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) {
int dx_offset[4] = {0, 1, 2, 3};
@ -626,8 +630,8 @@ void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
"ushll2 v6.4s, v6.8h, #0 \n"
"mul v16.4s, v16.4s, v7.4s \n"
"mul v17.4s, v17.4s, v6.4s \n"
"shrn v6.4h, v16.4s, #16 \n"
"shrn2 v6.8h, v17.4s, #16 \n"
"rshrn v6.4h, v16.4s, #16 \n"
"rshrn2 v6.8h, v17.4s, #16 \n"
"add v4.8h, v4.8h, v6.8h \n"
"xtn v4.8b, v4.8h \n"

View File

@ -860,6 +860,16 @@ void ScaleAddRow_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width) {
}
#endif // HAS_SCALEADDROW_AVX2
// Constant for making pixels signed to avoid pmaddubsw
// saturation.
static uvec8 kFsub80 =
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
// Constant for making pixels unsigned and adding .5 for rounding.
static uvec16 kFadd40 =
{ 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040 };
// Bilinear column filtering. SSSE3 version.
__declspec(naked)
void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
@ -877,6 +887,8 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
movd xmm5, eax
pcmpeqb xmm6, xmm6 // generate 0x007f for inverting fraction.
psrlw xmm6, 9
pcmpeqb xmm7, xmm7 // generate 0x0001
psrlw xmm7, 15
pextrw eax, xmm2, 1 // get x0 integer. preroll
sub ecx, 2
jl xloop29
@ -899,20 +911,22 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
movd xmm4, ebx
pshufb xmm1, xmm5 // 0011
punpcklwd xmm0, xmm4
psubb xmm0, xmmword ptr kFsub80 // make pixels signed.
pxor xmm1, xmm6 // 0..7f and 7f..0
pmaddubsw xmm0, xmm1 // 16 bit, 2 pixels.
paddusb xmm1, xmm7 // +1 so 0..7f and 80..1
pmaddubsw xmm1, xmm0 // 16 bit, 2 pixels.
pextrw eax, xmm2, 1 // get x0 integer. next iteration.
pextrw edx, xmm2, 3 // get x1 integer. next iteration.
psrlw xmm0, 7 // 8.7 fixed point to low 8 bits.
packuswb xmm0, xmm0 // 8 bits, 2 pixels.
movd ebx, xmm0
paddw xmm1, xmmword ptr kFadd40 // make pixels unsigned and round.
psrlw xmm1, 7 // 8.7 fixed point to low 8 bits.
packuswb xmm1, xmm1 // 8 bits, 2 pixels.
movd ebx, xmm1
mov [edi], bx
lea edi, [edi + 2]
sub ecx, 2 // 2 pixels
jge xloop2
xloop29:
add ecx, 2 - 1
jl xloop99
@ -921,11 +935,14 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
movd xmm0, ebx
psrlw xmm2, 9 // 7 bit fractions.
pshufb xmm2, xmm5 // 0011
psubb xmm0, xmmword ptr kFsub80 // make pixels signed.
pxor xmm2, xmm6 // 0..7f and 7f..0
pmaddubsw xmm0, xmm2 // 16 bit
psrlw xmm0, 7 // 8.7 fixed point to low 8 bits.
packuswb xmm0, xmm0 // 8 bits
movd ebx, xmm0
paddusb xmm2, xmm7 // +1 so 0..7f and 80..1
pmaddubsw xmm2, xmm0 // 16 bit
paddw xmm2, xmmword ptr kFadd40 // make pixels unsigned and round.
psrlw xmm2, 7 // 8.7 fixed point to low 8 bits.
packuswb xmm2, xmm2 // 8 bits
movd ebx, xmm2
mov [edi], bl
xloop99:

View File

@ -25,6 +25,7 @@ struct FourCCAliasEntry {
static const struct FourCCAliasEntry kFourCCAliases[] = {
{FOURCC_IYUV, FOURCC_I420},
{FOURCC_YU12, FOURCC_I420},
{FOURCC_YU16, FOURCC_I422},
{FOURCC_YU24, FOURCC_I444},
{FOURCC_YUYV, FOURCC_YUY2},

View File

@ -18,7 +18,7 @@ if (is_win) {
config("gflags_config") {
include_dirs = [
"$gflags_gen_arch_root/include", # For configured files.
"src", # For everything else.
"src/src", # For everything else.
]
defines = [
@ -38,31 +38,39 @@ config("gflags_config") {
}
source_set("gflags") {
cflags = []
sources = [
"src/gflags.cc",
"src/gflags_completions.cc",
"src/gflags_reporting.cc",
"src/src/gflags.cc",
"src/src/gflags_completions.cc",
"src/src/gflags_reporting.cc",
]
if (is_win) {
sources += [ "src/windows/port.cc" ]
sources += [ "src/src/windows_port.cc" ]
cflags = [
cflags += [
"/wd4005", # WIN32_LEAN_AND_MEAN.
"/wd4267", # Conversion from size_t to "type".
]
}
include_dirs = [ "$gflags_gen_arch_root/include/private" ] # For config.h
include_dirs = [
"$gflags_gen_arch_root/include/gflags", # For configured files.
"$gflags_gen_arch_root/include/private", # For config.h
]
public_configs = [ ":gflags_config" ]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
if (is_win) {
configs -= [ "//build/config/win:unicode" ]
}
if (is_clang) {
# TODO(andrew): Look into fixing this warning upstream:
# http://code.google.com/p/webrtc/issues/detail?id=760
configs -= [ "//build/config/clang:extra_warnings" ]
cflags += [ "-Wno-microsoft-include" ]
}
}

View File

@ -1,5 +1,5 @@
URL: http://code.google.com/p/gflags/
Version: 2.0
URL: https://github.com/gflags/gflags
Version: 2.1.2
License: New BSD
License File: LICENSE

View File

@ -28,7 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
// Author: Ray Sidney
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
@ -52,8 +51,8 @@
// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
// }
//
// Then, at the command-line:
// ./foo --noverbose --start=5 --end=100
// Then, at the command-line:
// ./foo --noverbose --start=5 --end=100
//
// For more details, see
// doc/gflags.html
@ -76,53 +75,27 @@
// other thread is writing to the variable or calling non-const
// methods of this class.
#ifndef GOOGLE_GFLAGS_H_
#define GOOGLE_GFLAGS_H_
#ifndef GFLAGS_GFLAGS_H_
#define GFLAGS_GFLAGS_H_
#include <string>
#include <vector>
// We care a lot about number of bits things take up. Unfortunately,
// systems define their bit-specific ints in a lot of different ways.
// We use our own way, and have a typedef to get there.
// Note: these commands below may look like "#if 1" or "#if 0", but
// that's because they were constructed that way at ./configure time.
// Look at gflags.h.in to see how they're calculated (based on your config).
#if 1
#include <stdint.h> // the normal place uint16_t is defined
#endif
#if 1
#include <sys/types.h> // the normal place u_int16_t is defined
#endif
#if 1
#include <inttypes.h> // a third place for uint16_t or u_int16_t
#include "gflags_declare.h" // IWYU pragma: export
// We always want to export variables defined in user code
#ifndef GFLAGS_DLL_DEFINE_FLAG
# ifdef _MSC_VER
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# else
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
namespace google {
#if 1 // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 1 // the BSD format
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 0 // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#endif
namespace GFLAGS_NAMESPACE {
// TODO(kjellander): update generated .h's for new gflags.
// https://code.google.com/p/webrtc/issues/detail?id=2251
extern const char* VersionString();
extern void SetVersionString(const std::string& version);
// --------------------------------------------------------------------
// To actually define a flag in a file, use DEFINE_bool,
@ -153,18 +126,17 @@ extern void SetVersionString(const std::string& version);
// Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag).
bool RegisterFlagValidator(const bool* flag,
bool (*validate_fn)(const char*, bool));
bool RegisterFlagValidator(const int32* flag,
bool (*validate_fn)(const char*, int32));
bool RegisterFlagValidator(const int64* flag,
bool (*validate_fn)(const char*, int64));
bool RegisterFlagValidator(const uint64* flag,
bool (*validate_fn)(const char*, uint64));
bool RegisterFlagValidator(const double* flag,
bool (*validate_fn)(const char*, double));
bool RegisterFlagValidator(const std::string* flag,
bool (*validate_fn)(const char*, const std::string&));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
// Convenience macro for the registration of a flag validator
#define DEFINE_validator(name, validator) \
static const bool name##_validator_registered = \
GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
// --------------------------------------------------------------------
@ -177,49 +149,56 @@ bool RegisterFlagValidator(const std::string* flag,
// In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once.
//
// No need to export this data only structure from DLL, avoiding VS warning 4251.
struct CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption
const void* flag_ptr;
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on this flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption
const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
};
// Using this inside of a validator is a recipe for a deadlock.
// TODO(wojtekm) Fix locking when validators are running, to make it safe to
// TODO(user) Fix locking when validators are running, to make it safe to
// call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in
// commandlineflags_unittest.sh
extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in commandlineflags_reporting.cc.
extern void ShowUsageWithFlags(const char *argv0); // what --help does
extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
// gflags_unittest.sh
extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in gflags_reporting.cc.
extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
// Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks.
extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
// Thread-hostile; meant to be called before any threads are spawned.
extern void SetArgv(int argc, const char** argv);
extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is
// only called before any threads start.
extern const std::vector<std::string>& GetArgvs(); // all of argv as a vector
extern const char* GetArgv(); // all of argv as a string
extern const char* GetArgv0(); // only argv0
extern uint32 GetArgvSum(); // simple checksum of argv
extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern const char* ProgramInvocationShortName(); // basename(argv0)
extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start.
extern const char* ProgramUsage(); // string set by SetUsageMessage()
extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
// --------------------------------------------------------------------
@ -232,19 +211,18 @@ extern const char* ProgramUsage(); // string set by SetUsageMessage()
// Return true iff the flagname was found.
// OUTPUT is set to the flag's value, or unchanged if we return false.
extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
// Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false.
extern bool GetCommandLineFlagInfo(const char* name,
CommandLineFlagInfo* OUTPUT);
extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value:
// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
enum FlagSettingMode {
enum GFLAGS_DLL_DECL FlagSettingMode {
// update the flag's value (can call this multiple times).
SET_FLAGS_VALUE,
// update the flag's value, but *only if* it has not yet been updated
@ -264,9 +242,8 @@ enum FlagSettingMode {
// non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern std::string SetCommandLineOption(const char* name, const char* value);
extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
FlagSettingMode set_mode);
extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
// --------------------------------------------------------------------
@ -287,14 +264,17 @@ extern std::string SetCommandLineOptionWithMode(const char* name, const char* va
// // without worrying about restoring the FLAG values.
// }
//
// Note: This class is marked with __attribute__((unused)) because all the
// work is done in the constructor and destructor, so in the standard
// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
// the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an
// unused variable.
//
// This class is thread-safe.
// This class is thread-safe. However, its destructor writes to
// exactly the set of flags that have changed value during its
// lifetime, so concurrent _direct_ access to those flags
// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
class FlagSaver {
class GFLAGS_DLL_DECL FlagSaver {
public:
FlagSaver();
~FlagSaver();
@ -304,24 +284,23 @@ class FlagSaver {
FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&);
} __attribute__ ((unused));
}__attribute((unused));
// --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions.
// This is often used for logging. TODO(csilvers): figure out a better way
extern std::string CommandlineFlagsIntoString();
extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead.
extern bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
extern GFLAGS_DLL_DECL
bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality.
// DEPRECATED.
extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern bool SaveCommandFlags(); // actually defined in google.cc !
extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
// --------------------------------------------------------------------
@ -332,16 +311,16 @@ extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name
// Otherwise, return the value. NOTE: for booleans, for true use
// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
extern bool BoolFromEnv(const char *varname, bool defval);
extern int32 Int32FromEnv(const char *varname, int32 defval);
extern int64 Int64FromEnv(const char *varname, int64 defval);
extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
extern double DoubleFromEnv(const char *varname, double defval);
extern const char *StringFromEnv(const char *varname, const char *defval);
extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
// --------------------------------------------------------------------
// The next two functions parse commandlineflags from main():
// The next two functions parse gflags from main():
// Set the "usage" message for this program. For example:
// string usage("This program does nothing. Sample usage:\n");
@ -349,7 +328,13 @@ extern const char *StringFromEnv(const char *varname, const char *defval);
// SetUsageMessage(usage);
// Do not include commandline flags in the usage: we do that for you!
// Thread-hostile; meant to be called before any threads are spawned.
extern void SetUsageMessage(const std::string& usage);
extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put
// flags first, or removes them entirely if remove_flags is true.
@ -358,8 +343,7 @@ extern void SetUsageMessage(const std::string& usage);
// of the first non-flag argument.
// See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern uint32 ParseCommandLineFlags(int *argc, char*** argv,
bool remove_flags);
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
#endif
@ -373,18 +357,18 @@ extern uint32 ParseCommandLineFlags(int *argc, char*** argv,
// defined more than once in the command line or flag file, the last
// definition is used. Returns the index (into argv) of the first
// non-flag argument. (If remove_flags is true, will always return 1.)
extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
bool remove_flags);
// This is actually defined in commandlineflags_reporting.cc.
extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
// This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-(
extern void HandleCommandLineHelpFlags(); // in commandlineflags_reporting.cc
extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a
// later parse. Thread-hostile; meant to be called before any threads
// are spawned.
extern void AllowCommandLineReparsing();
extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized. Only flags
// registered since the last parse will be recognized. Any flag value
@ -392,19 +376,18 @@ extern void AllowCommandLineReparsing();
// separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded.
// Returns the index (into the original argv) of the first non-flag
// argument. (If remove_flags is true, will always return 1.)
extern void ReparseCommandLineNonHelpFlags();
extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory
// debugging tools such as valgrind. It is not required for normal
// operation, or for the perftools heap-checker. It must only be called
// when the process is about to exit, and all threads that might
// access flags are quiescent. Referencing flags after this is called
// will have unexpected consequences. This is not safe to run when
// multiple threads might be running: the function is thread-hostile.
extern void ShutDownCommandLineFlags();
// operation, or for the google perftools heap-checker. It must only
// be called when the process is about to exit, and all threads that
// might access flags are quiescent. Referencing flags after this is
// called will have unexpected consequences. This is not safe to run
// when multiple threads might be running: the function is
// thread-hostile.
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// --------------------------------------------------------------------
@ -435,7 +418,7 @@ extern void ShutDownCommandLineFlags();
// directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get
// access to a flag, rather than saying "extern bool FLAGS_whatever;"
// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere.
@ -444,29 +427,30 @@ extern void ShutDownCommandLineFlags();
// people can't DECLARE_int32 something that they DEFINE_bool'd
// elsewhere.
class FlagRegisterer {
class GFLAGS_DLL_DECL FlagRegisterer {
public:
FlagRegisterer(const char* name, const char* type,
const char* help, const char* filename,
void* current_storage, void* defvalue_storage);
};
extern bool FlagsTypeWarn(const char *name);
// If your application #defines STRIP_FLAG_HELP to a non-zero value
// before #including this file, we remove the help message from the
// binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons.
extern const char kStrippedFlagHelp[];
extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
}
#ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : ::google::kStrippedFlagHelp)
#define MAYBE_STRIPPED_HELP(txt) \
(false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
#else
#define MAYBE_STRIPPED_HELP(txt) txt
#endif
@ -482,21 +466,16 @@ extern const char kStrippedFlagHelp[];
// FLAGS_no<name>. This serves the second purpose of assuring a
// compile error if someone tries to define a flag named no<name>
// which is illegal (--foo and --nofoo both affect the "foo" flag).
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \
type FLAGS_##name = FLAGS_nono##name; \
type FLAGS_no##name = FLAGS_nono##name; \
static ::google::FlagRegisterer o_##name( \
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
using fL##shorttype::FLAGS_##name
#define DECLARE_VARIABLE(type, shorttype, name) \
namespace fL##shorttype { \
extern type FLAGS_##name; \
} \
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \
/* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
type FLAGS_no##name = FLAGS_nono##name; \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
using fL##shorttype::FLAGS_##name
// For DEFINE_bool, we want to do the extra check that the passed-in
@ -506,34 +485,39 @@ extern const char kStrippedFlagHelp[];
// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
// that the compiler have different sizes for bool & double. Since
// this is not guaranteed by the standard, we check it with a
// compile-time assert (msg[-1] will give a compile-time error).
// COMPILE_ASSERT.
namespace fLB {
struct CompileAssert {};
typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
(sizeof(double) != sizeof(bool)) ? 1 : -1];
template<typename From> double IsBoolFlag(const From& from);
bool IsBoolFlag(bool from);
template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
} // namespace fLB
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name)
#define DEFINE_bool(name, val, txt) \
namespace fLB { \
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \
} \
// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
// are in a separate include, gflags_declare.h, for reducing
// the physical transitive size for DECLARE use.
#define DEFINE_bool(name, val, txt) \
namespace fLB { \
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
} \
DEFINE_VARIABLE(bool, B, name, val, txt)
#define DECLARE_int32(name) DECLARE_VARIABLE(::google::int32, I, name)
#define DEFINE_int32(name,val,txt) DEFINE_VARIABLE(::google::int32, I, name, val, txt)
#define DEFINE_int32(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
name, val, txt)
#define DECLARE_int64(name) DECLARE_VARIABLE(::google::int64, I64, name)
#define DEFINE_int64(name,val,txt) DEFINE_VARIABLE(::google::int64, I64, name, val, txt)
#define DEFINE_int64(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
name, val, txt)
#define DECLARE_uint64(name) DECLARE_VARIABLE(::google::uint64, U64, name)
#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64, U64, name, val, txt)
#define DEFINE_uint64(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
name, val, txt)
#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name)
#define DEFINE_double(name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt)
#define DEFINE_double(name, val, txt) \
DEFINE_VARIABLE(double, D, name, val, txt)
// Strings are trickier, because they're not a POD, so we can't
// construct them at static-initialization time (instead they get
@ -543,11 +527,6 @@ bool IsBoolFlag(bool from);
// into it later. It's not perfect, but the best we can do.
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const char *value) {
@ -561,9 +540,6 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
int value);
} // namespace fLS
#define DECLARE_string(name) namespace fLS { extern ::fLS::clstring& FLAGS_##name; } \
using fLS::FLAGS_##name
// We need to define a var named FLAGS_no##name so people don't define
// --string and --nostring. And we need a temporary place to put val
// so we don't have to evaluate it twice. Two great needs that go
@ -578,10 +554,10 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \
val); \
static ::google::FlagRegisterer o_##name( \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
extern clstring& FLAGS_##name; \
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
using fLS::FLAGS_##name; \
clstring& FLAGS_##name = *FLAGS_no##name; \
} \
@ -589,4 +565,9 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
#endif // SWIG
#endif // GOOGLE_GFLAGS_H_
// Import gflags library symbols into alternative/deprecated namespace(s)
#include "gflags_gflags.h"
#endif // GFLAGS_GFLAGS_H_

View File

@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---
// Author: Dave Nicponski
//
// Implement helpful bash-style command line flag completions
//
@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ):
/*
$ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
$ complete -o bashdefault -o default -o nospace -C \
'/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...]
*/
@ -109,13 +109,13 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_
#ifndef GFLAGS_COMPLETIONS_H_
#define GFLAGS_COMPLETIONS_H_
namespace google {
void HandleCommandLineCompletions(void);
extern void HandleCommandLineCompletions(void);
}
#endif // GOOGLE_GFLAGS_COMPLETIONS_H_
#endif // GFLAGS_COMPLETIONS_H_

View File

@ -0,0 +1,141 @@
// Copyright (c) 1999, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
//
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
// command line flag.
#ifndef GFLAGS_DECLARE_H_
#define GFLAGS_DECLARE_H_
// ---------------------------------------------------------------------------
// Namespace of gflags library symbols.
#define GFLAGS_NAMESPACE google
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// We always want to import the symbols of the gflags library
#ifndef GFLAGS_DLL_DECL
# if 0 && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// We always want to import variables declared in user code
#ifndef GFLAGS_DLL_DECLARE_FLAG
# ifdef _MSC_VER
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if 1
# include <stdint.h> // the normal place uint32_t is defined
#elif 1
# include <sys/types.h> // the normal place u_int32_t is defined
#elif 1
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
namespace GFLAGS_NAMESPACE {
#if 1 // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 0 // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
# error Do not know how to define a 32-bit integer quantity on your system
#endif
} // namespace GFLAGS_NAMESPACE
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
} // namespace fLS
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
/* We always want to import declared variables, dll or no */ \
namespace fLS { \
using ::fLS::clstring; \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif // GFLAGS_DECLARE_H_

View File

@ -0,0 +1,101 @@
// Copyright (c) 2014, Andreas Schuh
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------
// Imports the gflags library symbols into an alternative/deprecated namespace.
#ifndef GFLAGS_GFLAGS_H_
# error The internal header gflags_gflags.h may only be included by gflags.h
#endif
#ifndef GFLAGS_NS_GFLAGS_H_
#define GFLAGS_NS_GFLAGS_H_
namespace gflags {
using GFLAGS_NAMESPACE::int32;
using GFLAGS_NAMESPACE::uint32;
using GFLAGS_NAMESPACE::int64;
using GFLAGS_NAMESPACE::uint64;
using GFLAGS_NAMESPACE::RegisterFlagValidator;
using GFLAGS_NAMESPACE::CommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetAllFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlagsRestrict;
using GFLAGS_NAMESPACE::DescribeOneFlag;
using GFLAGS_NAMESPACE::SetArgv;
using GFLAGS_NAMESPACE::GetArgvs;
using GFLAGS_NAMESPACE::GetArgv;
using GFLAGS_NAMESPACE::GetArgv0;
using GFLAGS_NAMESPACE::GetArgvSum;
using GFLAGS_NAMESPACE::ProgramInvocationName;
using GFLAGS_NAMESPACE::ProgramInvocationShortName;
using GFLAGS_NAMESPACE::ProgramUsage;
using GFLAGS_NAMESPACE::VersionString;
using GFLAGS_NAMESPACE::GetCommandLineOption;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfoOrDie;
using GFLAGS_NAMESPACE::FlagSettingMode;
using GFLAGS_NAMESPACE::SET_FLAGS_VALUE;
using GFLAGS_NAMESPACE::SET_FLAG_IF_DEFAULT;
using GFLAGS_NAMESPACE::SET_FLAGS_DEFAULT;
using GFLAGS_NAMESPACE::SetCommandLineOption;
using GFLAGS_NAMESPACE::SetCommandLineOptionWithMode;
using GFLAGS_NAMESPACE::FlagSaver;
using GFLAGS_NAMESPACE::CommandlineFlagsIntoString;
using GFLAGS_NAMESPACE::ReadFlagsFromString;
using GFLAGS_NAMESPACE::AppendFlagsIntoFile;
using GFLAGS_NAMESPACE::ReadFromFlagsFile;
using GFLAGS_NAMESPACE::BoolFromEnv;
using GFLAGS_NAMESPACE::Int32FromEnv;
using GFLAGS_NAMESPACE::Int64FromEnv;
using GFLAGS_NAMESPACE::Uint64FromEnv;
using GFLAGS_NAMESPACE::DoubleFromEnv;
using GFLAGS_NAMESPACE::StringFromEnv;
using GFLAGS_NAMESPACE::SetUsageMessage;
using GFLAGS_NAMESPACE::SetVersionString;
using GFLAGS_NAMESPACE::ParseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::HandleCommandLineHelpFlags;
using GFLAGS_NAMESPACE::AllowCommandLineReparsing;
using GFLAGS_NAMESPACE::ReparseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::ShutDownCommandLineFlags;
using GFLAGS_NAMESPACE::FlagRegisterer;
#ifndef SWIG
using GFLAGS_NAMESPACE::ParseCommandLineFlags;
#endif
} // namespace gflags
#endif // GFLAGS_NS_GFLAGS_H_

View File

@ -1,110 +1,112 @@
/* src/config.h. Generated from config.h.in by configure. */
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Generated from config.h.in during build configuration using CMake. */
/* Always the empty-string on non-windows systems. On windows, should be
"__declspec(dllexport)". This way, when we compile the dll, we export our
functions/classes. It's safe to define this here because config.h is only
used internally, to compile the DLL, and every DLL source file #includes
"config.h" before anything else. */
#define GFLAGS_DLL_DECL /**/
// Note: This header file is only used internally. It is not part of public interface!
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE ::google
// ---------------------------------------------------------------------------
// System checks
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
// Define if you build this library for a MS Windows OS.
/* #undef OS_WINDOWS */
/* Define to 1 if you have the <fnmatch.h> header file. */
#define HAVE_FNMATCH_H 1
// Define if you have the <stdint.h> header file.
#define HAVE_STDINT_H
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
// Define if you have the <sys/types.h> header file.
#define HAVE_SYS_TYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
// Define if you have the <inttypes.h> header file.
#define HAVE_INTTYPES_H
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
// Define if you have the <sys/stat.h> header file.
#define HAVE_SYS_STAT_H
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
// Define if you have the <unistd.h> header file.
#define HAVE_UNISTD_H
/* Define to 1 if you have the `putenv' function. */
#define HAVE_PUTENV 1
// Define if you have the <fnmatch.h> header file.
#define HAVE_FNMATCH_H
/* Define to 1 if you have the `setenv' function. */
#define HAVE_SETENV 1
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
/* #undef HAVE_SHLWAPI_H */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
// Define if you have the strtoll function.
#define HAVE_STRTOLL
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
// Define if you have the strtoq function.
/* #undef HAVE_STRTOQ */
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
// Define if you have the <pthread.h> header file.
#define HAVE_PTHREAD
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
// Define if your pthread library defines the type pthread_rwlock_t
#define HAVE_RWLOCK
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
// gcc requires this to get PRId64, etc.
#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS 1
#endif
/* Define to 1 if you have the `strtoq' function. */
#define HAVE_STRTOQ 1
// ---------------------------------------------------------------------------
// Package information
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
// Name of package.
#define PACKAGE gflags
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
// Define to the full name of this package.
#define PACKAGE_NAME gflags
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
// Define to the full name and version of this package.
#define PACKAGE_STRING gflags 2.2.0
/* define if your compiler has __attribute__ */
#define HAVE___ATTRIBUTE__ 1
// Define to the one symbol short name of this package.
#define PACKAGE_TARNAME gflags-2.2.0
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
// Define to the version of this package.
#define PACKAGE_VERSION 2.2.0
/* Name of package */
#define PACKAGE "gflags"
// Version number of package.
#define VERSION PACKAGE_VERSION
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "opensource@google.com"
// Define to the address where bug reports for this package should be sent.
#define PACKAGE_BUGREPORT https://github.com/schuhschuh/gflags/issues
/* Define to the full name of this package. */
#define PACKAGE_NAME "gflags"
// ---------------------------------------------------------------------------
// Path separator
#ifndef PATH_SEPARATOR
# ifdef OS_WINDOWS
# define PATH_SEPARATOR '\\'
# else
# define PATH_SEPARATOR '/'
# endif
#endif
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "gflags 1.5"
// ---------------------------------------------------------------------------
// Windows
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "gflags"
// Whether gflags library is a DLL.
#ifndef GFLAGS_IS_A_DLL
# define GFLAGS_IS_A_DLL 0
#endif
/* Define to the home page for this package. */
#define PACKAGE_URL ""
// Always export symbols when compiling a shared library as this file is only
// included by internal modules when building the gflags library itself.
// The gflags_declare.h header file will set it to import these symbols otherwise.
#ifndef GFLAGS_DLL_DECL
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllexport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// Flags defined by the gflags library itself must be exported
#ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
#endif
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.5"
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* Version number of package */
#define VERSION "1.5"
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {
#ifdef OS_WINDOWS
// The unittests import the symbols of the shared gflags library
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
# endif
# include "windows_port.h"
#endif

View File

@ -28,7 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
// Author: Ray Sidney
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
@ -52,8 +51,8 @@
// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
// }
//
// Then, at the command-line:
// ./foo --noverbose --start=5 --end=100
// Then, at the command-line:
// ./foo --noverbose --start=5 --end=100
//
// For more details, see
// doc/gflags.html
@ -76,76 +75,27 @@
// other thread is writing to the variable or calling non-const
// methods of this class.
#ifndef GOOGLE_GFLAGS_H_
#define GOOGLE_GFLAGS_H_
#ifndef GFLAGS_GFLAGS_H_
#define GFLAGS_GFLAGS_H_
#include <string>
#include <vector>
// We care a lot about number of bits things take up. Unfortunately,
// systems define their bit-specific ints in a lot of different ways.
// We use our own way, and have a typedef to get there.
// Note: these commands below may look like "#if 1" or "#if 0", but
// that's because they were constructed that way at ./configure time.
// Look at gflags.h.in to see how they're calculated (based on your config).
#if 0
#include <stdint.h> // the normal place uint16_t is defined
#endif
#if 1
#include <sys/types.h> // the normal place u_int16_t is defined
#endif
#if 0
#include <inttypes.h> // a third place for uint16_t or u_int16_t
#include "gflags_declare.h" // IWYU pragma: export
// We always want to export variables defined in user code
#ifndef GFLAGS_DLL_DEFINE_FLAG
# ifdef _MSC_VER
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# else
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
// Annoying stuff for windows -- makes sure clients can import these functions
#if defined(_WIN32)
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# endif
#else
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
namespace google {
namespace GFLAGS_NAMESPACE {
#if 0 // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // the BSD format
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 1 // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#endif
// TODO(kjellander): update generated .h's for new gflags.
// https://code.google.com/p/webrtc/issues/detail?id=2251
extern const char* VersionString();
extern void SetVersionString(const std::string& version);
// --------------------------------------------------------------------
// To actually define a flag in a file, use DEFINE_bool,
@ -176,18 +126,17 @@ extern void SetVersionString(const std::string& version);
// Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag).
GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag,
bool (*validate_fn)(const char*, bool));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag,
bool (*validate_fn)(const char*, int32));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag,
bool (*validate_fn)(const char*, int64));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag,
bool (*validate_fn)(const char*, uint64));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag,
bool (*validate_fn)(const char*, double));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag,
bool (*validate_fn)(const char*, const std::string&));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
// Convenience macro for the registration of a flag validator
#define DEFINE_validator(name, validator) \
static const bool name##_validator_registered = \
GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
// --------------------------------------------------------------------
@ -200,28 +149,29 @@ GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag,
// In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once.
struct GFLAGS_DLL_DECL CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption
const void* flag_ptr;
//
// No need to export this data only structure from DLL, avoiding VS warning 4251.
struct CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on this flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption
const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
};
// Using this inside of a validator is a recipe for a deadlock.
// TODO(wojtekm) Fix locking when validators are running, to make it safe to
// TODO(user) Fix locking when validators are running, to make it safe to
// call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in
// commandlineflags_unittest.sh
// gflags_unittest.sh
extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in commandlineflags_reporting.cc.
// These two are actually defined in gflags_reporting.cc.
extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
@ -231,17 +181,24 @@ extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& fl
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is
// only called before any threads start.
extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs(); // all of argv as a vector
extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
// --------------------------------------------------------------------
@ -258,8 +215,7 @@ extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string*
// Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name,
CommandLineFlagInfo* OUTPUT);
extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value:
@ -286,9 +242,8 @@ enum GFLAGS_DLL_DECL FlagSettingMode {
// non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern GFLAGS_DLL_DECL std::string SetCommandLineOption(const char* name, const char* value);
extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value,
FlagSettingMode set_mode);
extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
// --------------------------------------------------------------------
@ -309,12 +264,15 @@ extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name
// // without worrying about restoring the FLAG values.
// }
//
// Note: This class is marked with __attribute__((unused)) because all the
// work is done in the constructor and destructor, so in the standard
// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
// the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an
// unused variable.
//
// This class is thread-safe.
// This class is thread-safe. However, its destructor writes to
// exactly the set of flags that have changed value during its
// lifetime, so concurrent _direct_ access to those flags
// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
class GFLAGS_DLL_DECL FlagSaver {
public:
@ -326,7 +284,7 @@ class GFLAGS_DLL_DECL FlagSaver {
FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&);
} ;
};
// --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions.
@ -334,16 +292,15 @@ class GFLAGS_DLL_DECL FlagSaver {
// This is often used for logging. TODO(csilvers): figure out a better way
extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead.
extern GFLAGS_DLL_DECL bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
extern GFLAGS_DLL_DECL
bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality.
// DEPRECATED.
extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern GFLAGS_DLL_DECL bool SaveCommandFlags(); // actually defined in google.cc !
extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
// --------------------------------------------------------------------
@ -363,7 +320,7 @@ extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char
// --------------------------------------------------------------------
// The next two functions parse commandlineflags from main():
// The next two functions parse gflags from main():
// Set the "usage" message for this program. For example:
// string usage("This program does nothing. Sample usage:\n");
@ -373,14 +330,20 @@ extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put
// flags first, or removes them entirely if remove_flags is true.
// If a flag is defined more than once in the command line or flag
// file, the last definition is used.
// file, the last definition is used. Returns the index (into argv)
// of the first non-flag argument.
// See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv,
bool remove_flags);
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
#endif
@ -390,15 +353,16 @@ extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv,
// changing default values for some FLAGS (via
// e.g. SetCommandLineOptionWithMode calls) between the time of
// command line parsing and the time of dumping help information for
// the flags as a result of command line parsing.
// If a flag is defined more than once in the command line or flag
// file, the last definition is used.
extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
bool remove_flags);
// This is actually defined in commandlineflags_reporting.cc.
// the flags as a result of command line parsing. If a flag is
// defined more than once in the command line or flag file, the last
// definition is used. Returns the index (into argv) of the first
// non-flag argument. (If remove_flags is true, will always return 1.)
extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
// This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-(
extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in commandlineflags_reporting.cc
extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a
@ -406,10 +370,10 @@ extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in commandlinefla
// are spawned.
extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized.
// Only flags registered since the last parse will be recognized.
// Any flag value must be provided as part of the argument using "=",
// not as a separate command line argument that follows the flag argument.
// Reparse the flags that have not yet been recognized. Only flags
// registered since the last parse will be recognized. Any flag value
// must be provided as part of the argument using "=", not as a
// separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded.
extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
@ -417,11 +381,12 @@ extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory
// debugging tools such as valgrind. It is not required for normal
// operation, or for the perftools heap-checker. It must only be called
// when the process is about to exit, and all threads that might
// access flags are quiescent. Referencing flags after this is called
// will have unexpected consequences. This is not safe to run when
// multiple threads might be running: the function is thread-hostile.
// operation, or for the google perftools heap-checker. It must only
// be called when the process is about to exit, and all threads that
// might access flags are quiescent. Referencing flags after this is
// called will have unexpected consequences. This is not safe to run
// when multiple threads might be running: the function is
// thread-hostile.
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
@ -453,7 +418,7 @@ extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get
// access to a flag, rather than saying "extern bool FLAGS_whatever;"
// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere.
@ -469,22 +434,23 @@ class GFLAGS_DLL_DECL FlagRegisterer {
void* current_storage, void* defvalue_storage);
};
extern bool FlagsTypeWarn(const char *name);
// If your application #defines STRIP_FLAG_HELP to a non-zero value
// before #including this file, we remove the help message from the
// binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons.
extern const char kStrippedFlagHelp[];
extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
}
#ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : kStrippedFlagHelp)
#define MAYBE_STRIPPED_HELP(txt) \
(false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
#else
#define MAYBE_STRIPPED_HELP(txt) txt
#endif
@ -500,23 +466,16 @@ extern const char kStrippedFlagHelp[];
// FLAGS_no<name>. This serves the second purpose of assuring a
// compile error if someone tries to define a flag named no<name>
// which is illegal (--foo and --nofoo both affect the "foo" flag).
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \
/* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
type FLAGS_no##name = FLAGS_nono##name; \
static ::google::FlagRegisterer o_##name( \
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
using fL##shorttype::FLAGS_##name
#define DECLARE_VARIABLE(type, shorttype, name) \
namespace fL##shorttype { \
/* We always want to import declared variables, dll or no */ \
extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; \
} \
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \
/* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
type FLAGS_no##name = FLAGS_nono##name; \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
using fL##shorttype::FLAGS_##name
// For DEFINE_bool, we want to do the extra check that the passed-in
@ -526,34 +485,39 @@ extern const char kStrippedFlagHelp[];
// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
// that the compiler have different sizes for bool & double. Since
// this is not guaranteed by the standard, we check it with a
// compile-time assert (msg[-1] will give a compile-time error).
// COMPILE_ASSERT.
namespace fLB {
struct CompileAssert {};
typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
(sizeof(double) != sizeof(bool)) ? 1 : -1];
template<typename From> GFLAGS_DLL_DECL double IsBoolFlag(const From& from);
template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
} // namespace fLB
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name)
#define DEFINE_bool(name, val, txt) \
namespace fLB { \
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \
} \
// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
// are in a separate include, gflags_declare.h, for reducing
// the physical transitive size for DECLARE use.
#define DEFINE_bool(name, val, txt) \
namespace fLB { \
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
} \
DEFINE_VARIABLE(bool, B, name, val, txt)
#define DECLARE_int32(name) DECLARE_VARIABLE(::google::int32, I, name)
#define DEFINE_int32(name,val,txt) DEFINE_VARIABLE(::google::int32, I, name, val, txt)
#define DEFINE_int32(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
name, val, txt)
#define DECLARE_int64(name) DECLARE_VARIABLE(::google::int64, I64, name)
#define DEFINE_int64(name,val,txt) DEFINE_VARIABLE(::google::int64, I64, name, val, txt)
#define DEFINE_int64(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
name, val, txt)
#define DECLARE_uint64(name) DECLARE_VARIABLE(::google::uint64, U64, name)
#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64, U64, name, val, txt)
#define DEFINE_uint64(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
name, val, txt)
#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name)
#define DEFINE_double(name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt)
#define DEFINE_double(name, val, txt) \
DEFINE_VARIABLE(double, D, name, val, txt)
// Strings are trickier, because they're not a POD, so we can't
// construct them at static-initialization time (instead they get
@ -563,11 +527,6 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
// into it later. It's not perfect, but the best we can do.
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const char *value) {
@ -581,13 +540,13 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
int value);
} // namespace fLS
#define DECLARE_string(name) namespace fLS { extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; } \
using fLS::FLAGS_##name
// We need to define a var named FLAGS_no##name so people don't define
// --string and --nostring. And we need a temporary place to put val
// so we don't have to evaluate it twice. Two great needs that go
// great together!
// The weird 'using' + 'extern' inside the fLS namespace is to work around
// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
// http://code.google.com/p/google-gflags/issues/detail?id=20
#define DEFINE_string(name, val, txt) \
namespace fLS { \
using ::fLS::clstring; \
@ -595,13 +554,20 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \
val); \
static ::google::FlagRegisterer o_##name( \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name = *FLAGS_no##name; \
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
using fLS::FLAGS_##name; \
clstring& FLAGS_##name = *FLAGS_no##name; \
} \
using fLS::FLAGS_##name
#endif // SWIG
#endif // GOOGLE_GFLAGS_H_
// Import gflags library symbols into alternative/deprecated namespace(s)
#include "gflags_gflags.h"
#endif // GFLAGS_GFLAGS_H_

View File

@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---
// Author: Dave Nicponski
//
// Implement helpful bash-style command line flag completions
//
@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ):
/*
$ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
$ complete -o bashdefault -o default -o nospace -C \
'/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...]
*/
@ -109,22 +109,13 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GFLAGS_DLL_DECL
# ifdef _WIN32
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
#ifndef GFLAGS_COMPLETIONS_H_
#define GFLAGS_COMPLETIONS_H_
namespace google {
GFLAGS_DLL_DECL void HandleCommandLineCompletions(void);
extern void HandleCommandLineCompletions(void);
}
#endif // GOOGLE_GFLAGS_COMPLETIONS_H_
#endif // GFLAGS_COMPLETIONS_H_

View File

@ -0,0 +1,141 @@
// Copyright (c) 1999, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
//
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
// command line flag.
#ifndef GFLAGS_DECLARE_H_
#define GFLAGS_DECLARE_H_
// ---------------------------------------------------------------------------
// Namespace of gflags library symbols.
#define GFLAGS_NAMESPACE google
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// We always want to import the symbols of the gflags library
#ifndef GFLAGS_DLL_DECL
# if 0 && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// We always want to import variables declared in user code
#ifndef GFLAGS_DLL_DECLARE_FLAG
# ifdef _MSC_VER
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if 1
# include <stdint.h> // the normal place uint32_t is defined
#elif 1
# include <sys/types.h> // the normal place u_int32_t is defined
#elif 0
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
namespace GFLAGS_NAMESPACE {
#if 0 // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 1 // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
# error Do not know how to define a 32-bit integer quantity on your system
#endif
} // namespace GFLAGS_NAMESPACE
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
} // namespace fLS
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
/* We always want to import declared variables, dll or no */ \
namespace fLS { \
using ::fLS::clstring; \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif // GFLAGS_DECLARE_H_

View File

@ -0,0 +1,101 @@
// Copyright (c) 2014, Andreas Schuh
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------
// Imports the gflags library symbols into an alternative/deprecated namespace.
#ifndef GFLAGS_GFLAGS_H_
# error The internal header gflags_gflags.h may only be included by gflags.h
#endif
#ifndef GFLAGS_NS_GFLAGS_H_
#define GFLAGS_NS_GFLAGS_H_
namespace gflags {
using GFLAGS_NAMESPACE::int32;
using GFLAGS_NAMESPACE::uint32;
using GFLAGS_NAMESPACE::int64;
using GFLAGS_NAMESPACE::uint64;
using GFLAGS_NAMESPACE::RegisterFlagValidator;
using GFLAGS_NAMESPACE::CommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetAllFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlagsRestrict;
using GFLAGS_NAMESPACE::DescribeOneFlag;
using GFLAGS_NAMESPACE::SetArgv;
using GFLAGS_NAMESPACE::GetArgvs;
using GFLAGS_NAMESPACE::GetArgv;
using GFLAGS_NAMESPACE::GetArgv0;
using GFLAGS_NAMESPACE::GetArgvSum;
using GFLAGS_NAMESPACE::ProgramInvocationName;
using GFLAGS_NAMESPACE::ProgramInvocationShortName;
using GFLAGS_NAMESPACE::ProgramUsage;
using GFLAGS_NAMESPACE::VersionString;
using GFLAGS_NAMESPACE::GetCommandLineOption;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfoOrDie;
using GFLAGS_NAMESPACE::FlagSettingMode;
using GFLAGS_NAMESPACE::SET_FLAGS_VALUE;
using GFLAGS_NAMESPACE::SET_FLAG_IF_DEFAULT;
using GFLAGS_NAMESPACE::SET_FLAGS_DEFAULT;
using GFLAGS_NAMESPACE::SetCommandLineOption;
using GFLAGS_NAMESPACE::SetCommandLineOptionWithMode;
using GFLAGS_NAMESPACE::FlagSaver;
using GFLAGS_NAMESPACE::CommandlineFlagsIntoString;
using GFLAGS_NAMESPACE::ReadFlagsFromString;
using GFLAGS_NAMESPACE::AppendFlagsIntoFile;
using GFLAGS_NAMESPACE::ReadFromFlagsFile;
using GFLAGS_NAMESPACE::BoolFromEnv;
using GFLAGS_NAMESPACE::Int32FromEnv;
using GFLAGS_NAMESPACE::Int64FromEnv;
using GFLAGS_NAMESPACE::Uint64FromEnv;
using GFLAGS_NAMESPACE::DoubleFromEnv;
using GFLAGS_NAMESPACE::StringFromEnv;
using GFLAGS_NAMESPACE::SetUsageMessage;
using GFLAGS_NAMESPACE::SetVersionString;
using GFLAGS_NAMESPACE::ParseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::HandleCommandLineHelpFlags;
using GFLAGS_NAMESPACE::AllowCommandLineReparsing;
using GFLAGS_NAMESPACE::ReparseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::ShutDownCommandLineFlags;
using GFLAGS_NAMESPACE::FlagRegisterer;
#ifndef SWIG
using GFLAGS_NAMESPACE::ParseCommandLineFlags;
#endif
} // namespace gflags
#endif // GFLAGS_NS_GFLAGS_H_

View File

@ -1,139 +1,112 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Generated from config.h.in during build configuration using CMake. */
/* Sometimes we accidentally #include this config.h instead of the one
in .. -- this is particularly true for msys/mingw, which uses the
unix config.h but also runs code in the windows directory.
*/
#ifdef __MINGW32__
#include "../config.h"
#define GOOGLE_GFLAGS_WINDOWS_CONFIG_H_
// Note: This header file is only used internally. It is not part of public interface!
// ---------------------------------------------------------------------------
// System checks
// Define if you build this library for a MS Windows OS.
#define OS_WINDOWS
// Define if you have the <stdint.h> header file.
#define HAVE_STDINT_H
// Define if you have the <sys/types.h> header file.
#define HAVE_SYS_TYPES_H
// Define if you have the <inttypes.h> header file.
/* #undef HAVE_INTTYPES_H */
// Define if you have the <sys/stat.h> header file.
#define HAVE_SYS_STAT_H
// Define if you have the <unistd.h> header file.
/* #undef HAVE_UNISTD_H */
// Define if you have the <fnmatch.h> header file.
/* #undef HAVE_FNMATCH_H */
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
#define HAVE_SHLWAPI_H
// Define if you have the strtoll function.
/* #undef HAVE_STRTOLL */
// Define if you have the strtoq function.
/* #undef HAVE_STRTOQ */
// Define if you have the <pthread.h> header file.
/* #undef HAVE_PTHREAD */
// Define if your pthread library defines the type pthread_rwlock_t
/* #undef HAVE_RWLOCK */
// gcc requires this to get PRId64, etc.
#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS 1
#endif
#ifndef GOOGLE_GFLAGS_WINDOWS_CONFIG_H_
#define GOOGLE_GFLAGS_WINDOWS_CONFIG_H_
// ---------------------------------------------------------------------------
// Package information
/* Always the empty-string on non-windows systems. On windows, should be
"__declspec(dllexport)". This way, when we compile the dll, we export our
functions/classes. It's safe to define this here because config.h is only
used internally, to compile the DLL, and every DLL source file #includes
"config.h" before anything else. */
// Name of package.
#define PACKAGE gflags
// Define to the full name of this package.
#define PACKAGE_NAME gflags
// Define to the full name and version of this package.
#define PACKAGE_STRING gflags 2.2.0
// Define to the one symbol short name of this package.
#define PACKAGE_TARNAME gflags-2.2.0
// Define to the version of this package.
#define PACKAGE_VERSION 2.2.0
// Version number of package.
#define VERSION PACKAGE_VERSION
// Define to the address where bug reports for this package should be sent.
#define PACKAGE_BUGREPORT https://github.com/schuhschuh/gflags/issues
// ---------------------------------------------------------------------------
// Path separator
#ifndef PATH_SEPARATOR
# ifdef OS_WINDOWS
# define PATH_SEPARATOR '\\'
# else
# define PATH_SEPARATOR '/'
# endif
#endif
// ---------------------------------------------------------------------------
// Windows
// Whether gflags library is a DLL.
#ifndef GFLAGS_IS_A_DLL
# define GFLAGS_IS_A_DLL 0
#endif
// Always export symbols when compiling a shared library as this file is only
// included by internal modules when building the gflags library itself.
// The gflags_declare.h header file will set it to import these symbols otherwise.
#ifndef GFLAGS_DLL_DECL
# define GFLAGS_IS_A_DLL 1 /* not set if you're statically linking */
# define GFLAGS_DLL_DECL __declspec(dllexport)
# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllexport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// Flags defined by the gflags library itself must be exported
#ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
#endif
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE ::google
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <fnmatch.h> header file. */
#undef HAVE_FNMATCH_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the `putenv' function. */
#define HAVE_PUTENV 1
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the `strtoq' function. */
#define HAVE_STRTOQ 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* define if your compiler has __attribute__ */
#undef HAVE___ATTRIBUTE__
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* Version number of package */
#undef VERSION
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {
// ---------------------------------------------------------------------
// Extra stuff not found in config.h.in
// This must be defined before the windows.h is included. It's needed
// for mutex.h, to give access to the TryLock method.
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
#ifdef OS_WINDOWS
// The unittests import the symbols of the shared gflags library
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
# endif
# include "windows_port.h"
#endif
// TODO(csilvers): include windows/port.h in every relevant source file instead?
#include "windows/port.h"
#endif /* GOOGLE_GFLAGS_WINDOWS_CONFIG_H_ */

View File

@ -25,9 +25,9 @@
'target_name': 'gflags',
'type': 'static_library',
'include_dirs': [
'<(gflags_gen_arch_root)/include/gflags', # For configured files.
'<(gflags_gen_arch_root)/include/private', # For config.h
'<(gflags_gen_arch_root)/include', # For configured files.
'<(gflags_root)/src', # For everything else.
'<(gflags_root)/src/src', # For everything else.
],
'defines': [
# These macros exist so flags and symbols are properly
@ -40,7 +40,7 @@
'direct_dependent_settings': {
'include_dirs': [
'<(gflags_gen_arch_root)/include', # For configured files.
'<(gflags_root)/src', # For everything else.
'<(gflags_root)/src/src', # For everything else.
],
'defines': [
'GFLAGS_DLL_DECL=',
@ -49,42 +49,44 @@
],
},
'sources': [
'src/gflags.cc',
'src/gflags_completions.cc',
'src/gflags_reporting.cc',
'src/src/gflags.cc',
'src/src/gflags_completions.cc',
'src/src/gflags_reporting.cc',
],
'conditions': [
['OS=="win"', {
'sources': [
'src/windows/port.cc',
'src/src/windows_port.cc',
],
# Suppress warnings about WIN32_LEAN_AND_MEAN and size_t truncation.
'msvs_disabled_warnings': [4005, 4267],
'msvs_disabled_warnings': [
4005, # WIN32_LEAN_AND_MEAN redefinition.
4267, # Conversion from size_t to "type".
],
'configurations': {
'Common_Base': {
'msvs_configuration_attributes': {
'CharacterSet': '2', # Use Multi-byte Character Set.
},
},
},
}],
# TODO(andrew): Look into fixing this warning upstream:
# http://code.google.com/p/webrtc/issues/detail?id=760
['OS=="win" and clang==1', {
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions!': [
'-Wheader-hygiene', # Suppress warning about using namespace.
],
'AdditionalOptions': [
'-Wno-unused-local-typedef', # Suppress unused private typedef.
'-Wno-microsoft-include',
],
},
},
}],
['clang==1', {
'cflags': ['-Wno-unused-local-typedef',],
'cflags!': ['-Wheader-hygiene',],
'xcode_settings': {
'WARNING_CFLAGS': ['-Wno-unused-local-typedef',],
'WARNING_CFLAGS!': ['-Wheader-hygiene',],
},
'cflags': [
'-Wno-microsoft-include',
],
}],
],
},
],
}

View File

@ -10,12 +10,12 @@
#include <stdlib.h>
#include "libyuv/basic_types.h"
#include "libyuv/convert.h"
#include "libyuv/convert_argb.h"
#include "libyuv/convert_from.h"
#include "libyuv/convert_from_argb.h"
#include "libyuv/cpu_id.h"
#include "libyuv/row.h" // For Sobel
#include "../unit_test/unit_test.h"
namespace libyuv {
@ -41,15 +41,15 @@ namespace libyuv {
const int kPixels = benchmark_width_ * benchmark_height_; \
const int kHalfPixels = ((benchmark_width_ + 1) / 2) * \
((benchmark_height_ + HS1) / HS); \
align_buffer_64(orig_y, kPixels); \
align_buffer_64(orig_u, kHalfPixels); \
align_buffer_64(orig_v, kHalfPixels); \
align_buffer_64(orig_pixels, kPixels * 4); \
align_buffer_64(temp_y, kPixels); \
align_buffer_64(temp_u, kHalfPixels); \
align_buffer_64(temp_v, kHalfPixels); \
align_buffer_64(dst_pixels_opt, kPixels * 4); \
align_buffer_64(dst_pixels_c, kPixels * 4); \
align_buffer_page_end(orig_y, kPixels); \
align_buffer_page_end(orig_u, kHalfPixels); \
align_buffer_page_end(orig_v, kHalfPixels); \
align_buffer_page_end(orig_pixels, kPixels * 4); \
align_buffer_page_end(temp_y, kPixels); \
align_buffer_page_end(temp_u, kHalfPixels); \
align_buffer_page_end(temp_v, kHalfPixels); \
align_buffer_page_end(dst_pixels_opt, kPixels * 4); \
align_buffer_page_end(dst_pixels_c, kPixels * 4); \
\
MemRandomize(orig_pixels, kPixels * 4); \
MemRandomize(orig_y, kPixels); \
@ -132,21 +132,21 @@ namespace libyuv {
static_cast<int>(dst_pixels_opt[i]), DIFF); \
} \
\
free_aligned_buffer_64(orig_pixels); \
free_aligned_buffer_64(orig_y); \
free_aligned_buffer_64(orig_u); \
free_aligned_buffer_64(orig_v); \
free_aligned_buffer_64(temp_y); \
free_aligned_buffer_64(temp_u); \
free_aligned_buffer_64(temp_v); \
free_aligned_buffer_64(dst_pixels_opt); \
free_aligned_buffer_64(dst_pixels_c); \
free_aligned_buffer_page_end(orig_pixels); \
free_aligned_buffer_page_end(orig_y); \
free_aligned_buffer_page_end(orig_u); \
free_aligned_buffer_page_end(orig_v); \
free_aligned_buffer_page_end(temp_y); \
free_aligned_buffer_page_end(temp_u); \
free_aligned_buffer_page_end(temp_v); \
free_aligned_buffer_page_end(dst_pixels_opt); \
free_aligned_buffer_page_end(dst_pixels_c); \
} \
TESTCS(TestI420, I420ToARGB, ARGBToI420, 1, 2, benchmark_width_, ERROR_FULL)
TESTCS(TestI422, I422ToARGB, ARGBToI422, 0, 1, 0, ERROR_FULL)
TESTCS(TestJ420, J420ToARGB, ARGBToJ420, 1, 2, benchmark_width_, ERROR_J420)
TESTCS(TestJ422, J422ToARGB, ARGBToJ422, 0, 1, 0, 3)
TESTCS(TestJ422, J422ToARGB, ARGBToJ422, 0, 1, 0, ERROR_J420)
static void YUVToRGB(int y, int u, int v, int* r, int* g, int* b) {
const int kWidth = 16;

View File

@ -16,7 +16,6 @@
#include "libyuv/basic_types.h"
#include "libyuv/compare.h"
#include "libyuv/cpu_id.h"
#include "libyuv/row.h"
#include "libyuv/video_common.h"
namespace libyuv {
@ -34,8 +33,8 @@ static uint32 ReferenceHashDjb2(const uint8* src, uint64 count, uint32 seed) {
TEST_F(LibYUVBaseTest, Djb2_Test) {
const int kMaxTest = benchmark_width_ * benchmark_height_;
align_buffer_64(src_a, kMaxTest);
align_buffer_64(src_b, kMaxTest);
align_buffer_page_end(src_a, kMaxTest);
align_buffer_page_end(src_b, kMaxTest);
const char* fox = "The quick brown fox jumps over the lazy dog"
" and feels as if he were in the seventh heaven of typography"
@ -112,13 +111,13 @@ TEST_F(LibYUVBaseTest, Djb2_Test) {
h2 = HashDjb2(src_a, kMaxTest / 2, 0);
EXPECT_EQ(h1, h2);
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVBaseTest, BenchmarkDjb2_Opt) {
const int kMaxTest = benchmark_width_ * benchmark_height_;
align_buffer_64(src_a, kMaxTest);
align_buffer_page_end(src_a, kMaxTest);
for (int i = 0; i < kMaxTest; ++i) {
src_a[i] = i;
@ -129,12 +128,12 @@ TEST_F(LibYUVBaseTest, BenchmarkDjb2_Opt) {
h1 = HashDjb2(src_a, kMaxTest, 5381);
}
EXPECT_EQ(h1, h2);
free_aligned_buffer_64(src_a);
free_aligned_buffer_page_end(src_a);
}
TEST_F(LibYUVBaseTest, BenchmarkDjb2_Unaligned) {
const int kMaxTest = benchmark_width_ * benchmark_height_;
align_buffer_64(src_a, kMaxTest + 1);
align_buffer_page_end(src_a, kMaxTest + 1);
for (int i = 0; i < kMaxTest; ++i) {
src_a[i + 1] = i;
}
@ -144,13 +143,13 @@ TEST_F(LibYUVBaseTest, BenchmarkDjb2_Unaligned) {
h1 = HashDjb2(src_a + 1, kMaxTest, 5381);
}
EXPECT_EQ(h1, h2);
free_aligned_buffer_64(src_a);
free_aligned_buffer_page_end(src_a);
}
TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Opt) {
uint32 fourcc;
const int kMaxTest = benchmark_width_ * benchmark_height_ * 4;
align_buffer_64(src_a, kMaxTest);
align_buffer_page_end(src_a, kMaxTest);
for (int i = 0; i < kMaxTest; ++i) {
src_a[i] = 255;
}
@ -172,15 +171,15 @@ TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Opt) {
}
EXPECT_EQ(0, fourcc);
free_aligned_buffer_64(src_a);
free_aligned_buffer_page_end(src_a);
}
TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Unaligned) {
uint32 fourcc;
const int kMaxTest = benchmark_width_ * benchmark_height_ * 4 + 1;
align_buffer_64(src_a, kMaxTest);
for (int i = 0; i < kMaxTest; ++i) {
src_a[i + 1] = 255;
align_buffer_page_end(src_a, kMaxTest);
for (int i = 1; i < kMaxTest; ++i) {
src_a[i] = 255;
}
src_a[0 + 1] = 0;
@ -200,12 +199,12 @@ TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Unaligned) {
}
EXPECT_EQ(0, fourcc);
free_aligned_buffer_64(src_a);
free_aligned_buffer_page_end(src_a);
}
TEST_F(LibYUVBaseTest, BenchmarkSumSquareError_Opt) {
const int kMaxWidth = 4096 * 3;
align_buffer_64(src_a, kMaxWidth);
align_buffer_64(src_b, kMaxWidth);
align_buffer_page_end(src_a, kMaxWidth);
align_buffer_page_end(src_b, kMaxWidth);
memset(src_a, 0, kMaxWidth);
memset(src_b, 0, kMaxWidth);
@ -229,14 +228,14 @@ TEST_F(LibYUVBaseTest, BenchmarkSumSquareError_Opt) {
EXPECT_EQ(0, h1);
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVBaseTest, SumSquareError) {
const int kMaxWidth = 4096 * 3;
align_buffer_64(src_a, kMaxWidth);
align_buffer_64(src_b, kMaxWidth);
align_buffer_page_end(src_a, kMaxWidth);
align_buffer_page_end(src_b, kMaxWidth);
memset(src_a, 0, kMaxWidth);
memset(src_b, 0, kMaxWidth);
@ -269,13 +268,13 @@ TEST_F(LibYUVBaseTest, SumSquareError) {
EXPECT_EQ(c_err, opt_err);
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVBaseTest, BenchmarkPsnr_Opt) {
align_buffer_64(src_a, benchmark_width_ * benchmark_height_);
align_buffer_64(src_b, benchmark_width_ * benchmark_height_);
align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_);
align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
src_a[i] = i;
src_b[i] = i;
@ -294,13 +293,13 @@ TEST_F(LibYUVBaseTest, BenchmarkPsnr_Opt) {
EXPECT_EQ(0, 0);
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVBaseTest, BenchmarkPsnr_Unaligned) {
align_buffer_64(src_a, benchmark_width_ * benchmark_height_ + 1);
align_buffer_64(src_b, benchmark_width_ * benchmark_height_);
align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_ + 1);
align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
src_a[i + 1] = i;
src_b[i] = i;
@ -319,8 +318,8 @@ TEST_F(LibYUVBaseTest, BenchmarkPsnr_Unaligned) {
EXPECT_EQ(0, 0);
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVBaseTest, Psnr) {
@ -329,8 +328,8 @@ TEST_F(LibYUVBaseTest, Psnr) {
const int b = 128;
const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
const int kSrcStride = 2 * b + kSrcWidth;
align_buffer_64(src_a, kSrcPlaneSize);
align_buffer_64(src_b, kSrcPlaneSize);
align_buffer_page_end(src_a, kSrcPlaneSize);
align_buffer_page_end(src_b, kSrcPlaneSize);
memset(src_a, 0, kSrcPlaneSize);
memset(src_b, 0, kSrcPlaneSize);
@ -396,13 +395,13 @@ TEST_F(LibYUVBaseTest, Psnr) {
EXPECT_EQ(opt_err, c_err);
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVBaseTest, DISABLED_BenchmarkSsim_Opt) {
align_buffer_64(src_a, benchmark_width_ * benchmark_height_);
align_buffer_64(src_b, benchmark_width_ * benchmark_height_);
align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_);
align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
src_a[i] = i;
src_b[i] = i;
@ -421,8 +420,8 @@ TEST_F(LibYUVBaseTest, DISABLED_BenchmarkSsim_Opt) {
EXPECT_EQ(0, 0); // Pass if we get this far.
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVBaseTest, Ssim) {
@ -431,8 +430,8 @@ TEST_F(LibYUVBaseTest, Ssim) {
const int b = 128;
const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
const int kSrcStride = 2 * b + kSrcWidth;
align_buffer_64(src_a, kSrcPlaneSize);
align_buffer_64(src_b, kSrcPlaneSize);
align_buffer_page_end(src_a, kSrcPlaneSize);
align_buffer_page_end(src_b, kSrcPlaneSize);
memset(src_a, 0, kSrcPlaneSize);
memset(src_b, 0, kSrcPlaneSize);
@ -507,8 +506,8 @@ TEST_F(LibYUVBaseTest, Ssim) {
EXPECT_EQ(opt_err, c_err);
}
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(src_b);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
} // namespace libyuv

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,6 @@
#include "libyuv/basic_types.h"
#include "libyuv/cpu_id.h"
#include "libyuv/row.h" // For HAS_ARGBSHUFFLEROW_AVX2.
#include "libyuv/version.h"
#include "../unit_test/unit_test.h"
@ -68,16 +67,9 @@ printf("_MSC_VER %d\n", _MSC_VER);
#if !defined(LIBYUV_DISABLE_X86) && (defined(GCC_HAS_AVX2) || \
defined(CLANG_HAS_AVX2) || defined(VISUALC_HAS_AVX2))
printf("Has AVX2 1\n");
// If compiler supports AVX2, the following function is expected to exist:
#if !defined(HAS_ARGBSHUFFLEROW_AVX2)
EXPECT_TRUE(0); // HAS_ARGBSHUFFLEROW_AVX2 was expected.
#endif
#else
printf("Has AVX2 0\n");
// If compiler does not support AVX2, the following function not expected:
#if defined(HAS_ARGBSHUFFLEROW_AVX2)
EXPECT_TRUE(0); // HAS_ARGBSHUFFLEROW_AVX2 was not expected.
#endif
#endif
}

View File

@ -14,7 +14,6 @@
#include "libyuv/basic_types.h"
#include "libyuv/cpu_id.h"
#include "libyuv/row.h"
#include "libyuv/scale.h"
#include "libyuv/scale_row.h"
#include "../unit_test/unit_test.h"

View File

@ -19,17 +19,16 @@
#include "libyuv/cpu_id.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
#include "libyuv/row.h" // For Sobel
#include "../unit_test/unit_test.h"
namespace libyuv {
TEST_F(LibYUVPlanarTest, TestAttenuate) {
const int kSize = 1280 * 4;
align_buffer_64(orig_pixels, kSize);
align_buffer_64(atten_pixels, kSize);
align_buffer_64(unatten_pixels, kSize);
align_buffer_64(atten2_pixels, kSize);
align_buffer_page_end(orig_pixels, kSize);
align_buffer_page_end(atten_pixels, kSize);
align_buffer_page_end(unatten_pixels, kSize);
align_buffer_page_end(atten2_pixels, kSize);
// Test unattenuation clamps
orig_pixels[0 * 4 + 0] = 200u;
@ -98,10 +97,10 @@ TEST_F(LibYUVPlanarTest, TestAttenuate) {
EXPECT_NEAR(85, atten_pixels[255 * 4 + 2], 1);
EXPECT_EQ(255, atten_pixels[255 * 4 + 3]);
free_aligned_buffer_64(atten2_pixels);
free_aligned_buffer_64(unatten_pixels);
free_aligned_buffer_64(atten_pixels);
free_aligned_buffer_64(orig_pixels);
free_aligned_buffer_page_end(atten2_pixels);
free_aligned_buffer_page_end(unatten_pixels);
free_aligned_buffer_page_end(atten_pixels);
free_aligned_buffer_page_end(orig_pixels);
}
static int TestAttenuateI(int width, int height, int benchmark_iterations,
@ -112,9 +111,9 @@ static int TestAttenuateI(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) {
src_argb[i + off] = (fastrand() & 0xff);
}
@ -140,9 +139,9 @@ static int TestAttenuateI(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -186,9 +185,9 @@ static int TestUnattenuateI(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) {
src_argb[i + off] = (fastrand() & 0xff);
}
@ -217,9 +216,9 @@ static int TestUnattenuateI(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -1023,16 +1022,16 @@ TEST_F(LibYUVPlanarTest, TestInterpolatePlane) {
#define TESTTERP(FMT_A, BPP_A, STRIDE_A, \
FMT_B, BPP_B, STRIDE_B, \
W1280, TERP, N, NEG, OFF) \
W1280, TERP, N, NEG, OFF) \
TEST_F(LibYUVPlanarTest, ARGBInterpolate##TERP##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = benchmark_height_; \
const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \
const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \
align_buffer_64(src_argb_a, kStrideA * kHeight + OFF); \
align_buffer_64(src_argb_b, kStrideA * kHeight + OFF); \
align_buffer_64(dst_argb_c, kStrideB * kHeight); \
align_buffer_64(dst_argb_opt, kStrideB * kHeight); \
align_buffer_page_end(src_argb_a, kStrideA * kHeight + OFF); \
align_buffer_page_end(src_argb_b, kStrideA * kHeight + OFF); \
align_buffer_page_end(dst_argb_c, kStrideB * kHeight); \
align_buffer_page_end(dst_argb_opt, kStrideB * kHeight); \
for (int i = 0; i < kStrideA * kHeight; ++i) { \
src_argb_a[i + OFF] = (fastrand() & 0xff); \
src_argb_b[i + OFF] = (fastrand() & 0xff); \
@ -1052,10 +1051,10 @@ TEST_F(LibYUVPlanarTest, ARGBInterpolate##TERP##N) { \
for (int i = 0; i < kStrideB * kHeight; ++i) { \
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \
} \
free_aligned_buffer_64(src_argb_a); \
free_aligned_buffer_64(src_argb_b); \
free_aligned_buffer_64(dst_argb_c); \
free_aligned_buffer_64(dst_argb_opt); \
free_aligned_buffer_page_end(src_argb_a); \
free_aligned_buffer_page_end(src_argb_b); \
free_aligned_buffer_page_end(dst_argb_c); \
free_aligned_buffer_page_end(dst_argb_opt); \
}
#define TESTINTERPOLATE(TERP) \
@ -1078,10 +1077,10 @@ static int TestBlend(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff);
@ -1114,10 +1113,10 @@ static int TestBlend(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(src_argb_b);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -1157,11 +1156,11 @@ static void TestBlendPlane(int width, int height, int benchmark_iterations,
}
const int kBpp = 1;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off);
align_buffer_64(src_argb_alpha, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height + off);
align_buffer_64(dst_argb_opt, kStride * height + off);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_page_end(src_argb_alpha, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height + off);
align_buffer_page_end(dst_argb_opt, kStride * height + off);
memset(dst_argb_c, 255, kStride * height + off);
memset(dst_argb_opt, 255, kStride * height + off);
@ -1212,11 +1211,11 @@ static void TestBlendPlane(int width, int height, int benchmark_iterations,
for (int i = 0; i < kStride * height; ++i) {
EXPECT_EQ(dst_argb_c[i + off], dst_argb_opt[i + off]);
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(src_argb_b);
free_aligned_buffer_64(src_argb_alpha);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_page_end(src_argb_alpha);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return;
}
@ -1245,19 +1244,19 @@ static void TestI420Blend(int width, int height, int benchmark_iterations,
width = ((width) > 0) ? (width) : 1;
const int kStrideUV = SUBSAMPLE(width, 2);
const int kSizeUV = kStrideUV * SUBSAMPLE(height, 2);
align_buffer_64(src_y0, width * height + off);
align_buffer_64(src_u0, kSizeUV + off);
align_buffer_64(src_v0, kSizeUV + off);
align_buffer_64(src_y1, width * height + off);
align_buffer_64(src_u1, kSizeUV + off);
align_buffer_64(src_v1, kSizeUV + off);
align_buffer_64(src_a, width * height + off);
align_buffer_64(dst_y_c, width * height + off);
align_buffer_64(dst_u_c, kSizeUV + off);
align_buffer_64(dst_v_c, kSizeUV + off);
align_buffer_64(dst_y_opt, width * height + off);
align_buffer_64(dst_u_opt, kSizeUV + off);
align_buffer_64(dst_v_opt, kSizeUV + off);
align_buffer_page_end(src_y0, width * height + off);
align_buffer_page_end(src_u0, kSizeUV + off);
align_buffer_page_end(src_v0, kSizeUV + off);
align_buffer_page_end(src_y1, width * height + off);
align_buffer_page_end(src_u1, kSizeUV + off);
align_buffer_page_end(src_v1, kSizeUV + off);
align_buffer_page_end(src_a, width * height + off);
align_buffer_page_end(dst_y_c, width * height + off);
align_buffer_page_end(dst_u_c, kSizeUV + off);
align_buffer_page_end(dst_v_c, kSizeUV + off);
align_buffer_page_end(dst_y_opt, width * height + off);
align_buffer_page_end(dst_u_opt, kSizeUV + off);
align_buffer_page_end(dst_v_opt, kSizeUV + off);
MemRandomize(src_y0, width * height + off);
MemRandomize(src_u0, kSizeUV + off);
@ -1306,19 +1305,19 @@ static void TestI420Blend(int width, int height, int benchmark_iterations,
EXPECT_EQ(dst_u_c[i + off], dst_u_opt[i + off]);
EXPECT_EQ(dst_v_c[i + off], dst_v_opt[i + off]);
}
free_aligned_buffer_64(src_y0);
free_aligned_buffer_64(src_u0);
free_aligned_buffer_64(src_v0);
free_aligned_buffer_64(src_y1);
free_aligned_buffer_64(src_u1);
free_aligned_buffer_64(src_v1);
free_aligned_buffer_64(src_a);
free_aligned_buffer_64(dst_y_c);
free_aligned_buffer_64(dst_u_c);
free_aligned_buffer_64(dst_v_c);
free_aligned_buffer_64(dst_y_opt);
free_aligned_buffer_64(dst_u_opt);
free_aligned_buffer_64(dst_v_opt);
free_aligned_buffer_page_end(src_y0);
free_aligned_buffer_page_end(src_u0);
free_aligned_buffer_page_end(src_v0);
free_aligned_buffer_page_end(src_y1);
free_aligned_buffer_page_end(src_u1);
free_aligned_buffer_page_end(src_v1);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(dst_y_c);
free_aligned_buffer_page_end(dst_u_c);
free_aligned_buffer_page_end(dst_v_c);
free_aligned_buffer_page_end(dst_y_opt);
free_aligned_buffer_page_end(dst_u_opt);
free_aligned_buffer_page_end(dst_v_opt);
return;
}
@ -1375,206 +1374,6 @@ TEST_F(LibYUVPlanarTest, TestAffine) {
#endif
}
TEST_F(LibYUVPlanarTest, TestSobelX) {
SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]);
SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]);
SIMD_ALIGNED(uint8 orig_pixels_2[1280 + 2]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]);
for (int i = 0; i < 1280 + 2; ++i) {
orig_pixels_0[i] = i;
orig_pixels_1[i] = i * 2;
orig_pixels_2[i] = i * 3;
}
SobelXRow_C(orig_pixels_0, orig_pixels_1, orig_pixels_2,
sobel_pixels_c, 1280);
EXPECT_EQ(16u, sobel_pixels_c[0]);
EXPECT_EQ(16u, sobel_pixels_c[100]);
EXPECT_EQ(255u, sobel_pixels_c[255]);
void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1,
const uint8* src_y2, uint8* dst_sobely, int width) =
SobelXRow_C;
#if defined(HAS_SOBELXROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelXRow = SobelXRow_SSE2;
}
#endif
#if defined(HAS_SOBELXROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelXRow = SobelXRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelXRow(orig_pixels_0, orig_pixels_1, orig_pixels_2,
sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobelY) {
SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]);
SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]);
for (int i = 0; i < 1280 + 2; ++i) {
orig_pixels_0[i] = i;
orig_pixels_1[i] = i * 2;
}
SobelYRow_C(orig_pixels_0, orig_pixels_1, sobel_pixels_c, 1280);
EXPECT_EQ(4u, sobel_pixels_c[0]);
EXPECT_EQ(255u, sobel_pixels_c[100]);
EXPECT_EQ(0u, sobel_pixels_c[255]);
void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1,
uint8* dst_sobely, int width) = SobelYRow_C;
#if defined(HAS_SOBELYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelYRow = SobelYRow_SSE2;
}
#endif
#if defined(HAS_SOBELYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelYRow = SobelYRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelYRow(orig_pixels_0, orig_pixels_1, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobel) {
SIMD_ALIGNED(uint8 orig_sobelx[1280]);
SIMD_ALIGNED(uint8 orig_sobely[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]);
for (int i = 0; i < 1280; ++i) {
orig_sobelx[i] = i;
orig_sobely[i] = i * 2;
}
SobelRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
EXPECT_EQ(0u, sobel_pixels_c[0]);
EXPECT_EQ(3u, sobel_pixels_c[4]);
EXPECT_EQ(3u, sobel_pixels_c[5]);
EXPECT_EQ(3u, sobel_pixels_c[6]);
EXPECT_EQ(255u, sobel_pixels_c[7]);
EXPECT_EQ(6u, sobel_pixels_c[8]);
EXPECT_EQ(6u, sobel_pixels_c[9]);
EXPECT_EQ(6u, sobel_pixels_c[10]);
EXPECT_EQ(255u, sobel_pixels_c[7]);
EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]);
EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]);
void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) = SobelRow_C;
#if defined(HAS_SOBELROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelRow = SobelRow_SSE2;
}
#endif
#if defined(HAS_SOBELROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelRow = SobelRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280 * 4; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobelToPlane) {
SIMD_ALIGNED(uint8 orig_sobelx[1280]);
SIMD_ALIGNED(uint8 orig_sobely[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]);
for (int i = 0; i < 1280; ++i) {
orig_sobelx[i] = i;
orig_sobely[i] = i * 2;
}
SobelToPlaneRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
EXPECT_EQ(0u, sobel_pixels_c[0]);
EXPECT_EQ(3u, sobel_pixels_c[1]);
EXPECT_EQ(6u, sobel_pixels_c[2]);
EXPECT_EQ(99u, sobel_pixels_c[33]);
EXPECT_EQ(255u, sobel_pixels_c[100]);
void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_y, int width) = SobelToPlaneRow_C;
#if defined(HAS_SOBELTOPLANEROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelToPlaneRow = SobelToPlaneRow_SSE2;
}
#endif
#if defined(HAS_SOBELTOPLANEROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelToPlaneRow = SobelToPlaneRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelToPlaneRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobelXY) {
SIMD_ALIGNED(uint8 orig_sobelx[1280]);
SIMD_ALIGNED(uint8 orig_sobely[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]);
for (int i = 0; i < 1280; ++i) {
orig_sobelx[i] = i;
orig_sobely[i] = i * 2;
}
SobelXYRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
EXPECT_EQ(0u, sobel_pixels_c[0]);
EXPECT_EQ(2u, sobel_pixels_c[4]);
EXPECT_EQ(3u, sobel_pixels_c[5]);
EXPECT_EQ(1u, sobel_pixels_c[6]);
EXPECT_EQ(255u, sobel_pixels_c[7]);
EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]);
EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]);
void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) = SobelXYRow_C;
#if defined(HAS_SOBELXYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelXYRow = SobelXYRow_SSE2;
}
#endif
#if defined(HAS_SOBELXYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelXYRow = SobelXYRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelXYRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280 * 4; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestCopyPlane) {
int err = 0;
int yw = benchmark_width_;
@ -1583,9 +1382,9 @@ TEST_F(LibYUVPlanarTest, TestCopyPlane) {
int i, j;
int y_plane_size = (yw + b * 2) * (yh + b * 2);
align_buffer_64(orig_y, y_plane_size);
align_buffer_64(dst_c, y_plane_size);
align_buffer_64(dst_opt, y_plane_size);
align_buffer_page_end(orig_y, y_plane_size);
align_buffer_page_end(dst_c, y_plane_size);
align_buffer_page_end(dst_opt, y_plane_size);
memset(orig_y, 0, y_plane_size);
memset(dst_c, 0, y_plane_size);
@ -1631,9 +1430,9 @@ TEST_F(LibYUVPlanarTest, TestCopyPlane) {
++err;
}
free_aligned_buffer_64(orig_y);
free_aligned_buffer_64(dst_c);
free_aligned_buffer_64(dst_opt);
free_aligned_buffer_page_end(orig_y);
free_aligned_buffer_page_end(dst_c);
free_aligned_buffer_page_end(dst_opt);
EXPECT_EQ(0, err);
}
@ -1646,10 +1445,10 @@ static int TestMultiply(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff);
@ -1678,10 +1477,10 @@ static int TestMultiply(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(src_argb_b);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -1721,10 +1520,10 @@ static int TestAdd(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff);
@ -1753,10 +1552,10 @@ static int TestAdd(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(src_argb_b);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -1796,10 +1595,10 @@ static int TestSubtract(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff);
@ -1828,10 +1627,10 @@ static int TestSubtract(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(src_argb_b);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -1871,9 +1670,9 @@ static int TestSobel(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
memset(src_argb_a, 0, kStride * height + off);
for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
@ -1900,9 +1699,9 @@ static int TestSobel(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -1944,9 +1743,9 @@ static int TestSobelToPlane(int width, int height, int benchmark_iterations,
const int kDstBpp = 1;
const int kSrcStride = (width * kSrcBpp + 15) & ~15;
const int kDstStride = (width * kDstBpp + 15) & ~15;
align_buffer_64(src_argb_a, kSrcStride * height + off);
align_buffer_64(dst_argb_c, kDstStride * height);
align_buffer_64(dst_argb_opt, kDstStride * height);
align_buffer_page_end(src_argb_a, kSrcStride * height + off);
align_buffer_page_end(dst_argb_c, kDstStride * height);
align_buffer_page_end(dst_argb_opt, kDstStride * height);
memset(src_argb_a, 0, kSrcStride * height + off);
for (int i = 0; i < kSrcStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
@ -1973,9 +1772,9 @@ static int TestSobelToPlane(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -2019,9 +1818,9 @@ static int TestSobelXY(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
memset(src_argb_a, 0, kStride * height + off);
for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
@ -2048,9 +1847,9 @@ static int TestSobelXY(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -2090,10 +1889,10 @@ static int TestBlur(int width, int height, int benchmark_iterations,
}
const int kBpp = 4;
const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off);
align_buffer_64(dst_cumsum, width * height * 16);
align_buffer_64(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height);
align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_page_end(dst_cumsum, width * height * 16);
align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff);
}
@ -2122,10 +1921,10 @@ static int TestBlur(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(src_argb_a);
free_aligned_buffer_64(dst_cumsum);
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_page_end(dst_cumsum);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -2288,7 +2087,7 @@ TEST_F(LibYUVPlanarTest, TestARGBLumaColorTable) {
SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]);
memset(orig_pixels, 0, sizeof(orig_pixels));
align_buffer_64(lumacolortable, 32768);
align_buffer_page_end(lumacolortable, 32768);
int v = 0;
for (int i = 0; i < 32768; ++i) {
lumacolortable[i] = v;
@ -2357,14 +2156,14 @@ TEST_F(LibYUVPlanarTest, TestARGBLumaColorTable) {
EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]);
}
free_aligned_buffer_64(lumacolortable);
free_aligned_buffer_page_end(lumacolortable);
}
TEST_F(LibYUVPlanarTest, TestARGBCopyAlpha) {
const int kSize = benchmark_width_ * benchmark_height_ * 4;
align_buffer_64(orig_pixels, kSize);
align_buffer_64(dst_pixels_opt, kSize);
align_buffer_64(dst_pixels_c, kSize);
align_buffer_page_end(orig_pixels, kSize);
align_buffer_page_end(dst_pixels_opt, kSize);
align_buffer_page_end(dst_pixels_c, kSize);
MemRandomize(orig_pixels, kSize);
MemRandomize(dst_pixels_opt, kSize);
@ -2385,16 +2184,46 @@ TEST_F(LibYUVPlanarTest, TestARGBCopyAlpha) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_64(dst_pixels_c);
free_aligned_buffer_64(dst_pixels_opt);
free_aligned_buffer_64(orig_pixels);
free_aligned_buffer_page_end(dst_pixels_c);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(orig_pixels);
}
TEST_F(LibYUVPlanarTest, TestARGBExtractAlpha) {
const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_page_end(src_pixels, kPixels * 4);
align_buffer_page_end(dst_pixels_opt, kPixels);
align_buffer_page_end(dst_pixels_c, kPixels);
MemRandomize(src_pixels, kPixels * 4);
MemRandomize(dst_pixels_opt, kPixels);
memcpy(dst_pixels_c, dst_pixels_opt, kPixels);
MaskCpuFlags(disable_cpu_flags_);
ARGBExtractAlpha(src_pixels, benchmark_width_ * 4,
dst_pixels_c, benchmark_width_,
benchmark_width_, benchmark_height_);
MaskCpuFlags(benchmark_cpu_info_);
for (int i = 0; i < benchmark_iterations_; ++i) {
ARGBExtractAlpha(src_pixels, benchmark_width_ * 4,
dst_pixels_opt, benchmark_width_,
benchmark_width_, benchmark_height_);
}
for (int i = 0; i < kPixels; ++i) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_page_end(dst_pixels_c);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(src_pixels);
}
TEST_F(LibYUVPlanarTest, TestARGBCopyYToAlpha) {
const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_64(orig_pixels, kPixels);
align_buffer_64(dst_pixels_opt, kPixels * 4);
align_buffer_64(dst_pixels_c, kPixels * 4);
align_buffer_page_end(orig_pixels, kPixels);
align_buffer_page_end(dst_pixels_opt, kPixels * 4);
align_buffer_page_end(dst_pixels_c, kPixels * 4);
MemRandomize(orig_pixels, kPixels);
MemRandomize(dst_pixels_opt, kPixels * 4);
@ -2415,9 +2244,9 @@ TEST_F(LibYUVPlanarTest, TestARGBCopyYToAlpha) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_64(dst_pixels_c);
free_aligned_buffer_64(dst_pixels_opt);
free_aligned_buffer_64(orig_pixels);
free_aligned_buffer_page_end(dst_pixels_c);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(orig_pixels);
}
static int TestARGBRect(int width, int height, int benchmark_iterations,
@ -2430,8 +2259,8 @@ static int TestARGBRect(int width, int height, int benchmark_iterations,
const int kSize = kStride * height;
const uint32 v32 = fastrand() & (bpp == 4 ? 0xffffffff : 0xff);
align_buffer_64(dst_argb_c, kSize + off);
align_buffer_64(dst_argb_opt, kSize + off);
align_buffer_page_end(dst_argb_c, kSize + off);
align_buffer_page_end(dst_argb_opt, kSize + off);
MemRandomize(dst_argb_c + off, kSize);
memcpy(dst_argb_opt + off, dst_argb_c + off, kSize);
@ -2460,8 +2289,8 @@ static int TestARGBRect(int width, int height, int benchmark_iterations,
max_diff = abs_diff;
}
}
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
return max_diff;
}
@ -2529,4 +2358,99 @@ TEST_F(LibYUVPlanarTest, SetPlane_Opt) {
EXPECT_EQ(0, max_diff);
}
TEST_F(LibYUVPlanarTest, MergeUVPlane_Opt) {
const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_page_end(src_pixels, kPixels * 2);
align_buffer_page_end(tmp_pixels_u, kPixels);
align_buffer_page_end(tmp_pixels_v, kPixels);
align_buffer_page_end(dst_pixels_opt, kPixels * 2);
align_buffer_page_end(dst_pixels_c, kPixels * 2);
MemRandomize(src_pixels, kPixels * 2);
MemRandomize(tmp_pixels_u, kPixels);
MemRandomize(tmp_pixels_v, kPixels);
MemRandomize(dst_pixels_opt, kPixels * 2);
MemRandomize(dst_pixels_c, kPixels * 2);
MaskCpuFlags(disable_cpu_flags_);
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_c, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
MaskCpuFlags(benchmark_cpu_info_);
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
for (int i = 0; i < benchmark_iterations_; ++i) {
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_opt, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
}
for (int i = 0; i < kPixels * 2; ++i) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_page_end(src_pixels);
free_aligned_buffer_page_end(tmp_pixels_u);
free_aligned_buffer_page_end(tmp_pixels_v);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(dst_pixels_c);
}
TEST_F(LibYUVPlanarTest, SplitUVPlane_Opt) {
const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_page_end(src_pixels, kPixels * 2);
align_buffer_page_end(tmp_pixels_u, kPixels);
align_buffer_page_end(tmp_pixels_v, kPixels);
align_buffer_page_end(dst_pixels_opt, kPixels * 2);
align_buffer_page_end(dst_pixels_c, kPixels * 2);
MemRandomize(src_pixels, kPixels * 2);
MemRandomize(tmp_pixels_u, kPixels);
MemRandomize(tmp_pixels_v, kPixels);
MemRandomize(dst_pixels_opt, kPixels * 2);
MemRandomize(dst_pixels_c, kPixels * 2);
MaskCpuFlags(disable_cpu_flags_);
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_c, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
MaskCpuFlags(benchmark_cpu_info_);
for (int i = 0; i < benchmark_iterations_; ++i) {
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
}
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_opt, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
for (int i = 0; i < kPixels * 2; ++i) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_page_end(src_pixels);
free_aligned_buffer_page_end(tmp_pixels_u);
free_aligned_buffer_page_end(tmp_pixels_v);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(dst_pixels_c);
}
} // namespace libyuv

View File

@ -12,7 +12,6 @@
#include "libyuv/cpu_id.h"
#include "libyuv/rotate_argb.h"
#include "libyuv/row.h"
#include "../unit_test/unit_test.h"
namespace libyuv {
@ -38,15 +37,15 @@ void TestRotateBpp(int src_width, int src_height,
}
int src_stride_argb = src_width * kBpp;
int src_argb_plane_size = src_stride_argb * abs(src_height);
align_buffer_64(src_argb, src_argb_plane_size);
align_buffer_page_end(src_argb, src_argb_plane_size);
for (int i = 0; i < src_argb_plane_size; ++i) {
src_argb[i] = fastrand() & 0xff;
}
int dst_stride_argb = dst_width * kBpp;
int dst_argb_plane_size = dst_stride_argb * dst_height;
align_buffer_64(dst_argb_c, dst_argb_plane_size);
align_buffer_64(dst_argb_opt, dst_argb_plane_size);
align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
memset(dst_argb_c, 2, dst_argb_plane_size);
memset(dst_argb_opt, 3, dst_argb_plane_size);
@ -81,9 +80,9 @@ void TestRotateBpp(int src_width, int src_height,
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]);
}
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_64(src_argb);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
free_aligned_buffer_page_end(src_argb);
}
static void ARGBTestRotate(int src_width, int src_height,

View File

@ -12,7 +12,6 @@
#include "libyuv/cpu_id.h"
#include "libyuv/rotate.h"
#include "libyuv/row.h"
#include "../unit_test/unit_test.h"
namespace libyuv {
@ -37,7 +36,7 @@ static void I420TestRotate(int src_width, int src_height,
int src_i420_y_size = src_width * Abs(src_height);
int src_i420_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2);
int src_i420_size = src_i420_y_size + src_i420_uv_size * 2;
align_buffer_64(src_i420, src_i420_size);
align_buffer_page_end(src_i420, src_i420_size);
for (int i = 0; i < src_i420_size; ++i) {
src_i420[i] = fastrand() & 0xff;
}
@ -45,8 +44,8 @@ static void I420TestRotate(int src_width, int src_height,
int dst_i420_y_size = dst_width * dst_height;
int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
align_buffer_64(dst_i420_c, dst_i420_size);
align_buffer_64(dst_i420_opt, dst_i420_size);
align_buffer_page_end(dst_i420_c, dst_i420_size);
align_buffer_page_end(dst_i420_opt, dst_i420_size);
memset(dst_i420_c, 2, dst_i420_size);
memset(dst_i420_opt, 3, dst_i420_size);
@ -78,9 +77,9 @@ static void I420TestRotate(int src_width, int src_height,
EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
}
free_aligned_buffer_64(dst_i420_c);
free_aligned_buffer_64(dst_i420_opt);
free_aligned_buffer_64(src_i420);
free_aligned_buffer_page_end(dst_i420_c);
free_aligned_buffer_page_end(dst_i420_opt);
free_aligned_buffer_page_end(src_i420);
}
TEST_F(LibYUVRotateTest, I420Rotate0_Opt) {
@ -163,7 +162,7 @@ static void NV12TestRotate(int src_width, int src_height,
int src_nv12_uv_size =
((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2) * 2;
int src_nv12_size = src_nv12_y_size + src_nv12_uv_size;
align_buffer_64(src_nv12, src_nv12_size);
align_buffer_page_end(src_nv12, src_nv12_size);
for (int i = 0; i < src_nv12_size; ++i) {
src_nv12[i] = fastrand() & 0xff;
}
@ -171,8 +170,8 @@ static void NV12TestRotate(int src_width, int src_height,
int dst_i420_y_size = dst_width * dst_height;
int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
align_buffer_64(dst_i420_c, dst_i420_size);
align_buffer_64(dst_i420_opt, dst_i420_size);
align_buffer_page_end(dst_i420_c, dst_i420_size);
align_buffer_page_end(dst_i420_opt, dst_i420_size);
memset(dst_i420_c, 2, dst_i420_size);
memset(dst_i420_opt, 3, dst_i420_size);
@ -201,9 +200,9 @@ static void NV12TestRotate(int src_width, int src_height,
EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
}
free_aligned_buffer_64(dst_i420_c);
free_aligned_buffer_64(dst_i420_opt);
free_aligned_buffer_64(src_nv12);
free_aligned_buffer_page_end(dst_i420_c);
free_aligned_buffer_page_end(dst_i420_opt);
free_aligned_buffer_page_end(src_nv12);
}
TEST_F(LibYUVRotateTest, NV12Rotate0_Opt) {

View File

@ -11,10 +11,9 @@
#include <stdlib.h>
#include <time.h>
#include "libyuv/convert_argb.h"
#include "libyuv/cpu_id.h"
#include "libyuv/convert.h"
#include "libyuv/scale_argb.h"
#include "libyuv/row.h"
#include "libyuv/video_common.h"
#include "../unit_test/unit_test.h"
@ -28,6 +27,10 @@ static int ARGBTestFilter(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode f, int benchmark_iterations,
int disable_cpu_flags, int benchmark_cpu_info) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
int i, j;
const int b = 0; // 128 to test for padding/stride.
int64 src_argb_plane_size = (Abs(src_width) + b * 2) *
@ -143,12 +146,16 @@ static int TileARGBScale(const uint8* src_argb, int src_stride_argb,
static int ARGBClipTestFilter(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode f, int benchmark_iterations) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
const int b = 128;
int64 src_argb_plane_size = (Abs(src_width) + b * 2) *
(Abs(src_height) + b * 2) * 4;
int src_stride_argb = (b * 2 + Abs(src_width)) * 4;
align_buffer_64(src_argb, src_argb_plane_size);
align_buffer_page_end(src_argb, src_argb_plane_size);
if (!src_argb) {
printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
return 0;
@ -165,8 +172,8 @@ static int ARGBClipTestFilter(int src_width, int src_height,
}
}
align_buffer_64(dst_argb_c, dst_argb_plane_size);
align_buffer_64(dst_argb_opt, dst_argb_plane_size);
align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
if (!dst_argb_c || !dst_argb_opt) {
printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
return 0;
@ -208,9 +215,9 @@ static int ARGBClipTestFilter(int src_width, int src_height,
}
}
free_aligned_buffer_64(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt);
free_aligned_buffer_64(src_argb);
free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_page_end(dst_argb_opt);
free_aligned_buffer_page_end(src_argb);
return max_diff;
}
@ -314,8 +321,7 @@ int YUVToARGBScaleReference2(const uint8* src_y, int src_stride_y,
int clip_x, int clip_y,
int clip_width, int clip_height,
enum FilterMode filtering) {
uint8* argb_buffer = (uint8*)malloc(src_width * src_height * 4);
uint8* argb_buffer = static_cast<uint8*>(malloc(src_width * src_height * 4));
int r;
I420ToARGB(src_y, src_stride_y,
src_u, src_stride_u,

View File

@ -25,6 +25,10 @@ static int TestFilter(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode f, int benchmark_iterations,
int disable_cpu_flags, int benchmark_cpu_info) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
int i, j;
const int b = 0; // 128 to test for padding/stride.
int src_width_uv = (Abs(src_width) + 1) >> 1;
@ -148,6 +152,10 @@ static int TestFilter(int src_width, int src_height,
static int TestFilter_16(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode f, int benchmark_iterations) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
int i, j;
const int b = 0; // 128 to test for padding/stride.
int src_width_uv = (Abs(src_width) + 1) >> 1;
@ -274,8 +282,8 @@ static int TestFilter_16(int src_width, int src_height,
// The following adjustments in dimensions ensure the scale factor will be
// exactly achieved.
// 2 is chroma subsample
#define DX(x, nom, denom) static_cast<int>((Abs(x) / nom / 2) * nom * 2)
#define SX(x, nom, denom) static_cast<int>((x / nom / 2) * denom * 2)
#define DX(x, nom, denom) static_cast<int>(((Abs(x) / nom + 1) / 2) * nom * 2)
#define SX(x, nom, denom) static_cast<int>(((x / nom + 1) / 2) * denom * 2)
#define TEST_FACTOR1(name, filter, nom, denom, max_diff) \
TEST_F(LibYUVScaleTest, ScaleDownBy##name##_##filter) { \
@ -306,10 +314,10 @@ static int TestFilter_16(int src_width, int src_height,
TEST_FACTOR(2, 1, 2, 0)
TEST_FACTOR(4, 1, 4, 0)
TEST_FACTOR(8, 1, 8, 3)
TEST_FACTOR(8, 1, 8, 0)
TEST_FACTOR(3by4, 3, 4, 1)
TEST_FACTOR(3by8, 3, 8, 1)
TEST_FACTOR(3, 1, 3, 3)
TEST_FACTOR(3, 1, 3, 0)
#undef TEST_FACTOR1
#undef TEST_FACTOR
#undef SX
@ -348,9 +356,9 @@ TEST_FACTOR(3, 1, 3, 3)
// Test scale to a specified size with all 4 filters.
#define TEST_SCALETO(name, width, height) \
TEST_SCALETO1(name, width, height, None, 0) \
TEST_SCALETO1(name, width, height, Linear, 3) \
TEST_SCALETO1(name, width, height, Bilinear, 3) \
TEST_SCALETO1(name, width, height, Box, 3)
TEST_SCALETO1(name, width, height, Linear, 0) \
TEST_SCALETO1(name, width, height, Bilinear, 0) \
TEST_SCALETO1(name, width, height, Box, 0)
TEST_SCALETO(Scale, 1, 1)
TEST_SCALETO(Scale, 320, 240)

View File

@ -25,16 +25,17 @@ unsigned int fastrand_seed = 0xfb;
DEFINE_int32(libyuv_width, 0, "width of test image.");
DEFINE_int32(libyuv_height, 0, "height of test image.");
DEFINE_int32(libyuv_repeat, 0, "number of times to repeat test.");
DEFINE_int32(libyuv_flags, 0, "cpu flags for reference code. 0 = C -1 = asm");
DEFINE_int32(libyuv_cpu_info, -1,
"cpu flags for benchmark code. -1 = SIMD, 1 = C");
DEFINE_int32(libyuv_flags, 0,
"cpu flags for reference code. 1 = C, -1 = SIMD");
DEFINE_int32(libyuv_cpu_info, 0,
"cpu flags for benchmark code. 1 = C, -1 = SIMD");
// For quicker unittests, default is 128 x 72. But when benchmarking,
// default to 720p. Allow size to specify.
// Set flags to -1 for benchmarking to avoid slower C code.
LibYUVConvertTest::LibYUVConvertTest() :
benchmark_iterations_(BENCHMARK_ITERATIONS), benchmark_width_(130),
benchmark_iterations_(BENCHMARK_ITERATIONS), benchmark_width_(128),
benchmark_height_(72), disable_cpu_flags_(1), benchmark_cpu_info_(-1) {
const char* repeat = getenv("LIBYUV_REPEAT");
if (repeat) {

View File

@ -22,18 +22,54 @@
#include "libyuv/basic_types.h"
#ifndef SIMD_ALIGNED
#if defined(_MSC_VER) && !defined(__CLR_VER)
#define SIMD_ALIGNED(var) __declspec(align(16)) var
#elif defined(__GNUC__) && !defined(__pnacl__)
#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
#else
#define SIMD_ALIGNED(var) var
#endif
#endif
static __inline int Abs(int v) {
return v >= 0 ? v : -v;
}
#define OFFBY 0
// Scaling uses 16.16 fixed point to step thru the source image, so a
// maximum size of 32767.999 can be expressed. 32768 is valid because
// the step is 1 beyond the image but not used.
// Destination size is mainly constrained by valid scale step not the
// absolute size, so it may be possible to relax the destination size
// constraint.
// Source size is unconstrained for most specialized scalers. e.g.
// An image of 65536 scaled to half size would be valid. The test
// could be relaxed for special scale factors.
// If this test is removed, the scaling function should gracefully
// fail with a return code. The test could be changed to know that
// libyuv failed in a controlled way.
static const int kMaxWidth = 32768;
static const int kMaxHeight = 32768;
static inline bool SizeValid(int src_width, int src_height,
int dst_width, int dst_height) {
if (src_width > kMaxWidth || src_height > kMaxHeight ||
dst_width > kMaxWidth || dst_height > kMaxHeight) {
printf("Warning - size too large to test. Skipping\n");
return false;
}
return true;
}
#define align_buffer_page_end(var, size) \
uint8* var; \
uint8* var##_mem; \
var##_mem = reinterpret_cast<uint8*>(malloc((((size) + 4095) & ~4095) + \
OFFBY)); \
var = var##_mem + (-(size) & 4095) + OFFBY;
var##_mem = reinterpret_cast<uint8*>(malloc(((size) + 4095 + 63) & ~4095)); \
var = (uint8*)((intptr_t)(var##_mem + (((size) + 4095 + 63) & ~4095) - \
(size)) & ~63);
#define free_aligned_buffer_page_end(var) \
free(var##_mem); \
@ -55,6 +91,16 @@ static inline double get_time() {
}
#endif
#ifndef SIMD_ALIGNED
#if defined(_MSC_VER) && !defined(__CLR_VER)
#define SIMD_ALIGNED(var) __declspec(align(16)) var
#elif defined(__GNUC__) && !defined(__pnacl__)
#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
#else
#define SIMD_ALIGNED(var) var
#endif
#endif
extern unsigned int fastrand_seed;
inline int fastrand() {
fastrand_seed = fastrand_seed * 214013u + 2531011u;

View File

@ -43,6 +43,7 @@ static bool TestValidFourCC(uint32 fourcc, int bpp) {
TEST_F(LibYUVBaseTest, TestCanonicalFourCC) {
EXPECT_EQ(FOURCC_I420, CanonicalFourCC(FOURCC_IYUV));
EXPECT_EQ(FOURCC_I420, CanonicalFourCC(FOURCC_YU12));
EXPECT_EQ(FOURCC_I422, CanonicalFourCC(FOURCC_YU16));
EXPECT_EQ(FOURCC_I444, CanonicalFourCC(FOURCC_YU24));
EXPECT_EQ(FOURCC_YUY2, CanonicalFourCC(FOURCC_YUYV));

View File

@ -10,7 +10,7 @@
// Get SSIM for video sequence. Assuming RAW 4:2:0 Y:Cb:Cr format
#ifndef UTIL_SSIM_H_ // NOLINT
#ifndef UTIL_SSIM_H_
#define UTIL_SSIM_H_
#include <math.h> // For log10()
@ -33,4 +33,4 @@ double CalcLSSIM(double ssim);
} // extern "C"
#endif
#endif // UTIL_SSIM_H_ // NOLINT
#endif // UTIL_SSIM_H_