/* * Copyright 2011 The LibYuv Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
#include"libyuv/convert.h"
#include"libyuv/basic_types.h" #include"libyuv/cpu_id.h" #include"libyuv/planar_functions.h" #include"libyuv/rotate.h" #include"libyuv/row.h" #include"libyuv/scale.h"// For ScalePlane() #include"libyuv/scale_row.h"// For FixedDiv #include"libyuv/scale_uv.h"// For UVScale()
// Subsample amount uses a shift. // v is value // a is amount to add to round up // s is shift to subsample down #define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) static __inlineint Abs(int v) { return v >= 0 ? v : -v;
}
// Any I4xx To I420 format staticint I4xxToI420(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u, const uint8_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int src_y_width, int src_y_height, int src_uv_width, int src_uv_height) { constint dst_y_width = src_y_width; constint dst_y_height = Abs(src_y_height); constint dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); constint dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); int r; if ((!src_y && dst_y) || !src_u || !src_v || !dst_u || !dst_v ||
src_y_width <= 0 || src_y_height == 0 || src_uv_width <= 0 ||
src_uv_height == 0) { return -1;
} if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, src_y_width,
src_y_height);
}
r = ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u,
dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); if (r != 0) { return r;
}
r = ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v,
dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); return r;
}
// Copy I420 with optional vertical flipping using negative height.
LIBYUV_API int I420Copy(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u, const uint8_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { int halfwidth = (width + 1) >> 1; int halfheight = (height + 1) >> 1; if ((!src_y && dst_y) || !src_u || !src_v || !dst_u || !dst_v || width <= 0 ||
height == 0) { return -1;
} // Negative height means invert the image. if (height < 0) {
height = -height;
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;
src_stride_y = -src_stride_y;
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
staticint I41xToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height, int depth) { constint scale = 1 << (24 - depth);
staticint I21xToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height, int depth) { constint scale = 1 << (24 - depth);
// Convert 10 bit YUV to 8 bit.
LIBYUV_API int I010ToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return Planar16bitTo8bit(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u,
dst_stride_u, dst_v, dst_stride_v, width, height, 1,
1, 10);
}
LIBYUV_API int I210ToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return I21xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 10);
}
LIBYUV_API int I210ToI422(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return Planar16bitTo8bit(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u,
dst_stride_u, dst_v, dst_stride_v, width, height, 1,
0, 10);
}
LIBYUV_API int I410ToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return I41xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 10);
}
LIBYUV_API int I410ToI444(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return Planar16bitTo8bit(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u,
dst_stride_u, dst_v, dst_stride_v, width, height, 0,
0, 10);
}
LIBYUV_API int I012ToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return Planar16bitTo8bit(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u,
dst_stride_u, dst_v, dst_stride_v, width, height, 1,
1, 12);
}
LIBYUV_API int I212ToI422(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return Planar16bitTo8bit(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u,
dst_stride_u, dst_v, dst_stride_v, width, height, 1,
0, 12);
}
LIBYUV_API int I212ToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return I21xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 12);
}
LIBYUV_API int I412ToI444(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return Planar16bitTo8bit(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u,
dst_stride_u, dst_v, dst_stride_v, width, height, 0,
0, 12);
}
LIBYUV_API int I412ToI420(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return I41xToI420(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 12);
}
// Any Ix10 To I010 format staticint Ix10ToI010(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint16_t* dst_y, int dst_stride_y,
uint16_t* dst_u, int dst_stride_u,
uint16_t* dst_v, int dst_stride_v, int width, int height, int subsample_x, int subsample_y) { constint dst_y_width = width; constint dst_y_height = Abs(height); constint src_uv_width = SUBSAMPLE(width, subsample_x, subsample_x); constint src_uv_height = SUBSAMPLE(height, subsample_y, subsample_y); constint dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); constint dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); int r; if ((!src_y && dst_y) || !src_u || !src_v || !dst_u || !dst_v || width <= 0 ||
height == 0) { return -1;
} if (dst_y) {
CopyPlane_16(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
r = ScalePlane_12(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u,
dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); if (r != 0) { return r;
}
r = ScalePlane_12(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v,
dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); return r;
}
LIBYUV_API int I410ToI010(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint16_t* dst_y, int dst_stride_y,
uint16_t* dst_u, int dst_stride_u,
uint16_t* dst_v, int dst_stride_v, int width, int height) { return Ix10ToI010(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 0, 0);
}
LIBYUV_API int I210ToI010(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint16_t* dst_y, int dst_stride_y,
uint16_t* dst_u, int dst_stride_u,
uint16_t* dst_v, int dst_stride_v, int width, int height) { return Ix10ToI010(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
dst_v, dst_stride_v, width, height, 1, 0);
}
// Any I[420]1[02] to P[420]1[02] format staticint IxxxToPxxx(const uint16_t* src_y, int src_stride_y, const uint16_t* src_u, int src_stride_u, const uint16_t* src_v, int src_stride_v,
uint16_t* dst_y, int dst_stride_y,
uint16_t* dst_uv, int dst_stride_uv, int width, int height, int subsample_x, int subsample_y, int depth) { constint uv_width = SUBSAMPLE(width, subsample_x, subsample_x); constint uv_height = SUBSAMPLE(height, subsample_y, subsample_y); if (width <= 0 || height == 0) { return -1;
}
LIBYUV_API int MM21ToNV12(const uint8_t* src_y, int src_stride_y, const uint8_t* src_uv, int src_stride_uv,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_uv, int dst_stride_uv, int width, int height) { if (!src_uv || !dst_uv || width <= 0) { return -1;
}
LIBYUV_API int MM21ToI420(const uint8_t* src_y, int src_stride_y, const uint8_t* src_uv, int src_stride_uv,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { int sign = height < 0 ? -1 : 1;
LIBYUV_API int MM21ToYUY2(const uint8_t* src_y, int src_stride_y, const uint8_t* src_uv, int src_stride_uv,
uint8_t* dst_yuy2, int dst_stride_yuy2, int width, int height) { if (!src_y || !src_uv || !dst_yuy2 || width <= 0) { return -1;
}
// Convert MT2T into P010. See tinyurl.com/mtk-10bit-video-format for format // documentation. // TODO(greenjustin): Add an MT2T to I420 conversion.
LIBYUV_API int MT2TToP010(const uint8_t* src_y, int src_stride_y, const uint8_t* src_uv, int src_stride_uv,
uint16_t* dst_y, int dst_stride_y,
uint16_t* dst_uv, int dst_stride_uv, int width, int height) { if (width <= 0 || !height || !src_uv || !dst_uv) { return -1;
}
// Convert NV21 to I420. Same as NV12 but u and v pointers swapped.
LIBYUV_API int NV21ToI420(const uint8_t* src_y, int src_stride_y, const uint8_t* src_vu, int src_stride_vu,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_u, int dst_stride_u,
uint8_t* dst_v, int dst_stride_v, int width, int height) { return NV12ToI420(src_y, src_stride_y, src_vu, src_stride_vu, dst_y,
dst_stride_y, dst_v, dst_stride_v, dst_u, dst_stride_u,
width, height);
}
LIBYUV_API int NV12ToNV24(const uint8_t* src_y, int src_stride_y, const uint8_t* src_uv, int src_stride_uv,
uint8_t* dst_y, int dst_stride_y,
uint8_t* dst_uv, int dst_stride_uv, int width, int height) { int r; if ((!src_y && dst_y) || !src_uv || !dst_uv || width <= 0 || height == 0) { return -1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.