Commit c7277d08 authored by fbarchard@google.com's avatar fbarchard@google.com

Add convert_from_argb.h for all conversion functions from ARGB to something else.

BUG=none
TEST=convert_test
Review URL: https://webrtc-codereview.appspot.com/857014

git-svn-id: http://libyuv.googlecode.com/svn/trunk@408 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 0cbbdde3
......@@ -9,6 +9,7 @@ LOCAL_SRC_FILES := \
source/compare.cc \
source/convert.cc \
source/convert_from.cc \
source/convert_from_argb.cc \
source/cpu_id.cc \
source/format_conversion.cc \
source/planar_functions.cc \
......
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 407
Version: 408
License: BSD
License File: LICENSE
......
......@@ -16,6 +16,7 @@
#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/format_conversion.h"
#include "libyuv/planar_functions.h"
......
/*
* Copyright 2012 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_CONVERT_FROM_ARGB_H_ // NOLINT
#define INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Alias.
#define ARGBToARGB ARGBCopy
// Copy ARGB to ARGB.
LIBYUV_API
int ARGBCopy(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert ARGB To RGBA.
LIBYUV_API
int ARGBToRGBA(const uint8* src_frame, int src_stride_frame,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert ARGB To RGB24.
LIBYUV_API
int ARGBToRGB24(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb24, int dst_stride_rgb24,
int width, int height);
// Convert ARGB To RAW.
LIBYUV_API
int ARGBToRAW(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb, int dst_stride_rgb,
int width, int height);
// Convert ARGB To RGB565.
LIBYUV_API
int ARGBToRGB565(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height);
// Convert ARGB To ARGB1555.
LIBYUV_API
int ARGBToARGB1555(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb1555, int dst_stride_argb1555,
int width, int height);
// Convert ARGB To ARGB4444.
LIBYUV_API
int ARGBToARGB4444(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb4444, int dst_stride_argb4444,
int width, int height);
// Convert ARGB to I400.
LIBYUV_API
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
int width, int height);
// ARGB little endian (bgra in memory) to I422.
LIBYUV_API
int ARGBToI422(const uint8* src_frame, int src_stride_frame,
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);
// Aliases.
#define ARGBToBGRA BGRAToARGB
#define ARGBToABGR ABGRToARGB
// BGRA little endian (argb in memory) to ARGB.
LIBYUV_API
int BGRAToARGB(const uint8* src_frame, int src_stride_frame,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// ABGR little endian (rgba in memory) to ARGB.
LIBYUV_API
int ABGRToARGB(const uint8* src_frame, int src_stride_frame,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ NOLINT
......@@ -18,8 +18,8 @@ namespace libyuv {
extern "C" {
#endif
// Internal flag to indicate cpuid is initialized.
static const int kCpuInitialized = 0x1;
// Internal flag to indicate cpuid requires initialization.
static const int kCpuInit = 0x1;
// These flags are only valid on ARM processors.
static const int kCpuHasARM = 0x2;
......@@ -46,9 +46,9 @@ int ArmCpuCaps(const char* cpuinfo_name);
// Detect CPU has SSE2 etc.
// Test_flag parameter should be one of kCpuHas constants above.
// returns non-zero if instruction set is detected
LIBYUV_API extern int cpu_info_;
static __inline int TestCpuFlag(int test_flag) {
return (cpu_info_ ? cpu_info_ : InitCpuFlags()) & test_flag;
LIBYUV_API extern int cpu_info_;
return (cpu_info_ == 1 ? InitCpuFlags() : cpu_info_) & test_flag;
}
// For testing, allow CPU flags to be disabled.
......
......@@ -92,60 +92,6 @@ int NV21ToRGB565(const uint8* src_y, int src_stride_y,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height);
// Aliases.
#define ARGBToBGRA BGRAToARGB
#define ARGBToABGR ABGRToARGB
// Convert ARGB To RGBA.
LIBYUV_API
int ARGBToRGBA(const uint8* src_frame, int src_stride_frame,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert ARGB To RGB24.
LIBYUV_API
int ARGBToRGB24(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb24, int dst_stride_rgb24,
int width, int height);
// Convert ARGB To RAW.
LIBYUV_API
int ARGBToRAW(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb, int dst_stride_rgb,
int width, int height);
// Convert ARGB To RGB565.
LIBYUV_API
int ARGBToRGB565(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height);
// Convert ARGB To ARGB1555.
LIBYUV_API
int ARGBToARGB1555(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb1555, int dst_stride_argb1555,
int width, int height);
// Convert ARGB To ARGB4444.
LIBYUV_API
int ARGBToARGB4444(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb4444, int dst_stride_argb4444,
int width, int height);
// Convert ARGB to I400.
LIBYUV_API
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
int width, int height);
// ARGB little endian (bgra in memory) to I422.
LIBYUV_API
int ARGBToI422(const uint8* src_frame, int src_stride_frame,
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);
// I422ToARGB is in convert_argb.h
// Convert I422 to BGRA.
LIBYUV_API
......
......@@ -117,7 +117,9 @@ extern "C" {
// The following are available on Neon platforms
#if !defined(YUV_DISABLE_ASM) && (defined(__ARM_NEON__) || defined(LIBYUV_NEON))
#define HAS_ABGRTOARGBROW_NEON
#define HAS_ARGBTOBAYERROW_NEON
#define HAS_BGRATOARGBROW_NEON
#define HAS_COPYROW_NEON
#define HAS_HALFROW_NEON
#define HAS_I422TOABGRROW_NEON
......@@ -128,6 +130,9 @@ extern "C" {
#define HAS_I422TORGBAROW_NEON
#define HAS_MIRRORROW_NEON
#define HAS_MIRRORROWUV_NEON
#define HAS_RAWTOARGBROW_NEON
#define HAS_RGB24TOARGBROW_NEON
#define HAS_RGBATOARGBROW_NEON
#define HAS_SETROW_NEON
#define HAS_SPLITUV_NEON
#define HAS_UYVYTOUV422ROW_NEON
......@@ -138,16 +143,11 @@ extern "C" {
#define HAS_YUY2TOYROW_NEON
// TODO(fbarchard): Hook these up to calling functions.
#define HAS_ABGRTOARGBROW_NEON
#define HAS_ARGBTORAWROW_NEON
#define HAS_ARGBTORGB24ROW_NEON
#define HAS_ARGBTORGBAROW_NEON
#define HAS_BGRATOARGBROW_NEON
#define HAS_NV12TOARGBROW_NEON
#define HAS_NV21TOARGBROW_NEON
#define HAS_RAWTOARGBROW_NEON
#define HAS_RGB24TOARGBROW_NEON
#define HAS_RGBATOARGBROW_NEON
#endif
#if defined(_MSC_VER) && !defined(__CLR_VER)
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 407
#define LIBYUV_VERSION 408
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
......@@ -50,6 +50,7 @@
'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/format_conversion.h',
'include/libyuv/mjpeg_decoder.h',
......@@ -68,6 +69,7 @@
'source/convert.cc',
'source/convert_argb.cc',
'source/convert_from.cc',
'source/convert_from_argb.cc',
'source/cpu_id.cc',
'source/format_conversion.cc',
'source/mjpeg_decoder.cc',
......
......@@ -27,6 +27,7 @@
# sources
'unit_test/compare_test.cc',
'unit_test/convert_test.cc',
'unit_test/cpu_test.cc',
'unit_test/planar_test.cc',
'unit_test/rotate_argb_test.cc',
......
......@@ -208,8 +208,7 @@ int I400ToARGB_Reference(const uint8* src_y, int src_stride_y,
uint8* rgb_buf,
int width) = YToARGBRow_C;
#if defined(HAS_YTOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) &&
IS_ALIGNED(width, 8) &&
if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 8) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
YToARGBRow = YToARGBRow_SSE2;
}
......@@ -241,8 +240,7 @@ int I400ToARGB(const uint8* src_y, int src_stride_y,
void (*I400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int pix) =
I400ToARGBRow_C;
#if defined(HAS_I400TOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) &&
IS_ALIGNED(width, 8) &&
if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 8) &&
IS_ALIGNED(src_y, 8) && IS_ALIGNED(src_stride_y, 8) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
I400ToARGBRow = I400ToARGBRow_SSE2;
......@@ -275,12 +273,15 @@ int BGRAToARGB(const uint8* src_bgra, int src_stride_bgra,
void (*BGRAToARGBRow)(const uint8* src_bgra, uint8* dst_argb, int pix) =
BGRAToARGBRow_C;
#if defined(HAS_BGRATOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 4) &&
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_bgra, 16) && IS_ALIGNED(src_stride_bgra, 16) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
BGRAToARGBRow = BGRAToARGBRow_SSSE3;
}
#elif defined(HAS_BGRATOARGBROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
BGRAToARGBRow = BGRAToARGBRow_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
......@@ -309,12 +310,15 @@ int ABGRToARGB(const uint8* src_abgr, int src_stride_abgr,
void (*ABGRToARGBRow)(const uint8* src_abgr, uint8* dst_argb, int pix) =
ABGRToARGBRow_C;
#if defined(HAS_ABGRTOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 4) &&
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_abgr, 16) && IS_ALIGNED(src_stride_abgr, 16) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
ABGRToARGBRow = ABGRToARGBRow_SSSE3;
}
#elif defined(HAS_ABGRTOARGBROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
ABGRToARGBRow = ABGRToARGBRow_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
......@@ -343,12 +347,15 @@ int RGBAToARGB(const uint8* src_rgba, int src_stride_rgba,
void (*RGBAToARGBRow)(const uint8* src_rgba, uint8* dst_argb, int pix) =
RGBAToARGBRow_C;
#if defined(HAS_RGBATOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 4) &&
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_rgba, 16) && IS_ALIGNED(src_stride_rgba, 16) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
RGBAToARGBRow = RGBAToARGBRow_SSSE3;
}
#elif defined(HAS_RGBATOARGBROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
RGBAToARGBRow = RGBAToARGBRow_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
......@@ -359,67 +366,73 @@ int RGBAToARGB(const uint8* src_rgba, int src_stride_rgba,
return 0;
}
// Convert RAW to ARGB.
// Convert RGB24 to ARGB.
LIBYUV_API
int RAWToARGB(const uint8* src_raw, int src_stride_raw,
uint8* dst_argb, int dst_stride_argb,
int width, int height) {
if (!src_raw || !dst_argb ||
int RGB24ToARGB(const uint8* src_rgb24, int src_stride_rgb24,
uint8* dst_argb, int dst_stride_argb,
int width, int height) {
if (!src_rgb24 || !dst_argb ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_raw = src_raw + (height - 1) * src_stride_raw;
src_stride_raw = -src_stride_raw;
src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24;
src_stride_rgb24 = -src_stride_rgb24;
}
void (*RAWToARGBRow)(const uint8* src_raw, uint8* dst_argb, int pix) =
RAWToARGBRow_C;
#if defined(HAS_RAWTOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 16) &&
void (*RGB24ToARGBRow)(const uint8* src_rgb24, uint8* dst_argb, int pix) =
RGB24ToARGBRow_C;
#if defined(HAS_RGB24TOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
RAWToARGBRow = RAWToARGBRow_SSSE3;
RGB24ToARGBRow = RGB24ToARGBRow_SSSE3;
}
#elif defined(HAS_RGB24TOARGBROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
RGB24ToARGBRow = RGB24ToARGBRow_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
RAWToARGBRow(src_raw, dst_argb, width);
src_raw += src_stride_raw;
RGB24ToARGBRow(src_rgb24, dst_argb, width);
src_rgb24 += src_stride_rgb24;
dst_argb += dst_stride_argb;
}
return 0;
}
// Convert RGB24 to ARGB.
// Convert RAW to ARGB.
LIBYUV_API
int RGB24ToARGB(const uint8* src_rgb24, int src_stride_rgb24,
uint8* dst_argb, int dst_stride_argb,
int width, int height) {
if (!src_rgb24 || !dst_argb ||
int RAWToARGB(const uint8* src_raw, int src_stride_raw,
uint8* dst_argb, int dst_stride_argb,
int width, int height) {
if (!src_raw || !dst_argb ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24;
src_stride_rgb24 = -src_stride_rgb24;
src_raw = src_raw + (height - 1) * src_stride_raw;
src_stride_raw = -src_stride_raw;
}
void (*RGB24ToARGBRow)(const uint8* src_rgb24, uint8* dst_argb, int pix) =
RGB24ToARGBRow_C;
#if defined(HAS_RGB24TOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 16) &&
void (*RAWToARGBRow)(const uint8* src_raw, uint8* dst_argb, int pix) =
RAWToARGBRow_C;
#if defined(HAS_RAWTOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16) &&
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
RGB24ToARGBRow = RGB24ToARGBRow_SSSE3;
RAWToARGBRow = RAWToARGBRow_SSSE3;
}
#elif defined(HAS_RAWTOARGBROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
RAWToARGBRow = RAWToARGBRow_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
RGB24ToARGBRow(src_rgb24, dst_argb, width);
src_rgb24 += src_stride_rgb24;
RAWToARGBRow(src_raw, dst_argb, width);
src_raw += src_stride_raw;
dst_argb += dst_stride_argb;
}
return 0;
......
/*
* Copyright 2012 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/convert_from_argb.h"
#include "libyuv/basic_types.h"
#include "libyuv/cpu_id.h"
#include "libyuv/format_conversion.h"
#include "libyuv/planar_functions.h"
#include "libyuv/row.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Convert ARGB to I400.
LIBYUV_API
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
int width, int height) {
if (!src_argb || !dst_y || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) =
ARGBToYRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToYRow(src_argb, dst_y, width);
src_argb += src_stride_argb;
dst_y += dst_stride_y;
}
return 0;
}
// ARGB little endian (bgra in memory) to I422
// same as I420 except UV plane is full height
LIBYUV_API
int ARGBToI422(const uint8* src_argb, int src_stride_argb,
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) {
if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) =
ARGBToYRow_C;
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
if (width > 16) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_Any_SSSE3;
}
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
}
}
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
ARGBToYRow(src_argb, dst_y, width);
src_argb += src_stride_argb;
dst_y += dst_stride_y;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
return 0;
}
// Convert ARGB to RGBA.
LIBYUV_API
int ARGBToRGBA(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgba, int dst_stride_rgba,
int width, int height) {
if (!src_argb || !dst_rgba ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRGBARow)(const uint8* src_argb, uint8* dst_rgba, int pix) =
ARGBToRGBARow_C;
#if defined(HAS_ARGBTORGBAROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_rgba, 16) && IS_ALIGNED(dst_stride_rgba, 16)) {
ARGBToRGBARow = ARGBToRGBARow_SSSE3;
}
#elif defined(HAS_ARGBTORGBAROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
ARGBToRGBARow = ARGBToRGBARow_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRGBARow(src_argb, dst_rgba, width);
src_argb += src_stride_argb;
dst_rgba += dst_stride_rgba;
}
return 0;
}
// Convert ARGB To RGB24.
LIBYUV_API
int ARGBToRGB24(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb24, int dst_stride_rgb24,
int width, int height) {
if (!src_argb || !dst_rgb24 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRGB24Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToRGB24Row_C;
#if defined(HAS_ARGBTORGB24ROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_rgb24, 16) && IS_ALIGNED(dst_stride_rgb24, 16)) {
ARGBToRGB24Row = ARGBToRGB24Row_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToRGB24Row = ARGBToRGB24Row_SSSE3;
}
}
#elif defined(HAS_ARGBTORGB24ROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
ARGBToRGB24Row = ARGBToRGB24Row_Any_NEON;
if (IS_ALIGNED(width, 8)) {
ARGBToRGB24Row = ARGBToRGB24Row_NEON;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRGB24Row(src_argb, dst_rgb24, width);
src_argb += src_stride_argb;
dst_rgb24 += dst_stride_rgb24;
}
return 0;
}
// Convert ARGB To RAW.
LIBYUV_API
int ARGBToRAW(const uint8* src_argb, int src_stride_argb,
uint8* dst_raw, int dst_stride_raw,
int width, int height) {
if (!src_argb || !dst_raw || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRAWRow)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToRAWRow_C;
#if defined(HAS_ARGBTORAWROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_raw, 16) && IS_ALIGNED(dst_stride_raw, 16)) {
ARGBToRAWRow = ARGBToRAWRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToRAWRow = ARGBToRAWRow_SSSE3;
}
}
#elif defined(HAS_ARGBTORAWROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
ARGBToRAWRow = ARGBToRAWRow_Any_NEON;
if (IS_ALIGNED(width, 8)) {
ARGBToRAWRow = ARGBToRAWRow_NEON;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRAWRow(src_argb, dst_raw, width);
src_argb += src_stride_argb;
dst_raw += dst_stride_raw;
}
return 0;
}
// Convert ARGB To RGB565.
LIBYUV_API
int ARGBToRGB565(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height) {
if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRGB565Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToRGB565Row_C;
#if defined(HAS_ARGBTORGB565ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && width >= 4 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToRGB565Row = ARGBToRGB565Row_Any_SSE2;
if (IS_ALIGNED(width, 4)) {
ARGBToRGB565Row = ARGBToRGB565Row_SSE2;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRGB565Row(src_argb, dst_rgb565, width);
src_argb += src_stride_argb;
dst_rgb565 += dst_stride_rgb565;
}
return 0;
}
// Convert ARGB To ARGB1555.
LIBYUV_API
int ARGBToARGB1555(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb1555, int dst_stride_argb1555,
int width, int height) {
if (!src_argb || !dst_argb1555 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToARGB1555Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToARGB1555Row_C;
#if defined(HAS_ARGBTOARGB1555ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && width >= 4 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToARGB1555Row = ARGBToARGB1555Row_Any_SSE2;
if (IS_ALIGNED(width, 4)) {
ARGBToARGB1555Row = ARGBToARGB1555Row_SSE2;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToARGB1555Row(src_argb, dst_argb1555, width);
src_argb += src_stride_argb;
dst_argb1555 += dst_stride_argb1555;
}
return 0;
}
// Convert ARGB To ARGB4444.
LIBYUV_API
int ARGBToARGB4444(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb4444, int dst_stride_argb4444,
int width, int height) {
if (!src_argb || !dst_argb4444 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToARGB4444Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToARGB4444Row_C;
#if defined(HAS_ARGBTOARGB4444ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && width >= 4 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToARGB4444Row = ARGBToARGB4444Row_Any_SSE2;
if (IS_ALIGNED(width, 4)) {
ARGBToARGB4444Row = ARGBToARGB4444Row_SSE2;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToARGB4444Row(src_argb, dst_argb4444, width);
src_argb += src_stride_argb;
dst_argb4444 += dst_stride_argb4444;
}
return 0;
}
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
......@@ -107,7 +107,6 @@ int ArmCpuCaps(const char* cpuinfo_name) {
char buf[512];
while (fgets(buf, 511, fin)) {
if (memcmp(buf, "Features", 8) == 0) {
flags |= kCpuInitialized;
char* p = strstr(buf, " neon");
if (p && (p[5] == ' ' || p[5] == '\n')) {
flags |= kCpuHasNEON;
......@@ -121,8 +120,9 @@ int ArmCpuCaps(const char* cpuinfo_name) {
}
// CPU detect function for SIMD instruction sets.
// TODO(fbarchard): Use constant if/when valgrind says cpu_info is initialized.
LIBYUV_API
int cpu_info_ = 0;
int cpu_info_ = 1; // 1 means cpu info is not initialized yet.
// Test environment variable for disabling CPU features. Any non-zero value
// to disable. Zero ignored to make it easy to set the variable on/off.
......@@ -146,7 +146,7 @@ int InitCpuFlags(void) {
((cpu_info[2] & 0x00080000) ? kCpuHasSSE41 : 0) |
((cpu_info[2] & 0x00100000) ? kCpuHasSSE42 : 0) |
(((cpu_info[2] & 0x18000000) == 0x18000000) ? kCpuHasAVX : 0) |
kCpuInitialized | kCpuHasX86;
kCpuHasX86;
#ifdef HAS_XGETBV
if (cpu_info_ & kCpuHasAVX) {
__cpuid(cpu_info, 7);
......@@ -179,7 +179,7 @@ int InitCpuFlags(void) {
cpu_info_ &= ~kCpuHasAVX2;
}
if (TestEnv("LIBYUV_DISABLE_ASM")) {
cpu_info_ = kCpuInitialized;
cpu_info_ = 0;
}
#elif defined(__arm__)
#if defined(__linux__) && (defined(__ARM_NEON__) || defined(LIBYUV_NEON))
......@@ -191,12 +191,12 @@ int InitCpuFlags(void) {
// to disable Neon on devices that do not have it.
cpu_info_ = kCpuHasNEON;
#endif
cpu_info_ |= kCpuInitialized | kCpuHasARM;
cpu_info_ |= kCpuHasARM;
if (TestEnv("LIBYUV_DISABLE_NEON")) {
cpu_info_ &= ~kCpuHasNEON;
}
if (TestEnv("LIBYUV_DISABLE_ASM")) {
cpu_info_ = kCpuInitialized;
cpu_info_ = 0;
}
#endif // __arm__
return cpu_info_;
......@@ -204,8 +204,7 @@ int InitCpuFlags(void) {
LIBYUV_API
void MaskCpuFlags(int enable_flags) {
InitCpuFlags();
cpu_info_ = (cpu_info_ & enable_flags) | kCpuInitialized;
cpu_info_ = InitCpuFlags() & enable_flags;
}
#ifdef __cplusplus
......
......@@ -364,88 +364,6 @@ int ARGBBlend(const uint8* src_argb0, int src_stride_argb0,
return 0;
}
// Convert ARGB to I400.
LIBYUV_API
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
int width, int height) {
if (!src_argb || !dst_y || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) =
ARGBToYRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToYRow(src_argb, dst_y, width);
src_argb += src_stride_argb;
dst_y += dst_stride_y;
}
return 0;
}
// ARGB little endian (bgra in memory) to I422
// same as I420 except UV plane is full height
LIBYUV_API
int ARGBToI422(const uint8* src_argb, int src_stride_argb,
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) {
if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) =
ARGBToYRow_C;
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
if (width > 16) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_Any_SSSE3;
}
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
}
}
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
ARGBToYRow(src_argb, dst_y, width);
src_argb += src_stride_argb;
dst_y += dst_stride_y;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
return 0;
}
// Convert I422 to BGRA.
LIBYUV_API
int I422ToBGRA(const uint8* src_y, int src_stride_y,
......@@ -602,225 +520,6 @@ int I422ToRGBA(const uint8* src_y, int src_stride_y,
return 0;
}
// Convert ARGB to RGBA.
LIBYUV_API
int ARGBToRGBA(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgba, int dst_stride_rgba,
int width, int height) {
if (!src_argb || !dst_rgba ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRGBARow)(const uint8* src_argb, uint8* dst_rgba, int pix) =
ARGBToRGBARow_C;
#if defined(HAS_ARGBTORGBAROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) &&
IS_ALIGNED(width, 4) &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_rgba, 16) && IS_ALIGNED(dst_stride_rgba, 16)) {
ARGBToRGBARow = ARGBToRGBARow_SSSE3;
}
#elif defined(HAS_ARGBTORGBAROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
ARGBToRGBARow = ARGBToRGBARow_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRGBARow(src_argb, dst_rgba, width);
src_argb += src_stride_argb;
dst_rgba += dst_stride_rgba;
}
return 0;
}
// Convert ARGB To RGB24.
LIBYUV_API
int ARGBToRGB24(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb24, int dst_stride_rgb24,
int width, int height) {
if (!src_argb || !dst_rgb24 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRGB24Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToRGB24Row_C;
#if defined(HAS_ARGBTORGB24ROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_rgb24, 16) && IS_ALIGNED(dst_stride_rgb24, 16)) {
ARGBToRGB24Row = ARGBToRGB24Row_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToRGB24Row = ARGBToRGB24Row_SSSE3;
}
}
#elif defined(HAS_ARGBTORGB24ROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
ARGBToRGB24Row = ARGBToRGB24Row_Any_NEON;
if (IS_ALIGNED(width, 8)) {
ARGBToRGB24Row = ARGBToRGB24Row_NEON;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRGB24Row(src_argb, dst_rgb24, width);
src_argb += src_stride_argb;
dst_rgb24 += dst_stride_rgb24;
}
return 0;
}
// Convert ARGB To RAW.
LIBYUV_API
int ARGBToRAW(const uint8* src_argb, int src_stride_argb,
uint8* dst_raw, int dst_stride_raw,
int width, int height) {
if (!src_argb || !dst_raw || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRAWRow)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToRAWRow_C;
#if defined(HAS_ARGBTORAWROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) &&
IS_ALIGNED(dst_raw, 16) && IS_ALIGNED(dst_stride_raw, 16)) {
ARGBToRAWRow = ARGBToRAWRow_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
ARGBToRAWRow = ARGBToRAWRow_SSSE3;
}
}
#elif defined(HAS_ARGBTORAWROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
ARGBToRAWRow = ARGBToRAWRow_Any_NEON;
if (IS_ALIGNED(width, 8)) {
ARGBToRAWRow = ARGBToRAWRow_NEON;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRAWRow(src_argb, dst_raw, width);
src_argb += src_stride_argb;
dst_raw += dst_stride_raw;
}
return 0;
}
// Convert ARGB To RGB565.
LIBYUV_API
int ARGBToRGB565(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height) {
if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToRGB565Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToRGB565Row_C;
#if defined(HAS_ARGBTORGB565ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && width >= 4 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToRGB565Row = ARGBToRGB565Row_Any_SSE2;
if (IS_ALIGNED(width, 4)) {
ARGBToRGB565Row = ARGBToRGB565Row_SSE2;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToRGB565Row(src_argb, dst_rgb565, width);
src_argb += src_stride_argb;
dst_rgb565 += dst_stride_rgb565;
}
return 0;
}
// Convert ARGB To ARGB1555.
LIBYUV_API
int ARGBToARGB1555(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb1555, int dst_stride_argb1555,
int width, int height) {
if (!src_argb || !dst_argb1555 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToARGB1555Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToARGB1555Row_C;
#if defined(HAS_ARGBTOARGB1555ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && width >= 4 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToARGB1555Row = ARGBToARGB1555Row_Any_SSE2;
if (IS_ALIGNED(width, 4)) {
ARGBToARGB1555Row = ARGBToARGB1555Row_SSE2;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToARGB1555Row(src_argb, dst_argb1555, width);
src_argb += src_stride_argb;
dst_argb1555 += dst_stride_argb1555;
}
return 0;
}
// Convert ARGB To ARGB4444.
LIBYUV_API
int ARGBToARGB4444(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb4444, int dst_stride_argb4444,
int width, int height) {
if (!src_argb || !dst_argb4444 || width <= 0 || height == 0) {
return -1;
}
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToARGB4444Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
ARGBToARGB4444Row_C;
#if defined(HAS_ARGBTOARGB4444ROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && width >= 4 &&
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToARGB4444Row = ARGBToARGB4444Row_Any_SSE2;
if (IS_ALIGNED(width, 4)) {
ARGBToARGB4444Row = ARGBToARGB4444Row_SSE2;
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToARGB4444Row(src_argb, dst_argb4444, width);
src_argb += src_stride_argb;
dst_argb4444 += dst_stride_argb4444;
}
return 0;
}
// Convert NV12 to RGB565.
// TODO(fbarchard): One pass conversion.
LIBYUV_API
......
......@@ -62,7 +62,7 @@ TEST_F(libyuvTest, BenchmakDjb2_C) {
}
uint32 h2 = ReferenceHashDjb2(src_a, kMaxTest, 5381);
uint32 h1;
MaskCpuFlags(kCpuInitialized);
MaskCpuFlags(0); \
for (int i = 0; i < benchmark_iterations_; ++i) {
h1 = HashDjb2(src_a, kMaxTest, 5381);
}
......@@ -108,7 +108,7 @@ TEST_F(libyuvTest, BenchmarkSumSquareError_C) {
align_buffer_16(src_a, kMaxWidth)
align_buffer_16(src_b, kMaxWidth)
MaskCpuFlags(kCpuInitialized);
MaskCpuFlags(0); \
memcpy(src_a, "test0123test4567", 16);
memcpy(src_b, "tick0123tock4567", 16);
......@@ -189,7 +189,7 @@ TEST_F(libyuvTest, SumSquareError) {
src_b[i] = (random() & 0xff);
}
MaskCpuFlags(kCpuInitialized);
MaskCpuFlags(0); \
uint64 c_err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
MaskCpuFlags(-1);
......@@ -210,7 +210,7 @@ TEST_F(libyuvTest, BenchmarkPsnr_C) {
src_b[i] = i;
}
MaskCpuFlags(kCpuInitialized);
MaskCpuFlags(0); \
double c_time = get_time();
for (int i = 0; i < benchmark_iterations_; ++i)
......@@ -313,7 +313,7 @@ TEST_F(libyuvTest, Psnr) {
}
}
MaskCpuFlags(kCpuInitialized);
MaskCpuFlags(0); \
double c_err, opt_err;
c_err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
......@@ -341,7 +341,7 @@ TEST_F(libyuvTest, BenchmarkSsim_C) {
src_b[i] = i;
}
MaskCpuFlags(kCpuInitialized);
MaskCpuFlags(0); \
double c_time = get_time();
for (int i = 0; i < benchmark_iterations_; ++i)
......@@ -440,7 +440,7 @@ TEST_F(libyuvTest, Ssim) {
}
}
MaskCpuFlags(kCpuInitialized);
MaskCpuFlags(0); \
double c_err, opt_err;
c_err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
......
/*
* Copyright 2011 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 <stdlib.h>
#include <time.h>
#include "libyuv/compare.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/format_conversion.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
#include "../unit_test/unit_test.h"
#if defined(_MSC_VER)
#define SIMD_ALIGNED(var) __declspec(align(16)) var
#else // __GNUC__
#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
#endif
namespace libyuv {
#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG) \
TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
align_buffer_16(src_y, kWidth * kHeight); \
align_buffer_16(src_u, kWidth / SRC_SUBSAMP_X * kHeight / SRC_SUBSAMP_Y); \
align_buffer_16(src_v, kWidth / SRC_SUBSAMP_X * kHeight / SRC_SUBSAMP_Y); \
align_buffer_16(dst_y_c, kWidth * kHeight); \
align_buffer_16(dst_u_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_y_opt, kWidth * kHeight); \
align_buffer_16(dst_u_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kWidth; ++j) \
src_y[(i * kWidth) + j] = (random() & 0xff); \
for (int i = 0; i < kHeight / SRC_SUBSAMP_Y; ++i) \
for (int j = 0; j < kWidth / SRC_SUBSAMP_X; ++j) { \
src_u[(i * kWidth / SRC_SUBSAMP_X) + j] = (random() & 0xff); \
src_v[(i * kWidth / SRC_SUBSAMP_X) + j] = (random() & 0xff); \
} \
MaskCpuFlags(0); \
SRC_FMT_PLANAR##To##FMT_PLANAR(src_y, kWidth, \
src_u, kWidth / SRC_SUBSAMP_X, \
src_v, kWidth / SRC_SUBSAMP_X, \
dst_y_c, kWidth, \
dst_u_c, kWidth / SUBSAMP_X, \
dst_v_c, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
SRC_FMT_PLANAR##To##FMT_PLANAR(src_y, kWidth, \
src_u, kWidth / SRC_SUBSAMP_X, \
src_v, kWidth / SRC_SUBSAMP_X, \
dst_y_opt, kWidth, \
dst_u_opt, kWidth / SUBSAMP_X, \
dst_v_opt, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_u_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_u_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_v_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_v_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(dst_y_c) \
free_aligned_buffer_16(dst_u_c) \
free_aligned_buffer_16(dst_v_c) \
free_aligned_buffer_16(dst_y_opt) \
free_aligned_buffer_16(dst_u_opt) \
free_aligned_buffer_16(dst_v_opt) \
free_aligned_buffer_16(src_y) \
free_aligned_buffer_16(src_u) \
free_aligned_buffer_16(src_v) \
}
#define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, 1280, _Opt, +) \
TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, 1280, _Invert, -) \
TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, 1276, _Any, +)
TESTPLANARTOP(I420, 2, 2, I420, 2, 2)
TESTPLANARTOP(I422, 2, 1, I420, 2, 2)
TESTPLANARTOP(I444, 1, 1, I420, 2, 2)
TESTPLANARTOP(I411, 4, 1, I420, 2, 2)
TESTPLANARTOP(I420, 2, 2, I422, 2, 1)
TESTPLANARTOP(I420, 2, 2, I444, 1, 1)
TESTPLANARTOP(I420, 2, 2, I411, 4, 1)
#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
W1280, N, NEG) \
TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
const int kStrideB = ((kWidth * 8 * BPP_B + 7) / 8 + ALIGN - 1) / \
ALIGN * ALIGN; \
align_buffer_16(src_y, kWidth * kHeight); \
align_buffer_16(src_u, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(src_v, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_argb_c, kStrideB * kHeight); \
align_buffer_16(dst_argb_opt, kStrideB * kHeight); \
memset(dst_argb_c, 0, kStrideB * kHeight); \
memset(dst_argb_opt, 0, kStrideB * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
src_y[(i * kWidth) + j] = (random() & 0xff); \
} \
} \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
src_u[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
src_v[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
} \
} \
MaskCpuFlags(0); \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_u, kWidth / SUBSAMP_X, \
src_v, kWidth / SUBSAMP_X, \
dst_argb_c, kStrideB, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_u, kWidth / SUBSAMP_X, \
src_v, kWidth / SUBSAMP_X, \
dst_argb_opt, kStrideB, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth * BPP_B; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i * kStrideB + j]) - \
static_cast<int>(dst_argb_opt[i * kStrideB + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(src_y) \
free_aligned_buffer_16(src_u) \
free_aligned_buffer_16(src_v) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN) \
TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
1280, _Opt, +) \
TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
1280, _Invert, -) \
TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
1276, _Any, +)
TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4)
TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4)
TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4)
TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4)
TESTPLANARTOB(I420, 2, 2, RAW, 3, 3)
TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3)
TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2)
TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2)
TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2)
TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4)
TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4)
TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4)
TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4)
TESTPLANARTOB(I411, 4, 1, ARGB, 4, 4)
TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4)
TESTPLANARTOB(I420, 2, 2, V210, 16 / 6, 128)
TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4)
TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4)
TESTPLANARTOB(I420, 2, 2, I400, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerBGGR, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerRGGB, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerGBRG, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerGRBG, 1, 1)
#define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
W1280, N, NEG) \
TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
align_buffer_16(src_y, kWidth * kHeight); \
align_buffer_16(src_uv, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y * 2); \
align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight); \
align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kWidth; ++j) \
src_y[(i * kWidth) + j] = (random() & 0xff); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) \
for (int j = 0; j < kWidth / SUBSAMP_X * 2; ++j) { \
src_uv[(i * kWidth / SUBSAMP_X) * 2 + j] = (random() & 0xff); \
} \
MaskCpuFlags(0); \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_uv, kWidth / SUBSAMP_X * 2, \
dst_argb_c, kWidth * BPP_B, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_uv, kWidth / SUBSAMP_X * 2, \
dst_argb_opt, kWidth * BPP_B, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth * BPP_B; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i * kWidth * BPP_B + j]) - \
static_cast<int>(dst_argb_opt[i * kWidth * BPP_B + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 3); \
free_aligned_buffer_16(src_y) \
free_aligned_buffer_16(src_uv) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
1280, _Opt, +) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
1280, _Invert, -) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
1276, _Any, +)
TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4)
TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4)
TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2)
TESTBIPLANARTOB(NV21, 2, 2, RGB565, 2)
#define TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
W1280, N, NEG) \
TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
const int kStride = (kWidth * 8 * BPP_A + 7) / 8; \
align_buffer_16(src_argb, kStride * kHeight); \
align_buffer_16(dst_y_c, kWidth * kHeight); \
align_buffer_16(dst_u_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_y_opt, kWidth * kHeight); \
align_buffer_16(dst_u_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kStride; ++j) \
src_argb[(i * kStride) + j] = (random() & 0xff); \
MaskCpuFlags(0); \
FMT_A##To##FMT_PLANAR(src_argb, kStride, \
dst_y_c, kWidth, \
dst_u_c, kWidth / SUBSAMP_X, \
dst_v_c, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_A##To##FMT_PLANAR(src_argb, kStride, \
dst_y_opt, kWidth, \
dst_u_opt, kWidth / SUBSAMP_X, \
dst_v_opt, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_u_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_u_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_v_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_v_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(dst_y_c) \
free_aligned_buffer_16(dst_u_c) \
free_aligned_buffer_16(dst_v_c) \
free_aligned_buffer_16(dst_y_opt) \
free_aligned_buffer_16(dst_u_opt) \
free_aligned_buffer_16(dst_v_opt) \
free_aligned_buffer_16(src_argb) \
}
#define TESTATOPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
1280, _Opt, +) \
TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
1280, _Invert, -) \
TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
1276, _Any, +)
TESTATOPLANAR(ARGB, 4, I420, 2, 2)
TESTATOPLANAR(BGRA, 4, I420, 2, 2)
TESTATOPLANAR(ABGR, 4, I420, 2, 2)
TESTATOPLANAR(RGBA, 4, I420, 2, 2)
TESTATOPLANAR(RAW, 3, I420, 2, 2)
TESTATOPLANAR(RGB24, 3, I420, 2, 2)
TESTATOPLANAR(RGB565, 2, I420, 2, 2)
TESTATOPLANAR(ARGB1555, 2, I420, 2, 2)
TESTATOPLANAR(ARGB4444, 2, I420, 2, 2)
// TESTATOPLANAR(ARGB, 4, I411, 4, 1)
TESTATOPLANAR(ARGB, 4, I422, 2, 1)
// TESTATOPLANAR(ARGB, 4, I444, 1, 1)
// TODO(fbarchard): Implement and test 411 and 444
TESTATOPLANAR(V210, 16 / 6, I420, 2, 2)
TESTATOPLANAR(YUY2, 2, I420, 2, 2)
TESTATOPLANAR(UYVY, 2, I420, 2, 2)
TESTATOPLANAR(YUY2, 2, I422, 2, 1)
TESTATOPLANAR(UYVY, 2, I422, 2, 1)
TESTATOPLANAR(I400, 1, I420, 2, 2)
TESTATOPLANAR(BayerBGGR, 1, I420, 2, 2)
TESTATOPLANAR(BayerRGGB, 1, I420, 2, 2)
TESTATOPLANAR(BayerGBRG, 1, I420, 2, 2)
TESTATOPLANAR(BayerGRBG, 1, I420, 2, 2)
#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, W1280, N, NEG) \
TEST_F(libyuvTest, FMT_A##To##FMT_B##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
align_buffer_16(src_argb, (kWidth * BPP_A) * kHeight); \
align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight); \
align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight * kWidth * BPP_A; ++i) { \
src_argb[i] = (random() & 0xff); \
} \
MaskCpuFlags(0); \
FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A, \
dst_argb_c, kWidth * BPP_B, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A, \
dst_argb_opt, kWidth * BPP_B, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight * kWidth * BPP_B; ++i) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i]) - \
static_cast<int>(dst_argb_opt[i])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(src_argb) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
#define TESTATOB(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, 1280, _Opt, +) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, 1280, _Invert, -) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, 1280, _Any, +)
TESTATOB(ARGB, 4, 4, ARGB, 4)
TESTATOB(ARGB, 4, 4, BGRA, 4)
TESTATOB(ARGB, 4, 4, ABGR, 4)
TESTATOB(ARGB, 4, 4, RGBA, 4)
TESTATOB(ARGB, 4, 4, RAW, 3)
TESTATOB(ARGB, 4, 4, RGB24, 3)
TESTATOB(ARGB, 4, 4, RGB565, 2)
TESTATOB(ARGB, 4, 4, ARGB1555, 2)
TESTATOB(ARGB, 4, 4, ARGB4444, 2)
TESTATOB(ARGB, 4, 4, BayerBGGR, 1)
TESTATOB(ARGB, 4, 4, BayerRGGB, 1)
TESTATOB(ARGB, 4, 4, BayerGBRG, 1)
TESTATOB(ARGB, 4, 4, BayerGRBG, 1)
TESTATOB(ARGB, 4, 4, I400, 1)
TESTATOB(BGRA, 4, 4, ARGB, 4)
TESTATOB(ABGR, 4, 4, ARGB, 4)
TESTATOB(RGBA, 4, 4, ARGB, 4)
TESTATOB(RAW, 3, 3, ARGB, 4)
TESTATOB(RGB24, 3, 3, ARGB, 4)
TESTATOB(RGB565, 2, 2, ARGB, 4)
TESTATOB(ARGB1555, 2, 2, ARGB, 4)
TESTATOB(ARGB4444, 2, 2, ARGB, 4)
TESTATOB(YUY2, 2, 2, ARGB, 4)
TESTATOB(UYVY, 2, 2, ARGB, 4)
TESTATOB(M420, 3 / 2, 1, ARGB, 4)
TESTATOB(BayerBGGR, 1, 1, ARGB, 4)
TESTATOB(BayerRGGB, 1, 1, ARGB, 4)
TESTATOB(BayerGBRG, 1, 1, ARGB, 4)
TESTATOB(BayerGRBG, 1, 1, ARGB, 4)
TESTATOB(I400, 1, 1, ARGB, 4)
TESTATOB(I400, 1, 1, I400, 1)
#define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, STRIDE_B) \
TEST_F(libyuvTest, FMT_A##To##FMT_B##_Random) { \
srandom(time(NULL)); \
for (int times = 0; times < benchmark_iterations_; ++times) { \
const int kWidth = (random() & 63) + 1; \
const int kHeight = (random() & 31) + 1; \
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_page_end(src_argb, kStrideA * kHeight); \
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[i] = (random() & 0xff); \
} \
MaskCpuFlags(0); \
FMT_A##To##FMT_B(src_argb, kStrideA, \
dst_argb_c, kStrideB, \
kWidth, kHeight); \
MaskCpuFlags(-1); \
FMT_A##To##FMT_B(src_argb, kStrideA, \
dst_argb_opt, kStrideB, \
kWidth, kHeight); \
int max_diff = 0; \
for (int i = 0; i < kStrideB * kHeight; ++i) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i]) - \
static_cast<int>(dst_argb_opt[i])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_page_end(src_argb) \
free_aligned_buffer_page_end(dst_argb_c) \
free_aligned_buffer_page_end(dst_argb_opt) \
} \
}
TESTATOBRANDOM(ARGB, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, BGRA, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, ABGR, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, RGBA, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, RAW, 3, 3)
TESTATOBRANDOM(ARGB, 4, 4, RGB24, 3, 3)
TESTATOBRANDOM(ARGB, 4, 4, RGB565, 2, 2)
TESTATOBRANDOM(ARGB, 4, 4, ARGB1555, 2, 2)
TESTATOBRANDOM(ARGB, 4, 4, ARGB4444, 2, 2)
TESTATOBRANDOM(ARGB, 4, 4, I400, 1, 1)
// TODO(fbarchard): Implement YUY2
// TESTATOBRANDOM(ARGB, 4, 4, YUY2, 4, 2)
// TESTATOBRANDOM(ARGB, 4, 4, UYVY, 4, 2)
TESTATOBRANDOM(BGRA, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(ABGR, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(RGBA, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(RAW, 3, 3, ARGB, 4, 4)
TESTATOBRANDOM(RGB24, 3, 3, ARGB, 4, 4)
TESTATOBRANDOM(RGB565, 2, 2, ARGB, 4, 4)
TESTATOBRANDOM(ARGB1555, 2, 2, ARGB, 4, 4)
TESTATOBRANDOM(ARGB4444, 2, 2, ARGB, 4, 4)
TESTATOBRANDOM(I400, 1, 1, ARGB, 4, 4)
TESTATOBRANDOM(YUY2, 4, 2, ARGB, 4, 4)
TESTATOBRANDOM(UYVY, 4, 2, ARGB, 4, 4)
TESTATOBRANDOM(I400, 1, 1, I400, 1, 1)
TEST_F(libyuvTest, Test565) {
SIMD_ALIGNED(uint8 orig_pixels[256][4]);
SIMD_ALIGNED(uint8 pixels565[256][2]);
for (int i = 0; i < 256; ++i) {
for (int j = 0; j < 4; ++j) {
orig_pixels[i][j] = i;
}
}
ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1);
uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381);
EXPECT_EQ(610919429u, checksum);
}
} // namespace libyuv
......@@ -19,7 +19,7 @@
namespace libyuv {
TEST_F(libyuvTest, TestCpuHas) {
int cpu_flags = TestCpuFlag(~kCpuInitialized);
int cpu_flags = TestCpuFlag(-1);
printf("Cpu Flags %x\n", cpu_flags);
int has_arm = TestCpuFlag(kCpuHasARM);
printf("Has ARM %x\n", has_arm);
......@@ -85,9 +85,9 @@ TEST_F(libyuvTest, TestCpuId) {
TEST_F(libyuvTest, TestLinuxNeon) {
int testdata = ArmCpuCaps("unit_test/testdata/arm_v7.txt");
if (testdata) {
EXPECT_EQ(kCpuInitialized,
EXPECT_EQ(0,
ArmCpuCaps("unit_test/testdata/arm_v7.txt"));
EXPECT_EQ((kCpuInitialized | kCpuHasNEON),
EXPECT_EQ(kCpuHasNEON,
ArmCpuCaps("unit_test/testdata/tegra3.txt"));
} else {
printf("WARNING: unable to load \"unit_test/testdata/arm_v7.txt\"\n");
......
......@@ -11,9 +11,11 @@
#include <stdlib.h>
#include <time.h>
#include "libyuv/compare.h"
#include "libyuv/convert.h"
#include "libyuv/convert_argb.h"
#include "libyuv/convert_from.h"
#include "libyuv/compare.h"
#include "libyuv/convert_from_argb.h"
#include "libyuv/cpu_id.h"
#include "libyuv/format_conversion.h"
#include "libyuv/planar_functions.h"
......@@ -28,502 +30,6 @@
namespace libyuv {
#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG) \
TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
align_buffer_16(src_y, kWidth * kHeight); \
align_buffer_16(src_u, kWidth / SRC_SUBSAMP_X * kHeight / SRC_SUBSAMP_Y); \
align_buffer_16(src_v, kWidth / SRC_SUBSAMP_X * kHeight / SRC_SUBSAMP_Y); \
align_buffer_16(dst_y_c, kWidth * kHeight); \
align_buffer_16(dst_u_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_y_opt, kWidth * kHeight); \
align_buffer_16(dst_u_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kWidth; ++j) \
src_y[(i * kWidth) + j] = (random() & 0xff); \
for (int i = 0; i < kHeight / SRC_SUBSAMP_Y; ++i) \
for (int j = 0; j < kWidth / SRC_SUBSAMP_X; ++j) { \
src_u[(i * kWidth / SRC_SUBSAMP_X) + j] = (random() & 0xff); \
src_v[(i * kWidth / SRC_SUBSAMP_X) + j] = (random() & 0xff); \
} \
MaskCpuFlags(kCpuInitialized); \
SRC_FMT_PLANAR##To##FMT_PLANAR(src_y, kWidth, \
src_u, kWidth / SRC_SUBSAMP_X, \
src_v, kWidth / SRC_SUBSAMP_X, \
dst_y_c, kWidth, \
dst_u_c, kWidth / SUBSAMP_X, \
dst_v_c, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
SRC_FMT_PLANAR##To##FMT_PLANAR(src_y, kWidth, \
src_u, kWidth / SRC_SUBSAMP_X, \
src_v, kWidth / SRC_SUBSAMP_X, \
dst_y_opt, kWidth, \
dst_u_opt, kWidth / SUBSAMP_X, \
dst_v_opt, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_u_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_u_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_v_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_v_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(dst_y_c) \
free_aligned_buffer_16(dst_u_c) \
free_aligned_buffer_16(dst_v_c) \
free_aligned_buffer_16(dst_y_opt) \
free_aligned_buffer_16(dst_u_opt) \
free_aligned_buffer_16(dst_v_opt) \
free_aligned_buffer_16(src_y) \
free_aligned_buffer_16(src_u) \
free_aligned_buffer_16(src_v) \
}
#define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, 1280, _Opt, +) \
TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, 1280, _Invert, -) \
TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, 1276, _Any, +)
TESTPLANARTOP(I420, 2, 2, I420, 2, 2)
TESTPLANARTOP(I422, 2, 1, I420, 2, 2)
TESTPLANARTOP(I444, 1, 1, I420, 2, 2)
TESTPLANARTOP(I411, 4, 1, I420, 2, 2)
TESTPLANARTOP(I420, 2, 2, I422, 2, 1)
TESTPLANARTOP(I420, 2, 2, I444, 1, 1)
TESTPLANARTOP(I420, 2, 2, I411, 4, 1)
#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
W1280, N, NEG) \
TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
const int kStrideB = ((kWidth * 8 * BPP_B + 7) / 8 + ALIGN - 1) / \
ALIGN * ALIGN; \
align_buffer_16(src_y, kWidth * kHeight); \
align_buffer_16(src_u, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(src_v, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_argb_c, kStrideB * kHeight); \
align_buffer_16(dst_argb_opt, kStrideB * kHeight); \
memset(dst_argb_c, 0, kStrideB * kHeight); \
memset(dst_argb_opt, 0, kStrideB * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
src_y[(i * kWidth) + j] = (random() & 0xff); \
} \
} \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
src_u[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
src_v[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
} \
} \
MaskCpuFlags(kCpuInitialized); \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_u, kWidth / SUBSAMP_X, \
src_v, kWidth / SUBSAMP_X, \
dst_argb_c, kStrideB, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_u, kWidth / SUBSAMP_X, \
src_v, kWidth / SUBSAMP_X, \
dst_argb_opt, kStrideB, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth * BPP_B; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i * kStrideB + j]) - \
static_cast<int>(dst_argb_opt[i * kStrideB + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(src_y) \
free_aligned_buffer_16(src_u) \
free_aligned_buffer_16(src_v) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN) \
TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
1280, _Opt, +) \
TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
1280, _Invert, -) \
TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
1276, _Any, +)
TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4)
TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4)
TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4)
TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4)
TESTPLANARTOB(I420, 2, 2, RAW, 3, 3)
TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3)
TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2)
TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2)
TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2)
TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4)
TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4)
TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4)
TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4)
TESTPLANARTOB(I411, 4, 1, ARGB, 4, 4)
TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4)
TESTPLANARTOB(I420, 2, 2, V210, 16 / 6, 128)
TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4)
TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4)
TESTPLANARTOB(I420, 2, 2, I400, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerBGGR, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerRGGB, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerGBRG, 1, 1)
TESTPLANARTOB(I420, 2, 2, BayerGRBG, 1, 1)
#define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
W1280, N, NEG) \
TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
align_buffer_16(src_y, kWidth * kHeight); \
align_buffer_16(src_uv, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y * 2); \
align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight); \
align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kWidth; ++j) \
src_y[(i * kWidth) + j] = (random() & 0xff); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) \
for (int j = 0; j < kWidth / SUBSAMP_X * 2; ++j) { \
src_uv[(i * kWidth / SUBSAMP_X) * 2 + j] = (random() & 0xff); \
} \
MaskCpuFlags(kCpuInitialized); \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_uv, kWidth / SUBSAMP_X * 2, \
dst_argb_c, kWidth * BPP_B, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_uv, kWidth / SUBSAMP_X * 2, \
dst_argb_opt, kWidth * BPP_B, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth * BPP_B; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i * kWidth * BPP_B + j]) - \
static_cast<int>(dst_argb_opt[i * kWidth * BPP_B + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 3); \
free_aligned_buffer_16(src_y) \
free_aligned_buffer_16(src_uv) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
1280, _Opt, +) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
1280, _Invert, -) \
TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
1276, _Any, +)
TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4)
TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4)
TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2)
TESTBIPLANARTOB(NV21, 2, 2, RGB565, 2)
#define TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
W1280, N, NEG) \
TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
const int kStride = (kWidth * 8 * BPP_A + 7) / 8; \
align_buffer_16(src_argb, kStride * kHeight); \
align_buffer_16(dst_y_c, kWidth * kHeight); \
align_buffer_16(dst_u_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_y_opt, kWidth * kHeight); \
align_buffer_16(dst_u_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kStride; ++j) \
src_argb[(i * kStride) + j] = (random() & 0xff); \
MaskCpuFlags(kCpuInitialized); \
FMT_A##To##FMT_PLANAR(src_argb, kStride, \
dst_y_c, kWidth, \
dst_u_c, kWidth / SUBSAMP_X, \
dst_v_c, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_A##To##FMT_PLANAR(src_argb, kStride, \
dst_y_opt, kWidth, \
dst_u_opt, kWidth / SUBSAMP_X, \
dst_v_opt, kWidth / SUBSAMP_X, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_u_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_u_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int abs_diff = \
abs(static_cast<int>(dst_v_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_v_opt[i * kWidth / SUBSAMP_X + j])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(dst_y_c) \
free_aligned_buffer_16(dst_u_c) \
free_aligned_buffer_16(dst_v_c) \
free_aligned_buffer_16(dst_y_opt) \
free_aligned_buffer_16(dst_u_opt) \
free_aligned_buffer_16(dst_v_opt) \
free_aligned_buffer_16(src_argb) \
}
#define TESTATOPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
1280, _Opt, +) \
TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
1280, _Invert, -) \
TESTATOPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
1276, _Any, +)
TESTATOPLANAR(ARGB, 4, I420, 2, 2)
TESTATOPLANAR(BGRA, 4, I420, 2, 2)
TESTATOPLANAR(ABGR, 4, I420, 2, 2)
TESTATOPLANAR(RGBA, 4, I420, 2, 2)
TESTATOPLANAR(RAW, 3, I420, 2, 2)
TESTATOPLANAR(RGB24, 3, I420, 2, 2)
TESTATOPLANAR(RGB565, 2, I420, 2, 2)
TESTATOPLANAR(ARGB1555, 2, I420, 2, 2)
TESTATOPLANAR(ARGB4444, 2, I420, 2, 2)
// TESTATOPLANAR(ARGB, 4, I411, 4, 1)
TESTATOPLANAR(ARGB, 4, I422, 2, 1)
// TESTATOPLANAR(ARGB, 4, I444, 1, 1)
// TODO(fbarchard): Implement and test 411 and 444
TESTATOPLANAR(V210, 16 / 6, I420, 2, 2)
TESTATOPLANAR(YUY2, 2, I420, 2, 2)
TESTATOPLANAR(UYVY, 2, I420, 2, 2)
TESTATOPLANAR(YUY2, 2, I422, 2, 1)
TESTATOPLANAR(UYVY, 2, I422, 2, 1)
TESTATOPLANAR(I400, 1, I420, 2, 2)
TESTATOPLANAR(BayerBGGR, 1, I420, 2, 2)
TESTATOPLANAR(BayerRGGB, 1, I420, 2, 2)
TESTATOPLANAR(BayerGBRG, 1, I420, 2, 2)
TESTATOPLANAR(BayerGRBG, 1, I420, 2, 2)
#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, W1280, N, NEG) \
TEST_F(libyuvTest, FMT_A##To##FMT_B##N) { \
const int kWidth = W1280; \
const int kHeight = 720; \
align_buffer_16(src_argb, (kWidth * BPP_A) * kHeight); \
align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight); \
align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight * kWidth * BPP_A; ++i) { \
src_argb[i] = (random() & 0xff); \
} \
MaskCpuFlags(kCpuInitialized); \
FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A, \
dst_argb_c, kWidth * BPP_B, \
kWidth, NEG kHeight); \
MaskCpuFlags(-1); \
for (int i = 0; i < benchmark_iterations_; ++i) { \
FMT_A##To##FMT_B(src_argb, kWidth * STRIDE_A, \
dst_argb_opt, kWidth * BPP_B, \
kWidth, NEG kHeight); \
} \
int max_diff = 0; \
for (int i = 0; i < kHeight * kWidth * BPP_B; ++i) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i]) - \
static_cast<int>(dst_argb_opt[i])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_16(src_argb) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
#define TESTATOB(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, 1280, _Opt, +) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, 1280, _Invert, -) \
TESTATOBI(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, 1280, _Any, +)
TESTATOB(ARGB, 4, 4, ARGB, 4)
TESTATOB(ARGB, 4, 4, BGRA, 4)
TESTATOB(ARGB, 4, 4, ABGR, 4)
TESTATOB(ARGB, 4, 4, RGBA, 4)
TESTATOB(ARGB, 4, 4, RAW, 3)
TESTATOB(ARGB, 4, 4, RGB24, 3)
TESTATOB(ARGB, 4, 4, RGB565, 2)
TESTATOB(ARGB, 4, 4, ARGB1555, 2)
TESTATOB(ARGB, 4, 4, ARGB4444, 2)
TESTATOB(ARGB, 4, 4, BayerBGGR, 1)
TESTATOB(ARGB, 4, 4, BayerRGGB, 1)
TESTATOB(ARGB, 4, 4, BayerGBRG, 1)
TESTATOB(ARGB, 4, 4, BayerGRBG, 1)
TESTATOB(ARGB, 4, 4, I400, 1)
TESTATOB(BGRA, 4, 4, ARGB, 4)
TESTATOB(ABGR, 4, 4, ARGB, 4)
TESTATOB(RGBA, 4, 4, ARGB, 4)
TESTATOB(RAW, 3, 3, ARGB, 4)
TESTATOB(RGB24, 3, 3, ARGB, 4)
TESTATOB(RGB565, 2, 2, ARGB, 4)
TESTATOB(ARGB1555, 2, 2, ARGB, 4)
TESTATOB(ARGB4444, 2, 2, ARGB, 4)
TESTATOB(YUY2, 2, 2, ARGB, 4)
TESTATOB(UYVY, 2, 2, ARGB, 4)
TESTATOB(M420, 3 / 2, 1, ARGB, 4)
TESTATOB(BayerBGGR, 1, 1, ARGB, 4)
TESTATOB(BayerRGGB, 1, 1, ARGB, 4)
TESTATOB(BayerGBRG, 1, 1, ARGB, 4)
TESTATOB(BayerGRBG, 1, 1, ARGB, 4)
TESTATOB(I400, 1, 1, ARGB, 4)
TESTATOB(I400, 1, 1, I400, 1)
#define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, FMT_B, BPP_B, STRIDE_B) \
TEST_F(libyuvTest, FMT_A##To##FMT_B##_Random) { \
srandom(time(NULL)); \
for (int times = 0; times < benchmark_iterations_; ++times) { \
const int kWidth = (random() & 63) + 1; \
const int kHeight = (random() & 31) + 1; \
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_page_end(src_argb, kStrideA * kHeight); \
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[i] = (random() & 0xff); \
} \
MaskCpuFlags(kCpuInitialized); \
FMT_A##To##FMT_B(src_argb, kStrideA, \
dst_argb_c, kStrideB, \
kWidth, kHeight); \
MaskCpuFlags(-1); \
FMT_A##To##FMT_B(src_argb, kStrideA, \
dst_argb_opt, kStrideB, \
kWidth, kHeight); \
int max_diff = 0; \
for (int i = 0; i < kStrideB * kHeight; ++i) { \
int abs_diff = \
abs(static_cast<int>(dst_argb_c[i]) - \
static_cast<int>(dst_argb_opt[i])); \
if (abs_diff > max_diff) { \
max_diff = abs_diff; \
} \
} \
EXPECT_LE(max_diff, 2); \
free_aligned_buffer_page_end(src_argb) \
free_aligned_buffer_page_end(dst_argb_c) \
free_aligned_buffer_page_end(dst_argb_opt) \
} \
}
TESTATOBRANDOM(ARGB, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, BGRA, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, ABGR, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, RGBA, 4, 4)
TESTATOBRANDOM(ARGB, 4, 4, RAW, 3, 3)
TESTATOBRANDOM(ARGB, 4, 4, RGB24, 3, 3)
TESTATOBRANDOM(ARGB, 4, 4, RGB565, 2, 2)
TESTATOBRANDOM(ARGB, 4, 4, ARGB1555, 2, 2)
TESTATOBRANDOM(ARGB, 4, 4, ARGB4444, 2, 2)
TESTATOBRANDOM(ARGB, 4, 4, I400, 1, 1)
// TODO(fbarchard): Implement YUY2
// TESTATOBRANDOM(ARGB, 4, 4, YUY2, 4, 2)
// TESTATOBRANDOM(ARGB, 4, 4, UYVY, 4, 2)
TESTATOBRANDOM(BGRA, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(ABGR, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(RGBA, 4, 4, ARGB, 4, 4)
TESTATOBRANDOM(RAW, 3, 3, ARGB, 4, 4)
TESTATOBRANDOM(RGB24, 3, 3, ARGB, 4, 4)
TESTATOBRANDOM(RGB565, 2, 2, ARGB, 4, 4)
TESTATOBRANDOM(ARGB1555, 2, 2, ARGB, 4, 4)
TESTATOBRANDOM(ARGB4444, 2, 2, ARGB, 4, 4)
TESTATOBRANDOM(I400, 1, 1, ARGB, 4, 4)
TESTATOBRANDOM(YUY2, 4, 2, ARGB, 4, 4)
TESTATOBRANDOM(UYVY, 4, 2, ARGB, 4, 4)
TESTATOBRANDOM(I400, 1, 1, I400, 1, 1)
TEST_F(libyuvTest, TestAttenuate) {
SIMD_ALIGNED(uint8 orig_pixels[256][4]);
SIMD_ALIGNED(uint8 atten_pixels[256][4]);
......@@ -1129,18 +635,4 @@ TEST_F(libyuvTest, TestAffine) {
#endif
}
TEST_F(libyuvTest, Test565) {
SIMD_ALIGNED(uint8 orig_pixels[256][4]);
SIMD_ALIGNED(uint8 pixels565[256][2]);
for (int i = 0; i < 256; ++i) {
for (int j = 0; j < 4; ++j) {
orig_pixels[i][j] = i;
}
}
ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1);
uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381);
EXPECT_EQ(610919429u, checksum);
}
} // namespace libyuv
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment