Commit 8536b2f3 authored by fbarchard@google.com's avatar fbarchard@google.com

Add 411 for MJPG and fix neon warnings

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

git-svn-id: http://libyuv.googlecode.com/svn/trunk@180 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 48f5dd39
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 179
Version: 180
License: BSD
License File: LICENSE
......
......@@ -49,6 +49,15 @@ int I444ToI420(const uint8* src_y, int src_stride_y,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert I411 to I420.
int I411ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
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);
// Convert I400 (grey) to I420.
int I400ToI420(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
......
......@@ -39,6 +39,14 @@ int I420ToI444(const uint8* src_y, int src_stride_y,
uint8* dst_v, int dst_stride_v,
int width, int height);
int I420ToI411(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
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);
// Copy to I400. Source can be I420,422,444,400,NV12,NV21
int I400Copy(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
......
......@@ -11,7 +11,7 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 179
#define LIBYUV_VERSION 180
#endif // INCLUDE_LIBYUV_VERSION_H_
......@@ -42,6 +42,7 @@ enum FourCC {
FOURCC_I420 = FOURCC('I', '4', '2', '0'),
FOURCC_I422 = FOURCC('I', '4', '2', '2'),
FOURCC_I444 = FOURCC('I', '4', '4', '4'),
FOURCC_I411 = FOURCC('I', '4', '1', '1'),
FOURCC_I400 = FOURCC('I', '4', '0', '0'),
FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'),
FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'),
......
......@@ -258,6 +258,57 @@ int I444ToI420(const uint8* src_y, int src_stride_y,
return 0;
}
// use Bilinear for upsampling chroma
void ScalePlaneBilinear(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);
// 411 chroma is 1/4 width, 1x height
// 420 chroma is 1/2 width, 1/2 height
int I411ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
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) {
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_y = dst_y + (height - 1) * dst_stride_y;
dst_u = dst_u + (height - 1) * dst_stride_u;
dst_v = dst_v + (height - 1) * dst_stride_v;
dst_stride_y = -dst_stride_y;
dst_stride_u = -dst_stride_u;
dst_stride_v = -dst_stride_v;
}
// Copy Y plane
if (dst_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.
ScalePlaneBilinear(quarterwidth, height, // from 1/4 width, 1x height
halfwidth, halfheight, // to 1/2 width, 1/2 height
src_stride_u,
dst_stride_u,
src_u, dst_u);
// Resample V plane.
ScalePlaneBilinear(quarterwidth, height, // from 1/4 width, 1x height
halfwidth, halfheight, // to 1/2 width, 1/2 height
src_stride_v,
dst_stride_v,
src_v, dst_v);
return 0;
}
// I400 is greyscale typically used in MJPG
int I400ToI420(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
......@@ -1607,6 +1658,23 @@ int ConvertToI420(const uint8* sample, size_t sample_size,
dst_width, inv_dst_height);
break;
}
case FOURCC_I411: {
int quarterwidth = (src_width + 3) / 4;
const uint8* src_y = sample + src_width * crop_y + crop_x;
const uint8* src_u = sample + src_width * abs_src_height +
quarterwidth * crop_y + crop_x / 4;
const uint8* src_v = sample + src_width * abs_src_height +
quarterwidth * (abs_src_height + crop_y) + crop_x / 4;
I411ToI420(src_y, src_width,
src_u, quarterwidth,
src_v, quarterwidth,
y, y_stride,
u, u_stride,
v, v_stride,
dst_width, inv_dst_height);
break;
}
// Formats not supported
case FOURCC_MJPG:
default:
......
......@@ -140,6 +140,51 @@ int I420ToI444(const uint8* src_y, int src_stride_y,
return 0;
}
// 420 chroma is 1/2 width, 1/2 height
// 411 chroma is 1/4 width, 1x height
int I420ToI411(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
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) {
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_y = dst_y + (height - 1) * dst_stride_y;
dst_u = dst_u + (height - 1) * dst_stride_u;
dst_v = dst_v + (height - 1) * dst_stride_v;
dst_stride_y = -dst_stride_y;
dst_stride_u = -dst_stride_u;
dst_stride_v = -dst_stride_v;
}
// Copy Y plane
if (dst_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.
ScalePlaneBilinear(halfwidth, halfheight, // from 1/2 width, 1/2 height
quarterwidth, height, // to 1/4 width, 1x height
src_stride_u,
dst_stride_u,
src_u, dst_u);
// Resample V plane.
ScalePlaneBilinear(halfwidth, halfheight, // from 1/2 width, 1/2 height
quarterwidth, height, // to 1/4 width, 1x height
src_stride_v,
dst_stride_v,
src_v, dst_v);
return 0;
}
// Copy to I400. Source can be I420,422,444,400,NV12,NV21
int I400Copy(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
......@@ -1231,6 +1276,19 @@ int ConvertFromI420(const uint8* y, int y_stride,
width, height);
break;
}
case FOURCC_I411: {
int quarterwidth = (width + 3) / 4;
uint8* dst_u = dst_sample + width * height;
uint8* dst_v = dst_u + quarterwidth * height;
I420ToI411(y, y_stride,
u, u_stride,
v, v_stride,
dst_sample, width,
dst_u, quarterwidth,
dst_v, quarterwidth,
width, height);
break;
}
// Formats not supported - MJPG, biplanar, some rgb formats.
default:
......
......@@ -107,7 +107,7 @@ void MirrorRow_NEON(const uint8* src, uint8* dst, int width) {
);
}
static const uint8 vtbl_4x4_transpose[16] __attribute__((vector_size(16))) =
static const uvec8 vtbl_4x4_transpose =
{ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 };
void TransposeWx8_NEON(const uint8* src, int src_stride,
......@@ -346,7 +346,7 @@ void MirrorRowUV_NEON(const uint8* src,
);
}
static const uint8 vtbl_4x4_transpose_di[16] __attribute__((vector_size(16))) =
static const uvec8 vtbl_4x4_transpose_di =
{ 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 };
void TransposeUVWx8_NEON(const uint8* src, int src_stride,
......
......@@ -61,8 +61,10 @@ extern "C" {
#if defined(HAS_I420TOARGBROW_NEON) || \
defined(HAS_I420TOBGRAROW_NEON) || \
defined(HAS_I420TOABGRROW_NEON)
static const vec8 kUVToRB[8] = { 127, 127, 127, 127, 102, 102, 102, 102 };
static const vec8 kUVToG[8] = { -25, -25, -25, -25, -52, -52, -52, -52 };
static const vec8 kUVToRB = { 127, 127, 127, 127, 102, 102, 102, 102,
0, 0, 0, 0, 0, 0, 0, 0 };
static const vec8 kUVToG = { -25, -25, -25, -25, -52, -52, -52, -52,
0, 0, 0, 0, 0, 0, 0, 0 };
#endif
#if defined(HAS_I420TOARGBROW_NEON)
......@@ -84,13 +86,13 @@ YUVTORGB
"vst4.u8 {d20, d21, d22, d23}, [%3]! \n"
"subs %4, %4, #8 \n"
"bhi 1b \n"
: "+r"(y_buf), // %0
"+r"(u_buf), // %1
"+r"(v_buf), // %2
"+r"(rgb_buf), // %3
"+r"(width) // %4
: "r"(kUVToRB),
"r"(kUVToG)
: "+r"(y_buf), // %0
"+r"(u_buf), // %1
"+r"(v_buf), // %2
"+r"(rgb_buf), // %3
"+r"(width) // %4
: "r"(kUVToRB), // %5
"r"(kUVToG) // %6
: "cc", "memory", "q0", "q1", "q2", "q3", "q8", "q9",
"q10", "q11", "q12", "q13", "q14", "q15"
);
......@@ -117,13 +119,13 @@ YUVTORGB
"vst4.u8 {d19, d20, d21, d22}, [%3]! \n"
"subs %4, %4, #8 \n"
"bhi 1b \n"
: "+r"(y_buf), // %0
"+r"(u_buf), // %1
"+r"(v_buf), // %2
"+r"(rgb_buf), // %3
"+r"(width) // %4
: "r"(kUVToRB),
"r"(kUVToG)
: "+r"(y_buf), // %0
"+r"(u_buf), // %1
"+r"(v_buf), // %2
"+r"(rgb_buf), // %3
"+r"(width) // %4
: "r"(kUVToRB), // %5
"r"(kUVToG) // %6
: "cc", "memory", "q0", "q1", "q2", "q3", "q8", "q9",
"q10", "q11", "q12", "q13", "q14", "q15"
);
......@@ -150,13 +152,13 @@ YUVTORGB
"vst4.u8 {d20, d21, d22, d23}, [%3]! \n"
"subs %4, %4, #8 \n"
"bhi 1b \n"
: "+r"(y_buf), // %0
"+r"(u_buf), // %1
"+r"(v_buf), // %2
"+r"(rgb_buf), // %3
"+r"(width) // %4
: "r"(kUVToRB),
"r"(kUVToG)
: "+r"(y_buf), // %0
"+r"(u_buf), // %1
"+r"(v_buf), // %2
"+r"(rgb_buf), // %3
"+r"(width) // %4
: "r"(kUVToRB), // %5
"r"(kUVToG) // %6
: "cc", "memory", "q0", "q1", "q2", "q3", "q8", "q9",
"q10", "q11", "q12", "q13", "q14", "q15"
);
......@@ -174,10 +176,10 @@ void SplitUV_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) {
"vst1.u8 {q0}, [%1]! \n" // store U
"vst1.u8 {q1}, [%2]! \n" // Store V
"bhi 1b \n"
: "+r"(src_uv),
"+r"(dst_u),
"+r"(dst_v),
"+r"(pix) // Output registers
: "+r"(src_uv), // %0
"+r"(dst_u), // %1
"+r"(dst_v), // %2
"+r"(pix) // %3 // Output registers
: // Input registers
: "memory", "cc", "q0", "q1" // Clobber List
);
......@@ -195,10 +197,10 @@ void CopyRow_NEON(const uint8* src, uint8* dst, int count) {
"subs %2, %2, #64 \n" // 64 processed per loop
"vst1.u8 {q0,q1,q2,q3}, [%1]! \n" // store 64
"bhi 1b \n"
: "+r"(src),
"+r"(dst),
"+r"(count) // Output registers
: // Input registers
: "+r"(src), // %0
"+r"(dst), // %1
"+r"(count) // %2 // Output registers
: // Input registers
: "memory", "cc", "q0", "q1", "q2", "q3" // Clobber List
);
}
......
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