mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-07 17:26:49 +08:00
Function to switch filters to a simplier one based on scale factors.
BUG=none TEST=untested R=tpsiaki@google.com Review URL: https://webrtc-codereview.appspot.com/4989004 git-svn-id: http://libyuv.googlecode.com/svn/trunk@894 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
99a1298c54
commit
ec0cc5bb2d
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 892
|
||||
Version: 894
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -18,12 +18,12 @@ namespace libyuv {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Supported filtering
|
||||
// Supported filtering.
|
||||
enum FilterMode {
|
||||
kFilterNone = 0, // Point sample; Fastest.
|
||||
kFilterBilinear = 1, // Faster than box, but lower quality scaling down.
|
||||
kFilterBox = 2, // Highest quality.
|
||||
kFilterLinear = 3 // Faster than bilinear, slower than None.
|
||||
kFilterLinear = 1, // Filter horizontally only.
|
||||
kFilterBilinear = 2, // Faster than box, but lower quality scaling down.
|
||||
kFilterBox = 3 // Highest quality.
|
||||
};
|
||||
|
||||
// Scale a YUV plane.
|
||||
|
||||
@ -55,6 +55,10 @@ extern "C" {
|
||||
#define HAS_SCALEROWDOWN38_MIPS_DSPR2
|
||||
#endif
|
||||
|
||||
FilterMode ScaleFilterReduce(int src_width, int src_height,
|
||||
int dst_width, int dst_height,
|
||||
FilterMode filtering);
|
||||
|
||||
// Scale ARGB vertically with bilinear interpolation.
|
||||
void ScalePlaneVertical(int src_height,
|
||||
int dst_width, int dst_height,
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 892
|
||||
#define LIBYUV_VERSION 894
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||
|
||||
@ -768,6 +768,11 @@ void ScalePlane(const uint8* src, int src_stride,
|
||||
uint8* dst, int dst_stride,
|
||||
int dst_width, int dst_height,
|
||||
FilterMode filtering) {
|
||||
// Simplify filtering when possible.
|
||||
filtering = ScaleFilterReduce(src_width, src_height,
|
||||
dst_width, dst_height,
|
||||
filtering);
|
||||
|
||||
// Negative height means invert the image.
|
||||
if (src_height < 0) {
|
||||
src_height = -src_height;
|
||||
|
||||
@ -572,6 +572,16 @@ static void ScaleARGB(const uint8* src, int src_stride,
|
||||
int dst_width, int dst_height,
|
||||
int clip_x, int clip_y, int clip_width, int clip_height,
|
||||
FilterMode filtering) {
|
||||
// ARGB does not support box filter yet, but allow the user to pass it.
|
||||
// TODO(fbarchard): Support Box filter. Move row function to common.
|
||||
if (filtering == kFilterBox) {
|
||||
filtering = kFilterBilinear;
|
||||
}
|
||||
// Simplify filtering when possible.
|
||||
filtering = ScaleFilterReduce(src_width, src_height,
|
||||
dst_width, dst_height,
|
||||
filtering);
|
||||
|
||||
// Negative src_height means invert the image.
|
||||
if (src_height < 0) {
|
||||
src_height = -src_height;
|
||||
|
||||
@ -460,18 +460,20 @@ void ScalePlaneVertical(int src_height,
|
||||
const uint8* src_argb, uint8* dst_argb,
|
||||
int x, int y, int dy,
|
||||
int bpp, FilterMode filtering) {
|
||||
int dst_widthx4 = dst_width * bpp;
|
||||
src_argb += (x >> 16) * bpp;
|
||||
// TODO(fbarchard): Allow higher bpp.
|
||||
assert(bpp >= 1 && bpp <= 4);
|
||||
assert(src_height != 0);
|
||||
assert(dst_width > 0);
|
||||
assert(dst_height > 0);
|
||||
int dst_width_bytes = dst_width * bpp;
|
||||
src_argb += (x >> 16) * bpp;
|
||||
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
|
||||
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
|
||||
InterpolateRow_C;
|
||||
#if defined(HAS_INTERPOLATEROW_SSE2)
|
||||
if (TestCpuFlag(kCpuHasSSE2) && dst_widthx4 >= 16) {
|
||||
if (TestCpuFlag(kCpuHasSSE2) && dst_width_bytes >= 16) {
|
||||
InterpolateRow = InterpolateRow_Any_SSE2;
|
||||
if (IS_ALIGNED(dst_widthx4, 16)) {
|
||||
if (IS_ALIGNED(dst_width_bytes, 16)) {
|
||||
InterpolateRow = InterpolateRow_Unaligned_SSE2;
|
||||
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) &&
|
||||
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) {
|
||||
@ -481,9 +483,9 @@ void ScalePlaneVertical(int src_height,
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_INTERPOLATEROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3) && dst_widthx4 >= 16) {
|
||||
if (TestCpuFlag(kCpuHasSSSE3) && dst_width_bytes >= 16) {
|
||||
InterpolateRow = InterpolateRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(dst_widthx4, 16)) {
|
||||
if (IS_ALIGNED(dst_width_bytes, 16)) {
|
||||
InterpolateRow = InterpolateRow_Unaligned_SSSE3;
|
||||
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) &&
|
||||
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) {
|
||||
@ -493,27 +495,27 @@ void ScalePlaneVertical(int src_height,
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_INTERPOLATEROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2) && dst_widthx4 >= 32) {
|
||||
if (TestCpuFlag(kCpuHasAVX2) && dst_width_bytes >= 32) {
|
||||
InterpolateRow = InterpolateRow_Any_AVX2;
|
||||
if (IS_ALIGNED(dst_widthx4, 32)) {
|
||||
if (IS_ALIGNED(dst_width_bytes, 32)) {
|
||||
InterpolateRow = InterpolateRow_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_INTERPOLATEROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON) && dst_widthx4 >= 16) {
|
||||
if (TestCpuFlag(kCpuHasNEON) && dst_width_bytes >= 16) {
|
||||
InterpolateRow = InterpolateRow_Any_NEON;
|
||||
if (IS_ALIGNED(dst_widthx4, 16)) {
|
||||
if (IS_ALIGNED(dst_width_bytes, 16)) {
|
||||
InterpolateRow = InterpolateRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_INTERPOLATEROWS_MIPS_DSPR2)
|
||||
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && dst_widthx4 >= 4 &&
|
||||
if (TestCpuFlag(kCpuHasMIPS_DSPR2) && dst_width_bytes >= 4 &&
|
||||
IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) &&
|
||||
IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) {
|
||||
InterpolateRow = InterpolateRow_Any_MIPS_DSPR2;
|
||||
if (IS_ALIGNED(dst_widthx4, 4)) {
|
||||
if (IS_ALIGNED(dst_width_bytes, 4)) {
|
||||
InterpolateRow = InterpolateRow_MIPS_DSPR2;
|
||||
}
|
||||
}
|
||||
@ -526,12 +528,53 @@ void ScalePlaneVertical(int src_height,
|
||||
int yi = y >> 16;
|
||||
int yf = filtering ? ((y >> 8) & 255) : 0;
|
||||
const uint8* src = src_argb + yi * src_stride;
|
||||
InterpolateRow(dst_argb, src, src_stride, dst_widthx4, yf);
|
||||
InterpolateRow(dst_argb, src, src_stride, dst_width_bytes, yf);
|
||||
dst_argb += dst_stride;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
|
||||
// Scale plane vertically with bilinear interpolation.
|
||||
FilterMode ScaleFilterReduce(int src_width, int src_height,
|
||||
int dst_width, int dst_height,
|
||||
FilterMode filtering) {
|
||||
if (src_width < 0) {
|
||||
src_width = -src_width;
|
||||
}
|
||||
if (src_height < 0) {
|
||||
src_height = -src_height;
|
||||
}
|
||||
if (filtering == kFilterBox) {
|
||||
// If scaling both axis to 0.5 or larger, switch from Box to Bilinear.
|
||||
if (dst_width * 2 >= src_width && dst_height * 2 >= src_height) {
|
||||
filtering = kFilterBilinear;
|
||||
}
|
||||
// If scaling to larger, switch from Box to Bilinear.
|
||||
if (dst_width >= src_width || dst_height >= src_height) {
|
||||
filtering = kFilterBilinear;
|
||||
}
|
||||
}
|
||||
if (filtering == kFilterBilinear) {
|
||||
if (src_height == 1) {
|
||||
filtering = kFilterLinear;
|
||||
}
|
||||
// TODO(fbarchard): Detect any odd scale factor and reduce to Linear.
|
||||
if (dst_height == src_height || dst_height * 3 == src_height) {
|
||||
filtering = kFilterLinear;
|
||||
}
|
||||
}
|
||||
if (filtering == kFilterLinear) {
|
||||
if (src_width == 1) {
|
||||
filtering = kFilterNone;
|
||||
}
|
||||
// TODO(fbarchard): Detect any odd scale factor and reduce to None.
|
||||
if (dst_width == src_width || dst_width * 3 == src_width) {
|
||||
filtering = kFilterNone;
|
||||
}
|
||||
}
|
||||
return filtering;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user