mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
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
This commit is contained in:
parent
48e5364313
commit
a8e4dcb5d5
@ -1,6 +1,6 @@
|
||||
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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user