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

Use scaling for YUV to YUV.

BUG=none
TEST=I4*ToI4*
R=tpsiaki@google.com

Review URL: https://webrtc-codereview.appspot.com/4969004

git-svn-id: http://libyuv.googlecode.com/svn/trunk@892 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 48e53643
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 891
Version: 892
License: BSD
License File: LICENSE
......
......@@ -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
......@@ -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);
......
......@@ -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;
}
......
......@@ -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) {
......
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