mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-01-01 03:12:16 +08:00
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
This commit is contained in:
parent
48f5dd39b8
commit
8536b2f389
@ -1,6 +1,6 @@
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user