Index: source/convert_from.cc |
diff --git a/source/convert_from.cc b/source/convert_from.cc |
index 2341dca95e41de4b4d39d96ff6056fbd1784f6d0..662b809f5e894750192aca77285be0be98719330 100644 |
--- a/source/convert_from.cc |
+++ b/source/convert_from.cc |
@@ -368,72 +368,46 @@ int I420ToNV12(const uint8* src_y, int src_stride_y, |
uint8* dst_y, int dst_stride_y, |
uint8* dst_uv, int dst_stride_uv, |
int width, int height) { |
- int y; |
- void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv, |
- int width) = MergeUVRow_C; |
- // Coalesce rows. |
- int halfwidth = (width + 1) >> 1; |
- int halfheight = (height + 1) >> 1; |
- if (!src_u || !src_v || !dst_uv || |
+ if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || |
width <= 0 || height == 0) { |
return -1; |
} |
+ int halfwidth = (width + 1) / 2; |
+ int halfheight = height > 0 ? (height + 1) / 2 : (height - 1) / 2; |
+ CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); |
+ return MergeUVPlanes(src_u, src_stride_u, |
+ src_v, src_stride_v, |
+ dst_uv, dst_stride_uv, |
+ halfwidth, halfheight); |
+} |
+ |
+LIBYUV_API |
+int MergeUVPlanes(const uint8* src_u, int src_stride_u, |
+ const uint8* src_v, int src_stride_v, |
+ uint8* dst_uv, int dst_stride_uv, |
+ int width, int height) { |
+ if (!src_u || !src_v || !dst_uv || width <= 0 || height == 0) { |
+ return -1; |
+ } |
// Negative height means invert the image. |
if (height < 0) { |
height = -height; |
- halfheight = (height + 1) >> 1; |
- if (dst_y) { |
- dst_y = dst_y + (height - 1) * dst_stride_y; |
- } |
- dst_uv = dst_uv + (halfheight - 1) * dst_stride_uv; |
- dst_stride_y = -dst_stride_y; |
+ dst_uv = dst_uv + (height - 1) * dst_stride_uv; |
dst_stride_uv = -dst_stride_uv; |
} |
- if (src_stride_y == width && |
- dst_stride_y == width) { |
+ // Coalesce rows. |
+ if (src_stride_u == width && |
+ src_stride_v == width && |
+ dst_stride_uv == width * 2) { |
width *= height; |
height = 1; |
- src_stride_y = dst_stride_y = 0; |
- } |
- // Coalesce rows. |
- if (src_stride_u == halfwidth && |
- src_stride_v == halfwidth && |
- dst_stride_uv == halfwidth * 2) { |
- halfwidth *= halfheight; |
- halfheight = 1; |
src_stride_u = src_stride_v = dst_stride_uv = 0; |
} |
-#if defined(HAS_MERGEUVROW_SSE2) |
- if (TestCpuFlag(kCpuHasSSE2)) { |
- MergeUVRow_ = MergeUVRow_Any_SSE2; |
- if (IS_ALIGNED(halfwidth, 16)) { |
- MergeUVRow_ = MergeUVRow_SSE2; |
- } |
- } |
-#endif |
-#if defined(HAS_MERGEUVROW_AVX2) |
- if (TestCpuFlag(kCpuHasAVX2)) { |
- MergeUVRow_ = MergeUVRow_Any_AVX2; |
- if (IS_ALIGNED(halfwidth, 32)) { |
- MergeUVRow_ = MergeUVRow_AVX2; |
- } |
- } |
-#endif |
-#if defined(HAS_MERGEUVROW_NEON) |
- if (TestCpuFlag(kCpuHasNEON)) { |
- MergeUVRow_ = MergeUVRow_Any_NEON; |
- if (IS_ALIGNED(halfwidth, 16)) { |
- MergeUVRow_ = MergeUVRow_NEON; |
- } |
- } |
-#endif |
+ MergeUVRowFunction MergeUVRow_ = GetOptimizedMergeUVRowFunction(width); |
- if (dst_y) { |
- CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); |
- } |
- for (y = 0; y < halfheight; ++y) { |
+ for (int y = 0; y < height; ++y) { |
// Merge a row of U and V into a row of UV. |
- MergeUVRow_(src_u, src_v, dst_uv, halfwidth); |
+ MergeUVRow_(src_u, src_v, dst_uv, width); |
src_u += src_stride_u; |
src_v += src_stride_v; |
dst_uv += dst_stride_uv; |