diff --git a/README.chromium b/README.chromium index b2dc03f38..175b15cba 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 891 +Version: 892 License: BSD License File: LICENSE diff --git a/include/libyuv/version.h b/include/libyuv/version.h index 0ef1a3c69..067914fd5 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 891 +#define LIBYUV_VERSION 892 #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT diff --git a/source/convert.cc b/source/convert.cc index edd6d274f..842ef094f 100644 --- a/source/convert.cc +++ b/source/convert.cc @@ -39,7 +39,7 @@ int I420Copy(const uint8* src_y, int src_stride_y, // Negative height means invert the image. if (height < 0) { height = -height; - int halfheight = (height + 1) >> 1; + const int 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; @@ -48,11 +48,12 @@ int I420Copy(const uint8* src_y, int src_stride_y, src_stride_v = -src_stride_v; } - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; if (dst_y) { CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } + // Copy UV planes. + const int halfwidth = (width + 1) >> 1; + const int halfheight = (height + 1) >> 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; @@ -89,15 +90,12 @@ int I422ToI420(const uint8* src_y, int src_stride_y, CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - - // Resample U plane. + // Resample UV planes. + const int halfwidth = (width + 1) >> 1; + const int halfheight = (height + 1) >> 1; ScalePlane(src_u, src_stride_u, halfwidth, height, dst_u, dst_stride_u, halfwidth, halfheight, kFilterBilinear); - - // Resample V plane. ScalePlane(src_v, src_stride_v, halfwidth, height, dst_v, dst_stride_v, halfwidth, halfheight, kFilterBilinear); @@ -135,15 +133,12 @@ int I444ToI420(const uint8* src_y, int src_stride_y, CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - - // Resample U plane. + // Resample UV planes. + const int halfwidth = (width + 1) >> 1; + const int halfheight = (height + 1) >> 1; ScalePlane(src_u, src_stride_u, width, height, dst_u, dst_stride_u, halfwidth, halfheight, kFilterBilinear); - - // Resample V plane. ScalePlane(src_v, src_stride_v, width, height, dst_v, dst_stride_v, halfwidth, halfheight, kFilterBilinear); @@ -152,8 +147,6 @@ int I444ToI420(const uint8* src_y, int src_stride_y, // 411 chroma is 1/4 width, 1x height // 420 chroma is 1/2 width, 1/2 height -// TODO(fbarchard): Change to kFilterBilinear; Test with valgrind. -// TODO(fbarchard): Share code for 444 and 422 to 420. LIBYUV_API int I411ToI420(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -183,16 +176,13 @@ int I411ToI420(const uint8* src_y, int src_stride_y, CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - int quarterwidth = (width + 3) >> 2; - - // Resample U plane. + // Resample UV planes. + const int halfwidth = (width + 1) >> 1; + const int halfheight = (height + 1) >> 1; + const int quarterwidth = (width + 3) >> 2; ScalePlane(src_u, src_stride_u, quarterwidth, height, dst_u, dst_stride_u, halfwidth, halfheight, kFilterNone); - - // Resample V plane. ScalePlane(src_v, src_stride_v, quarterwidth, height, dst_v, dst_stride_v, halfwidth, halfheight, kFilterNone); diff --git a/source/convert_from.cc b/source/convert_from.cc index 812c20d72..0507150a9 100644 --- a/source/convert_from.cc +++ b/source/convert_from.cc @@ -25,6 +25,8 @@ namespace libyuv { extern "C" { #endif +// 420 chroma is 1/2 width, 1/2 height +// 422 chroma is 1/2 width, 1x height LIBYUV_API int I420ToI422(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -48,69 +50,27 @@ int I420ToI422(const uint8* src_y, int src_stride_y, dst_stride_u = -dst_stride_u; dst_stride_v = -dst_stride_v; } - int halfwidth = (width + 1) >> 1; - void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; -#if defined(HAS_COPYROW_X86) - if (IS_ALIGNED(halfwidth, 4)) { - CopyRow = CopyRow_X86; - } -#endif -#if defined(HAS_COPYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(halfwidth, 32) && - IS_ALIGNED(src_u, 16) && IS_ALIGNED(src_stride_u, 16) && - IS_ALIGNED(src_v, 16) && IS_ALIGNED(src_stride_v, 16) && - IS_ALIGNED(dst_u, 16) && IS_ALIGNED(dst_stride_u, 16) && - IS_ALIGNED(dst_v, 16) && IS_ALIGNED(dst_stride_v, 16)) { - CopyRow = CopyRow_SSE2; - } -#endif -#if defined(HAS_COPYROW_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - CopyRow = CopyRow_ERMS; - } -#endif -#if defined(HAS_COPYROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(halfwidth, 32)) { - CopyRow = CopyRow_NEON; - } -#endif -#if defined(HAS_COPYROW_MIPS) - if (TestCpuFlag(kCpuHasMIPS)) { - CopyRow = CopyRow_MIPS; - } -#endif - // Copy Y plane + // Copy Y plane. + // TODO(fbarchard): Scale Y plane, which will do a copy, but allows mirror. if (dst_y) { CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } - // UpSample U plane. - int y; - for (y = 0; y < height - 1; y += 2) { - CopyRow(src_u, dst_u, halfwidth); - CopyRow(src_u, dst_u + dst_stride_u, halfwidth); - src_u += src_stride_u; - dst_u += dst_stride_u * 2; - } - if (height & 1) { - CopyRow(src_u, dst_u, halfwidth); - } - - // UpSample V plane. - for (y = 0; y < height - 1; y += 2) { - CopyRow(src_v, dst_v, halfwidth); - CopyRow(src_v, dst_v + dst_stride_v, halfwidth); - src_v += src_stride_v; - dst_v += dst_stride_v * 2; - } - if (height & 1) { - CopyRow(src_v, dst_v, halfwidth); - } + // Resample UV planes. + const int halfwidth = (width + 1) >> 1; + const int halfheight = (height + 1) >> 1; + ScalePlane(src_u, src_stride_u, halfwidth, halfheight, + dst_u, dst_stride_u, halfwidth, height, + kFilterBilinear); + ScalePlane(src_v, src_stride_v, halfwidth, halfheight, + dst_v, dst_stride_v, halfwidth, height, + kFilterBilinear); return 0; } -// TODO(fbarchard): Enable bilinear when fast enough or specialized upsampler. +// 420 chroma is 1/2 width, 1/2 height +// 444 chroma is 1x width, 1x height LIBYUV_API int I420ToI444(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -140,18 +100,15 @@ int I420ToI444(const uint8* src_y, int src_stride_y, CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - - // Upsample U plane from from 1/2 width, 1/2 height to 1x width, 1x height. + // Resample UV planes. + const int halfwidth = (width + 1) >> 1; + const int halfheight = (height + 1) >> 1; ScalePlane(src_u, src_stride_u, halfwidth, halfheight, dst_u, dst_stride_u, width, height, - kFilterNone); - - // Upsample V plane. + kFilterBilinear); ScalePlane(src_v, src_stride_v, halfwidth, halfheight, dst_v, dst_stride_v, width, height, - kFilterNone); + kFilterBilinear); return 0; } @@ -186,19 +143,16 @@ int I420ToI411(const uint8* src_y, int src_stride_y, CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); } - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - int quarterwidth = (width + 3) >> 2; - - // Resample U plane from 1/2 width, 1/2 height to 1/4 width, 1x height + // Resample UV planes. + const int halfwidth = (width + 1) >> 1; + const int halfheight = (height + 1) >> 1; + const int quarterwidth = (width + 3) >> 2; ScalePlane(src_u, src_stride_u, halfwidth, halfheight, dst_u, dst_stride_u, quarterwidth, height, - kFilterNone); - - // Resample V plane. + kFilterBilinear); ScalePlane(src_v, src_stride_v, halfwidth, halfheight, dst_v, dst_stride_v, quarterwidth, height, - kFilterNone); + kFilterBilinear); return 0; } diff --git a/source/scale.cc b/source/scale.cc index e4f069d6b..893002ba7 100644 --- a/source/scale.cc +++ b/source/scale.cc @@ -718,16 +718,29 @@ static void ScalePlaneSimple(int src_width, int src_height, int dst_width, int dst_height, int src_stride, int dst_stride, const uint8* src_ptr, uint8* dst_ptr) { - int dx = FixedDiv(Abs(src_width), dst_width); - int dy = FixedDiv(src_height, dst_height); - int x = dx >> 1; - int y = dy >> 1; + int dx = 0; + int dy = 0; + int x = 0; + int y = 0; + if (dst_width <= Abs(src_width)) { + dx = FixedDiv(Abs(src_width), dst_width); + x = (dx >> 1) - 32768; + } else if (dst_width > 1) { + dx = FixedDiv(Abs(src_width) - 1, dst_width - 1); + } // Negative src_width means horizontally mirror. if (src_width < 0) { x += (dst_width - 1) * dx; dx = -dx; src_width = -src_width; } + if (dst_height <= src_height) { + dy = FixedDiv(src_height, dst_height); + y = (dy >> 1) - 32768; + } else if (dst_height > 1) { + dy = FixedDiv(src_height - 1, dst_height - 1); + } + void (*ScaleCols)(uint8* dst_ptr, const uint8* src_ptr, int dst_width, int x, int dx) = ScaleCols_C; if (src_width * 2 == dst_width && x < 0x8000) {