Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: source/libvpx/third_party/libyuv/source/planar_functions.cc

Issue 1302353004: libvpx: Pull from upstream (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libvpx.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2011 The LibYuv Project Authors. All rights reserved. 2 * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 521
522 // Mirror plane 522 // Mirror plane
523 for (y = 0; y < height; ++y) { 523 for (y = 0; y < height; ++y) {
524 ARGBMirrorRow(src_argb, dst_argb, width); 524 ARGBMirrorRow(src_argb, dst_argb, width);
525 src_argb += src_stride_argb; 525 src_argb += src_stride_argb;
526 dst_argb += dst_stride_argb; 526 dst_argb += dst_stride_argb;
527 } 527 }
528 return 0; 528 return 0;
529 } 529 }
530 530
531 // Get a blender that optimized for the CPU, alignment and pixel count. 531 // Get a blender that optimized for the CPU and pixel count.
532 // As there are 6 blenders to choose from, the caller should try to use 532 // As there are 6 blenders to choose from, the caller should try to use
533 // the same blend function for all pixels if possible. 533 // the same blend function for all pixels if possible.
534 LIBYUV_API 534 LIBYUV_API
535 ARGBBlendRow GetARGBBlend() { 535 ARGBBlendRow GetARGBBlend() {
536 void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1, 536 void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1,
537 uint8* dst_argb, int width) = ARGBBlendRow_C; 537 uint8* dst_argb, int width) = ARGBBlendRow_C;
538 #if defined(HAS_ARGBBLENDROW_SSSE3) 538 #if defined(HAS_ARGBBLENDROW_SSSE3)
539 if (TestCpuFlag(kCpuHasSSSE3)) { 539 if (TestCpuFlag(kCpuHasSSSE3)) {
540 ARGBBlendRow = ARGBBlendRow_SSSE3; 540 ARGBBlendRow = ARGBBlendRow_SSSE3;
541 return ARGBBlendRow; 541 return ARGBBlendRow;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 dst_stride_argb = -dst_stride_argb; 670 dst_stride_argb = -dst_stride_argb;
671 } 671 }
672 // Coalesce rows. 672 // Coalesce rows.
673 if (src_stride_argb0 == width * 4 && 673 if (src_stride_argb0 == width * 4 &&
674 src_stride_argb1 == width * 4 && 674 src_stride_argb1 == width * 4 &&
675 dst_stride_argb == width * 4) { 675 dst_stride_argb == width * 4) {
676 width *= height; 676 width *= height;
677 height = 1; 677 height = 1;
678 src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 678 src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0;
679 } 679 }
680 #if defined(HAS_ARGBADDROW_SSE2) && defined(_MSC_VER) 680 #if defined(HAS_ARGBADDROW_SSE2) && (defined(_MSC_VER) && !defined(__clang__))
681 if (TestCpuFlag(kCpuHasSSE2)) { 681 if (TestCpuFlag(kCpuHasSSE2)) {
682 ARGBAddRow = ARGBAddRow_SSE2; 682 ARGBAddRow = ARGBAddRow_SSE2;
683 } 683 }
684 #endif 684 #endif
685 #if defined(HAS_ARGBADDROW_SSE2) && !defined(_MSC_VER) 685 #if defined(HAS_ARGBADDROW_SSE2) && !(defined(_MSC_VER) && !defined(__clang__))
686 if (TestCpuFlag(kCpuHasSSE2)) { 686 if (TestCpuFlag(kCpuHasSSE2)) {
687 ARGBAddRow = ARGBAddRow_Any_SSE2; 687 ARGBAddRow = ARGBAddRow_Any_SSE2;
688 if (IS_ALIGNED(width, 4)) { 688 if (IS_ALIGNED(width, 4)) {
689 ARGBAddRow = ARGBAddRow_SSE2; 689 ARGBAddRow = ARGBAddRow_SSE2;
690 } 690 }
691 } 691 }
692 #endif 692 #endif
693 #if defined(HAS_ARGBADDROW_AVX2) 693 #if defined(HAS_ARGBADDROW_AVX2)
694 if (TestCpuFlag(kCpuHasAVX2)) { 694 if (TestCpuFlag(kCpuHasAVX2)) {
695 ARGBAddRow = ARGBAddRow_Any_AVX2; 695 ARGBAddRow = ARGBAddRow_Any_AVX2;
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 } 1969 }
1970 1970
1971 // Sobel ARGB effect. 1971 // Sobel ARGB effect.
1972 static int ARGBSobelize(const uint8* src_argb, int src_stride_argb, 1972 static int ARGBSobelize(const uint8* src_argb, int src_stride_argb,
1973 uint8* dst_argb, int dst_stride_argb, 1973 uint8* dst_argb, int dst_stride_argb,
1974 int width, int height, 1974 int width, int height,
1975 void (*SobelRow)(const uint8* src_sobelx, 1975 void (*SobelRow)(const uint8* src_sobelx,
1976 const uint8* src_sobely, 1976 const uint8* src_sobely,
1977 uint8* dst, int width)) { 1977 uint8* dst, int width)) {
1978 int y; 1978 int y;
1979 void (*ARGBToBayerRow)(const uint8* src_argb, uint8* dst_bayer, 1979 void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_g, int pix) =
1980 uint32 selector, int pix) = ARGBToBayerGGRow_C; 1980 ARGBToYJRow_C;
1981 void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1, 1981 void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1,
1982 uint8* dst_sobely, int width) = SobelYRow_C; 1982 uint8* dst_sobely, int width) = SobelYRow_C;
1983 void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1, 1983 void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1,
1984 const uint8* src_y2, uint8* dst_sobely, int width) = 1984 const uint8* src_y2, uint8* dst_sobely, int width) =
1985 SobelXRow_C; 1985 SobelXRow_C;
1986 const int kEdge = 16; // Extra pixels at start of row for extrude/align. 1986 const int kEdge = 16; // Extra pixels at start of row for extrude/align.
1987 if (!src_argb || !dst_argb || width <= 0 || height == 0) { 1987 if (!src_argb || !dst_argb || width <= 0 || height == 0) {
1988 return -1; 1988 return -1;
1989 } 1989 }
1990 // Negative height means invert the image. 1990 // Negative height means invert the image.
1991 if (height < 0) { 1991 if (height < 0) {
1992 height = -height; 1992 height = -height;
1993 src_argb = src_argb + (height - 1) * src_stride_argb; 1993 src_argb = src_argb + (height - 1) * src_stride_argb;
1994 src_stride_argb = -src_stride_argb; 1994 src_stride_argb = -src_stride_argb;
1995 } 1995 }
1996 // ARGBToBayer used to select G channel from ARGB. 1996
1997 #if defined(HAS_ARGBTOBAYERGGROW_SSE2) 1997 #if defined(HAS_ARGBTOYJROW_SSSE3)
1998 if (TestCpuFlag(kCpuHasSSE2)) { 1998 if (TestCpuFlag(kCpuHasSSSE3)) {
1999 ARGBToBayerRow = ARGBToBayerGGRow_Any_SSE2; 1999 ARGBToYJRow = ARGBToYJRow_Any_SSSE3;
2000 if (IS_ALIGNED(width, 8)) { 2000 if (IS_ALIGNED(width, 16)) {
2001 ARGBToBayerRow = ARGBToBayerGGRow_SSE2; 2001 ARGBToYJRow = ARGBToYJRow_SSSE3;
2002 } 2002 }
2003 } 2003 }
2004 #endif 2004 #endif
2005 #if defined(HAS_ARGBTOBAYERROW_SSSE3) 2005 #if defined(HAS_ARGBTOYJROW_AVX2)
2006 if (TestCpuFlag(kCpuHasSSSE3)) { 2006 if (TestCpuFlag(kCpuHasAVX2)) {
2007 ARGBToBayerRow = ARGBToBayerRow_Any_SSSE3; 2007 ARGBToYJRow = ARGBToYJRow_Any_AVX2;
2008 if (IS_ALIGNED(width, 8)) { 2008 if (IS_ALIGNED(width, 32)) {
2009 ARGBToBayerRow = ARGBToBayerRow_SSSE3; 2009 ARGBToYJRow = ARGBToYJRow_AVX2;
2010 } 2010 }
2011 } 2011 }
2012 #endif 2012 #endif
2013 #if defined(HAS_ARGBTOBAYERGGROW_NEON) 2013 #if defined(HAS_ARGBTOYJROW_NEON)
2014 if (TestCpuFlag(kCpuHasNEON)) { 2014 if (TestCpuFlag(kCpuHasNEON)) {
2015 ARGBToBayerRow = ARGBToBayerGGRow_Any_NEON; 2015 ARGBToYJRow = ARGBToYJRow_Any_NEON;
2016 if (IS_ALIGNED(width, 8)) { 2016 if (IS_ALIGNED(width, 8)) {
2017 ARGBToBayerRow = ARGBToBayerGGRow_NEON; 2017 ARGBToYJRow = ARGBToYJRow_NEON;
2018 } 2018 }
2019 } 2019 }
2020 #endif 2020 #endif
2021
2021 #if defined(HAS_SOBELYROW_SSE2) 2022 #if defined(HAS_SOBELYROW_SSE2)
2022 if (TestCpuFlag(kCpuHasSSE2)) { 2023 if (TestCpuFlag(kCpuHasSSE2)) {
2023 SobelYRow = SobelYRow_SSE2; 2024 SobelYRow = SobelYRow_SSE2;
2024 } 2025 }
2025 #endif 2026 #endif
2026 #if defined(HAS_SOBELYROW_NEON) 2027 #if defined(HAS_SOBELYROW_NEON)
2027 if (TestCpuFlag(kCpuHasNEON)) { 2028 if (TestCpuFlag(kCpuHasNEON)) {
2028 SobelYRow = SobelYRow_NEON; 2029 SobelYRow = SobelYRow_NEON;
2029 } 2030 }
2030 #endif 2031 #endif
2031 #if defined(HAS_SOBELXROW_SSE2) 2032 #if defined(HAS_SOBELXROW_SSE2)
2032 if (TestCpuFlag(kCpuHasSSE2)) { 2033 if (TestCpuFlag(kCpuHasSSE2)) {
2033 SobelXRow = SobelXRow_SSE2; 2034 SobelXRow = SobelXRow_SSE2;
2034 } 2035 }
2035 #endif 2036 #endif
2036 #if defined(HAS_SOBELXROW_NEON) 2037 #if defined(HAS_SOBELXROW_NEON)
2037 if (TestCpuFlag(kCpuHasNEON)) { 2038 if (TestCpuFlag(kCpuHasNEON)) {
2038 SobelXRow = SobelXRow_NEON; 2039 SobelXRow = SobelXRow_NEON;
2039 } 2040 }
2040 #endif 2041 #endif
2041 { 2042 {
2042 // 3 rows with edges before/after. 2043 // 3 rows with edges before/after.
2043 const int kRowSize = (width + kEdge + 15) & ~15; 2044 const int kRowSize = (width + kEdge + 31) & ~31;
2044 align_buffer_64(rows, kRowSize * 2 + (kEdge + kRowSize * 3 + kEdge)); 2045 align_buffer_64(rows, kRowSize * 2 + (kEdge + kRowSize * 3 + kEdge));
2045 uint8* row_sobelx = rows; 2046 uint8* row_sobelx = rows;
2046 uint8* row_sobely = rows + kRowSize; 2047 uint8* row_sobely = rows + kRowSize;
2047 uint8* row_y = rows + kRowSize * 2; 2048 uint8* row_y = rows + kRowSize * 2;
2048 2049
2049 // Convert first row. 2050 // Convert first row.
2050 uint8* row_y0 = row_y + kEdge; 2051 uint8* row_y0 = row_y + kEdge;
2051 uint8* row_y1 = row_y0 + kRowSize; 2052 uint8* row_y1 = row_y0 + kRowSize;
2052 uint8* row_y2 = row_y1 + kRowSize; 2053 uint8* row_y2 = row_y1 + kRowSize;
2053 ARGBToBayerRow(src_argb, row_y0, 0x0d090501, width); 2054 ARGBToYJRow(src_argb, row_y0, width);
2054 row_y0[-1] = row_y0[0]; 2055 row_y0[-1] = row_y0[0];
2055 memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind. 2056 memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind.
2056 ARGBToBayerRow(src_argb, row_y1, 0x0d090501, width); 2057 ARGBToYJRow(src_argb, row_y1, width);
2057 row_y1[-1] = row_y1[0]; 2058 row_y1[-1] = row_y1[0];
2058 memset(row_y1 + width, row_y1[width - 1], 16); 2059 memset(row_y1 + width, row_y1[width - 1], 16);
2059 memset(row_y2 + width, 0, 16); 2060 memset(row_y2 + width, 0, 16);
2060 2061
2061 for (y = 0; y < height; ++y) { 2062 for (y = 0; y < height; ++y) {
2062 // Convert next row of ARGB to Y. 2063 // Convert next row of ARGB to G.
2063 if (y < (height - 1)) { 2064 if (y < (height - 1)) {
2064 src_argb += src_stride_argb; 2065 src_argb += src_stride_argb;
2065 } 2066 }
2066 ARGBToBayerRow(src_argb, row_y2, 0x0d090501, width); 2067 ARGBToYJRow(src_argb, row_y2, width);
2067 row_y2[-1] = row_y2[0]; 2068 row_y2[-1] = row_y2[0];
2068 row_y2[width] = row_y2[width - 1]; 2069 row_y2[width] = row_y2[width - 1];
2069 2070
2070 SobelXRow(row_y0 - 1, row_y1 - 1, row_y2 - 1, row_sobelx, width); 2071 SobelXRow(row_y0 - 1, row_y1 - 1, row_y2 - 1, row_sobelx, width);
2071 SobelYRow(row_y0 - 1, row_y2 - 1, row_sobely, width); 2072 SobelYRow(row_y0 - 1, row_y2 - 1, row_sobely, width);
2072 SobelRow(row_sobelx, row_sobely, dst_argb, width); 2073 SobelRow(row_sobelx, row_sobely, dst_argb, width);
2073 2074
2074 // Cycle thru circular queue of 3 row_y buffers. 2075 // Cycle thru circular queue of 3 row_y buffers.
2075 { 2076 {
2076 uint8* row_yt = row_y0; 2077 uint8* row_yt = row_y0;
(...skipping 10 matching lines...) Expand all
2087 } 2088 }
2088 2089
2089 // Sobel ARGB effect. 2090 // Sobel ARGB effect.
2090 LIBYUV_API 2091 LIBYUV_API
2091 int ARGBSobel(const uint8* src_argb, int src_stride_argb, 2092 int ARGBSobel(const uint8* src_argb, int src_stride_argb,
2092 uint8* dst_argb, int dst_stride_argb, 2093 uint8* dst_argb, int dst_stride_argb,
2093 int width, int height) { 2094 int width, int height) {
2094 void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely, 2095 void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely,
2095 uint8* dst_argb, int width) = SobelRow_C; 2096 uint8* dst_argb, int width) = SobelRow_C;
2096 #if defined(HAS_SOBELROW_SSE2) 2097 #if defined(HAS_SOBELROW_SSE2)
2097 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16)) { 2098 if (TestCpuFlag(kCpuHasSSE2)) {
2098 SobelRow = SobelRow_SSE2; 2099 SobelRow = SobelRow_Any_SSE2;
2100 if (IS_ALIGNED(width, 16)) {
2101 SobelRow = SobelRow_SSE2;
2102 }
2099 } 2103 }
2100 #endif 2104 #endif
2101 #if defined(HAS_SOBELROW_NEON) 2105 #if defined(HAS_SOBELROW_NEON)
2102 if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 2106 if (TestCpuFlag(kCpuHasNEON)) {
2103 SobelRow = SobelRow_NEON; 2107 SobelRow = SobelRow_Any_NEON;
2108 if (IS_ALIGNED(width, 8)) {
2109 SobelRow = SobelRow_NEON;
2110 }
2104 } 2111 }
2105 #endif 2112 #endif
2106 return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, 2113 return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
2107 width, height, SobelRow); 2114 width, height, SobelRow);
2108 } 2115 }
2109 2116
2110 // Sobel ARGB effect with planar output. 2117 // Sobel ARGB effect with planar output.
2111 LIBYUV_API 2118 LIBYUV_API
2112 int ARGBSobelToPlane(const uint8* src_argb, int src_stride_argb, 2119 int ARGBSobelToPlane(const uint8* src_argb, int src_stride_argb,
2113 uint8* dst_y, int dst_stride_y, 2120 uint8* dst_y, int dst_stride_y,
2114 int width, int height) { 2121 int width, int height) {
2115 void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely, 2122 void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely,
2116 uint8* dst_, int width) = SobelToPlaneRow_C; 2123 uint8* dst_, int width) = SobelToPlaneRow_C;
2117 #if defined(HAS_SOBELTOPLANEROW_SSE2) 2124 #if defined(HAS_SOBELTOPLANEROW_SSE2)
2118 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16)) { 2125 if (TestCpuFlag(kCpuHasSSE2)) {
2119 SobelToPlaneRow = SobelToPlaneRow_SSE2; 2126 SobelToPlaneRow = SobelToPlaneRow_Any_SSE2;
2127 if (IS_ALIGNED(width, 16)) {
2128 SobelToPlaneRow = SobelToPlaneRow_SSE2;
2129 }
2120 } 2130 }
2121 #endif 2131 #endif
2122 #if defined(HAS_SOBELTOPLANEROW_NEON) 2132 #if defined(HAS_SOBELTOPLANEROW_NEON)
2123 if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) { 2133 if (TestCpuFlag(kCpuHasNEON)) {
2124 SobelToPlaneRow = SobelToPlaneRow_NEON; 2134 SobelToPlaneRow = SobelToPlaneRow_Any_NEON;
2135 if (IS_ALIGNED(width, 16)) {
2136 SobelToPlaneRow = SobelToPlaneRow_NEON;
2137 }
2125 } 2138 }
2126 #endif 2139 #endif
2127 return ARGBSobelize(src_argb, src_stride_argb, dst_y, dst_stride_y, 2140 return ARGBSobelize(src_argb, src_stride_argb, dst_y, dst_stride_y,
2128 width, height, SobelToPlaneRow); 2141 width, height, SobelToPlaneRow);
2129 } 2142 }
2130 2143
2131 // SobelXY ARGB effect. 2144 // SobelXY ARGB effect.
2132 // Similar to Sobel, but also stores Sobel X in R and Sobel Y in B. G = Sobel. 2145 // Similar to Sobel, but also stores Sobel X in R and Sobel Y in B. G = Sobel.
2133 LIBYUV_API 2146 LIBYUV_API
2134 int ARGBSobelXY(const uint8* src_argb, int src_stride_argb, 2147 int ARGBSobelXY(const uint8* src_argb, int src_stride_argb,
2135 uint8* dst_argb, int dst_stride_argb, 2148 uint8* dst_argb, int dst_stride_argb,
2136 int width, int height) { 2149 int width, int height) {
2137 void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely, 2150 void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely,
2138 uint8* dst_argb, int width) = SobelXYRow_C; 2151 uint8* dst_argb, int width) = SobelXYRow_C;
2139 #if defined(HAS_SOBELXYROW_SSE2) 2152 #if defined(HAS_SOBELXYROW_SSE2)
2140 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16)) { 2153 if (TestCpuFlag(kCpuHasSSE2)) {
2141 SobelXYRow = SobelXYRow_SSE2; 2154 SobelXYRow = SobelXYRow_Any_SSE2;
2155 if (IS_ALIGNED(width, 16)) {
2156 SobelXYRow = SobelXYRow_SSE2;
2157 }
2142 } 2158 }
2143 #endif 2159 #endif
2144 #if defined(HAS_SOBELXYROW_NEON) 2160 #if defined(HAS_SOBELXYROW_NEON)
2145 if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 2161 if (TestCpuFlag(kCpuHasNEON)) {
2146 SobelXYRow = SobelXYRow_NEON; 2162 SobelXYRow = SobelXYRow_Any_NEON;
2163 if (IS_ALIGNED(width, 8)) {
2164 SobelXYRow = SobelXYRow_NEON;
2165 }
2147 } 2166 }
2148 #endif 2167 #endif
2149 return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, 2168 return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
2150 width, height, SobelXYRow); 2169 width, height, SobelXYRow);
2151 } 2170 }
2152 2171
2153 // Apply a 4x4 polynomial to each ARGB pixel. 2172 // Apply a 4x4 polynomial to each ARGB pixel.
2154 LIBYUV_API 2173 LIBYUV_API
2155 int ARGBPolynomial(const uint8* src_argb, int src_stride_argb, 2174 int ARGBPolynomial(const uint8* src_argb, int src_stride_argb,
2156 uint8* dst_argb, int dst_stride_argb, 2175 uint8* dst_argb, int dst_stride_argb,
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 #endif 2334 #endif
2316 2335
2317 for (y = 0; y < height; ++y) { 2336 for (y = 0; y < height; ++y) {
2318 ARGBCopyYToAlphaRow(src_y, dst_argb, width); 2337 ARGBCopyYToAlphaRow(src_y, dst_argb, width);
2319 src_y += src_stride_y; 2338 src_y += src_stride_y;
2320 dst_argb += dst_stride_argb; 2339 dst_argb += dst_stride_argb;
2321 } 2340 }
2322 return 0; 2341 return 0;
2323 } 2342 }
2324 2343
2344 LIBYUV_API
2345 int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
2346 uint8* dst_y, int dst_stride_y,
2347 uint8* dst_uv, int dst_stride_uv,
2348 int width, int height) {
2349 int y;
2350 int halfwidth = (width + 1) >> 1;
2351 void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) =
2352 SplitUVRow_C;
2353 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
2354 ptrdiff_t src_stride, int dst_width,
2355 int source_y_fraction) = InterpolateRow_C;
2356 if (!src_yuy2 ||
2357 !dst_y || !dst_uv ||
2358 width <= 0 || height == 0) {
2359 return -1;
2360 }
2361 // Negative height means invert the image.
2362 if (height < 0) {
2363 height = -height;
2364 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
2365 src_stride_yuy2 = -src_stride_yuy2;
2366 }
2367 #if defined(HAS_SPLITUVROW_SSE2)
2368 if (TestCpuFlag(kCpuHasSSE2)) {
2369 SplitUVRow = SplitUVRow_Any_SSE2;
2370 if (IS_ALIGNED(width, 16)) {
2371 SplitUVRow = SplitUVRow_SSE2;
2372 }
2373 }
2374 #endif
2375 #if defined(HAS_SPLITUVROW_AVX2)
2376 if (TestCpuFlag(kCpuHasAVX2)) {
2377 SplitUVRow = SplitUVRow_Any_AVX2;
2378 if (IS_ALIGNED(width, 32)) {
2379 SplitUVRow = SplitUVRow_AVX2;
2380 }
2381 }
2382 #endif
2383 #if defined(HAS_SPLITUVROW_NEON)
2384 if (TestCpuFlag(kCpuHasNEON)) {
2385 SplitUVRow = SplitUVRow_Any_NEON;
2386 if (IS_ALIGNED(width, 16)) {
2387 SplitUVRow = SplitUVRow_NEON;
2388 }
2389 }
2390 #endif
2391 #if defined(HAS_INTERPOLATEROW_SSE2)
2392 if (TestCpuFlag(kCpuHasSSE2)) {
2393 InterpolateRow = InterpolateRow_Any_SSE2;
2394 if (IS_ALIGNED(width, 16)) {
2395 InterpolateRow = InterpolateRow_SSE2;
2396 }
2397 }
2398 #endif
2399 #if defined(HAS_INTERPOLATEROW_SSSE3)
2400 if (TestCpuFlag(kCpuHasSSSE3)) {
2401 InterpolateRow = InterpolateRow_Any_SSSE3;
2402 if (IS_ALIGNED(width, 16)) {
2403 InterpolateRow = InterpolateRow_SSSE3;
2404 }
2405 }
2406 #endif
2407 #if defined(HAS_INTERPOLATEROW_AVX2)
2408 if (TestCpuFlag(kCpuHasAVX2)) {
2409 InterpolateRow = InterpolateRow_Any_AVX2;
2410 if (IS_ALIGNED(width, 32)) {
2411 InterpolateRow = InterpolateRow_AVX2;
2412 }
2413 }
2414 #endif
2415 #if defined(HAS_INTERPOLATEROW_NEON)
2416 if (TestCpuFlag(kCpuHasNEON)) {
2417 InterpolateRow = InterpolateRow_Any_NEON;
2418 if (IS_ALIGNED(width, 16)) {
2419 InterpolateRow = InterpolateRow_NEON;
2420 }
2421 }
2422 #endif
2423
2424 {
2425 int awidth = halfwidth * 2;
2426 // 2 rows of uv
2427 align_buffer_64(rows, awidth * 2);
2428
2429 for (y = 0; y < height - 1; y += 2) {
2430 // Split Y from UV.
2431 SplitUVRow(src_yuy2, dst_y, rows, awidth);
2432 SplitUVRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y,
2433 rows + awidth, awidth);
2434 InterpolateRow(dst_uv, rows, awidth, awidth, 128);
2435 src_yuy2 += src_stride_yuy2 * 2;
2436 dst_y += dst_stride_y * 2;
2437 dst_uv += dst_stride_uv;
2438 }
2439 if (height & 1) {
2440 // Split Y from UV.
2441 SplitUVRow(src_yuy2, dst_y, dst_uv, width);
2442 }
2443 free_aligned_buffer_64(rows);
2444 }
2445 return 0;
2446 }
2447
2448 LIBYUV_API
2449 int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
2450 uint8* dst_y, int dst_stride_y,
2451 uint8* dst_uv, int dst_stride_uv,
2452 int width, int height) {
2453 int y;
2454 int halfwidth = (width + 1) >> 1;
2455 void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) =
2456 SplitUVRow_C;
2457 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
2458 ptrdiff_t src_stride, int dst_width,
2459 int source_y_fraction) = InterpolateRow_C;
2460 if (!src_uyvy ||
2461 !dst_y || !dst_uv ||
2462 width <= 0 || height == 0) {
2463 return -1;
2464 }
2465 // Negative height means invert the image.
2466 if (height < 0) {
2467 height = -height;
2468 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
2469 src_stride_uyvy = -src_stride_uyvy;
2470 }
2471 #if defined(HAS_SPLITUVROW_SSE2)
2472 if (TestCpuFlag(kCpuHasSSE2)) {
2473 SplitUVRow = SplitUVRow_Any_SSE2;
2474 if (IS_ALIGNED(width, 16)) {
2475 SplitUVRow = SplitUVRow_SSE2;
2476 }
2477 }
2478 #endif
2479 #if defined(HAS_SPLITUVROW_AVX2)
2480 if (TestCpuFlag(kCpuHasAVX2)) {
2481 SplitUVRow = SplitUVRow_Any_AVX2;
2482 if (IS_ALIGNED(width, 32)) {
2483 SplitUVRow = SplitUVRow_AVX2;
2484 }
2485 }
2486 #endif
2487 #if defined(HAS_SPLITUVROW_NEON)
2488 if (TestCpuFlag(kCpuHasNEON)) {
2489 SplitUVRow = SplitUVRow_Any_NEON;
2490 if (IS_ALIGNED(width, 16)) {
2491 SplitUVRow = SplitUVRow_NEON;
2492 }
2493 }
2494 #endif
2495 #if defined(HAS_INTERPOLATEROW_SSE2)
2496 if (TestCpuFlag(kCpuHasSSE2)) {
2497 InterpolateRow = InterpolateRow_Any_SSE2;
2498 if (IS_ALIGNED(width, 16)) {
2499 InterpolateRow = InterpolateRow_SSE2;
2500 }
2501 }
2502 #endif
2503 #if defined(HAS_INTERPOLATEROW_SSSE3)
2504 if (TestCpuFlag(kCpuHasSSSE3)) {
2505 InterpolateRow = InterpolateRow_Any_SSSE3;
2506 if (IS_ALIGNED(width, 16)) {
2507 InterpolateRow = InterpolateRow_SSSE3;
2508 }
2509 }
2510 #endif
2511 #if defined(HAS_INTERPOLATEROW_AVX2)
2512 if (TestCpuFlag(kCpuHasAVX2)) {
2513 InterpolateRow = InterpolateRow_Any_AVX2;
2514 if (IS_ALIGNED(width, 32)) {
2515 InterpolateRow = InterpolateRow_AVX2;
2516 }
2517 }
2518 #endif
2519 #if defined(HAS_INTERPOLATEROW_NEON)
2520 if (TestCpuFlag(kCpuHasNEON)) {
2521 InterpolateRow = InterpolateRow_Any_NEON;
2522 if (IS_ALIGNED(width, 16)) {
2523 InterpolateRow = InterpolateRow_NEON;
2524 }
2525 }
2526 #endif
2527
2528 {
2529 int awidth = halfwidth * 2;
2530 // 2 rows of uv
2531 align_buffer_64(rows, awidth * 2);
2532
2533 for (y = 0; y < height - 1; y += 2) {
2534 // Split Y from UV.
2535 SplitUVRow(src_uyvy, rows, dst_y, awidth);
2536 SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth,
2537 dst_y + dst_stride_y, awidth);
2538 InterpolateRow(dst_uv, rows, awidth, awidth, 128);
2539 src_uyvy += src_stride_uyvy * 2;
2540 dst_y += dst_stride_y * 2;
2541 dst_uv += dst_stride_uv;
2542 }
2543 if (height & 1) {
2544 // Split Y from UV.
2545 SplitUVRow(src_uyvy, dst_y, dst_uv, width);
2546 }
2547 free_aligned_buffer_64(rows);
2548 }
2549 return 0;
2550 }
2551
2325 #ifdef __cplusplus 2552 #ifdef __cplusplus
2326 } // extern "C" 2553 } // extern "C"
2327 } // namespace libyuv 2554 } // namespace libyuv
2328 #endif 2555 #endif
OLDNEW
« no previous file with comments | « source/libvpx/third_party/libyuv/source/mjpeg_validate.cc ('k') | source/libvpx/third_party/libyuv/source/rotate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698