diff options
Diffstat (limited to 'files/source/planar_functions.cc')
-rw-r--r-- | files/source/planar_functions.cc | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/files/source/planar_functions.cc b/files/source/planar_functions.cc index b49bf0a0..9cab230f 100644 --- a/files/source/planar_functions.cc +++ b/files/source/planar_functions.cc @@ -440,7 +440,6 @@ void MergeUVPlane(const uint8_t* src_u, int y; void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_uv, int width) = MergeUVRow_C; - // Coalesce rows. // Negative height means invert the image. if (height < 0) { height = -height; @@ -504,6 +503,63 @@ void MergeUVPlane(const uint8_t* src_u, } } +// Convert NV21 to NV12. +LIBYUV_API +int NV21ToNV12(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_uv, + int dst_stride_uv, + int width, + int height) { + int y; + void (*UVToVURow)(const uint8_t* src_uv, uint8_t* dst_vu, int width) = + UVToVURow_C; + + int halfwidth = (width + 1) >> 1; + int halfheight = (height + 1) >> 1; + if (!src_vu || !dst_uv || 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_vu = src_vu + (halfheight - 1) * src_stride_vu; + src_stride_y = -src_stride_y; + src_stride_vu = -src_stride_vu; + } + // Coalesce rows. + if (src_stride_vu == halfwidth * 2 && dst_stride_uv == halfwidth * 2) { + halfwidth *= halfheight; + halfheight = 1; + src_stride_vu = dst_stride_uv = 0; + } + +#if defined(HAS_UVToVUROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + UVToVURow = UVToVURow_Any_NEON; + if (IS_ALIGNED(halfwidth, 16)) { + UVToVURow = UVToVURow_NEON; + } + } +#endif + if (dst_y) { + CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + } + + for (y = 0; y < halfheight; ++y) { + UVToVURow(src_vu, dst_uv, halfwidth); + src_vu += src_stride_vu; + dst_uv += dst_stride_uv; + } + return 0; +} + // Support function for NV12 etc RGB channels. // Width and height are plane sizes (typically half pixel width). LIBYUV_API |