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

Side by Side Diff: source/planar_functions.cc

Issue 2277603004: Add SplitUVPlanes and MergeUVPlanes (Closed) Base URL: https://chromium.googlesource.com/libyuv/libyuv@master
Patch Set: moved to planar_functions Created 4 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 13 matching lines...) Expand all
24 extern "C" { 24 extern "C" {
25 #endif 25 #endif
26 26
27 // Copy a plane of data 27 // Copy a plane of data
28 LIBYUV_API 28 LIBYUV_API
29 void CopyPlane(const uint8* src_y, int src_stride_y, 29 void CopyPlane(const uint8* src_y, int src_stride_y,
30 uint8* dst_y, int dst_stride_y, 30 uint8* dst_y, int dst_stride_y,
31 int width, int height) { 31 int width, int height) {
32 int y; 32 int y;
33 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; 33 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
34 // Negative height means invert the image.
fbarchard1 2016/08/24 23:04:11 remove
35 if (height < 0) {
36 height = -height;
37 dst_y = dst_y + (height - 1) * dst_stride_y;
38 dst_stride_y = -dst_stride_y;
39 }
34 // Coalesce rows. 40 // Coalesce rows.
35 if (src_stride_y == width && 41 if (src_stride_y == width &&
36 dst_stride_y == width) { 42 dst_stride_y == width) {
37 width *= height; 43 width *= height;
38 height = 1; 44 height = 1;
39 src_stride_y = dst_stride_y = 0; 45 src_stride_y = dst_stride_y = 0;
40 } 46 }
41 // Nothing to do. 47 // Nothing to do.
42 if (src_y == dst_y && src_stride_y == dst_stride_y) { 48 if (src_y == dst_y && src_stride_y == dst_stride_y) {
43 return; 49 return;
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 if (height < 0) { 223 if (height < 0) {
218 height = -height; 224 height = -height;
219 src_y = src_y + (height - 1) * src_stride_y; 225 src_y = src_y + (height - 1) * src_stride_y;
220 src_stride_y = -src_stride_y; 226 src_stride_y = -src_stride_y;
221 } 227 }
222 228
223 CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 229 CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
224 return 0; 230 return 0;
225 } 231 }
226 232
233 LIBYUV_API
234 int SplitUVPlane(const uint8* src_uv, int src_stride_uv,
235 uint8* dst_u, int dst_stride_u,
236 uint8* dst_v, int dst_stride_v,
237 int width, int height) {
238 if (!src_uv || !dst_u || !dst_v || width <= 0 || height == 0) {
239 return -1;
240 }
241 // Negative height means invert the image.
242 if (height < 0) {
243 height = -height;
244 dst_u = dst_u + (height - 1) * dst_stride_u;
245 dst_v = dst_v + (height - 1) * dst_stride_v;
246 dst_stride_u = -dst_stride_u;
247 dst_stride_v = -dst_stride_v;
248 }
249 // Coalesce rows.
250 if (src_stride_uv == width * 2 &&
251 dst_stride_u == width &&
252 dst_stride_v == width) {
253 width *= height;
254 height = 1;
255 src_stride_uv = dst_stride_u = dst_stride_v = 0;
256 }
257 SplitUVRowFunction SplitUVRow = GetOptimizedSplitUVRowFunction(
258 src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, dst_stride_v, width);
259
260 for (int y = 0; y < height; ++y) {
261 // Copy a row of UV.
262 SplitUVRow(src_uv, dst_u, dst_v, width);
263 dst_u += dst_stride_u;
264 dst_v += dst_stride_v;
265 src_uv += src_stride_uv;
266 }
267 return 0;
268 }
269
270 LIBYUV_API
271 int MergeUVPlanes(const uint8* src_u, int src_stride_u,
fbarchard1 2016/08/24 23:04:11 consider void return
272 const uint8* src_v, int src_stride_v,
273 uint8* dst_uv, int dst_stride_uv,
274 int width, int height) {
275 if (!src_u || !src_v || !dst_uv || width <= 0 || height == 0) {
276 return -1;
277 }
278 // Negative height means invert the image.
279 if (height < 0) {
280 height = -height;
281 dst_uv = dst_uv + (height - 1) * dst_stride_uv;
282 dst_stride_uv = -dst_stride_uv;
283 }
284 // Coalesce rows.
285 if (src_stride_u == width &&
286 src_stride_v == width &&
287 dst_stride_uv == width * 2) {
288 width *= height;
289 height = 1;
290 src_stride_u = src_stride_v = dst_stride_uv = 0;
291 }
292 MergeUVRowFunction MergeUVRow_ = GetOptimizedMergeUVRowFunction(width);
293
294 for (int y = 0; y < height; ++y) {
295 // Merge a row of U and V into a row of UV.
296 MergeUVRow_(src_u, src_v, dst_uv, width);
297 src_u += src_stride_u;
298 src_v += src_stride_v;
299 dst_uv += dst_stride_uv;
300 }
301 return 0;
302 }
303
227 // Mirror a plane of data. 304 // Mirror a plane of data.
228 void MirrorPlane(const uint8* src_y, int src_stride_y, 305 void MirrorPlane(const uint8* src_y, int src_stride_y,
229 uint8* dst_y, int dst_stride_y, 306 uint8* dst_y, int dst_stride_y,
230 int width, int height) { 307 int width, int height) {
231 int y; 308 int y;
232 void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; 309 void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C;
233 // Negative height means invert the image. 310 // Negative height means invert the image.
234 if (height < 0) { 311 if (height < 0) {
235 height = -height; 312 height = -height;
236 src_y = src_y + (height - 1) * src_stride_y; 313 src_y = src_y + (height - 1) * src_stride_y;
(...skipping 2238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 // TODO(fbarchard): Consider if width is even Y channel can be split 2552 // TODO(fbarchard): Consider if width is even Y channel can be split
2476 // directly. A SplitUVRow_Odd function could copy the remaining chroma. 2553 // directly. A SplitUVRow_Odd function could copy the remaining chroma.
2477 2554
2478 LIBYUV_API 2555 LIBYUV_API
2479 int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2, 2556 int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
2480 uint8* dst_y, int dst_stride_y, 2557 uint8* dst_y, int dst_stride_y,
2481 uint8* dst_uv, int dst_stride_uv, 2558 uint8* dst_uv, int dst_stride_uv,
2482 int width, int height) { 2559 int width, int height) {
2483 int y; 2560 int y;
2484 int halfwidth = (width + 1) >> 1; 2561 int halfwidth = (width + 1) >> 1;
2485 void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
fbarchard1 2016/08/24 23:04:11 change not needed for yuy2
2486 int width) = SplitUVRow_C;
2487 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 2562 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
2488 ptrdiff_t src_stride, int dst_width, 2563 ptrdiff_t src_stride, int dst_width,
2489 int source_y_fraction) = InterpolateRow_C; 2564 int source_y_fraction) = InterpolateRow_C;
2490 if (!src_yuy2 || 2565 if (!src_yuy2 ||
2491 !dst_y || !dst_uv || 2566 !dst_y || !dst_uv ||
2492 width <= 0 || height == 0) { 2567 width <= 0 || height == 0) {
2493 return -1; 2568 return -1;
2494 } 2569 }
2495 // Negative height means invert the image. 2570 // Negative height means invert the image.
2496 if (height < 0) { 2571 if (height < 0) {
2497 height = -height; 2572 height = -height;
2498 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 2573 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
2499 src_stride_yuy2 = -src_stride_yuy2; 2574 src_stride_yuy2 = -src_stride_yuy2;
2500 } 2575 }
2501 #if defined(HAS_SPLITUVROW_SSE2)
2502 if (TestCpuFlag(kCpuHasSSE2)) {
2503 SplitUVRow = SplitUVRow_Any_SSE2;
2504 if (IS_ALIGNED(width, 16)) {
2505 SplitUVRow = SplitUVRow_SSE2;
2506 }
2507 }
2508 #endif
2509 #if defined(HAS_SPLITUVROW_AVX2)
2510 if (TestCpuFlag(kCpuHasAVX2)) {
2511 SplitUVRow = SplitUVRow_Any_AVX2;
2512 if (IS_ALIGNED(width, 32)) {
2513 SplitUVRow = SplitUVRow_AVX2;
2514 }
2515 }
2516 #endif
2517 #if defined(HAS_SPLITUVROW_NEON)
2518 if (TestCpuFlag(kCpuHasNEON)) {
2519 SplitUVRow = SplitUVRow_Any_NEON;
2520 if (IS_ALIGNED(width, 16)) {
2521 SplitUVRow = SplitUVRow_NEON;
2522 }
2523 }
2524 #endif
2525 #if defined(HAS_INTERPOLATEROW_SSSE3) 2576 #if defined(HAS_INTERPOLATEROW_SSSE3)
2526 if (TestCpuFlag(kCpuHasSSSE3)) { 2577 if (TestCpuFlag(kCpuHasSSSE3)) {
2527 InterpolateRow = InterpolateRow_Any_SSSE3; 2578 InterpolateRow = InterpolateRow_Any_SSSE3;
2528 if (IS_ALIGNED(width, 16)) { 2579 if (IS_ALIGNED(width, 16)) {
2529 InterpolateRow = InterpolateRow_SSSE3; 2580 InterpolateRow = InterpolateRow_SSSE3;
2530 } 2581 }
2531 } 2582 }
2532 #endif 2583 #endif
2533 #if defined(HAS_INTERPOLATEROW_AVX2) 2584 #if defined(HAS_INTERPOLATEROW_AVX2)
2534 if (TestCpuFlag(kCpuHasAVX2)) { 2585 if (TestCpuFlag(kCpuHasAVX2)) {
(...skipping 10 matching lines...) Expand all
2545 InterpolateRow = InterpolateRow_NEON; 2596 InterpolateRow = InterpolateRow_NEON;
2546 } 2597 }
2547 } 2598 }
2548 #endif 2599 #endif
2549 2600
2550 { 2601 {
2551 int awidth = halfwidth * 2; 2602 int awidth = halfwidth * 2;
2552 // row of y and 2 rows of uv 2603 // row of y and 2 rows of uv
2553 align_buffer_64(rows, awidth * 3); 2604 align_buffer_64(rows, awidth * 3);
2554 2605
2606 SplitUVRowFunction SplitUVRow = GetOptimizedSplitUVRowFunction(
2607 src_yuy2, src_stride_yuy2,
2608 rows, awidth,
2609 rows, awidth,
2610 awidth);
2611
2555 for (y = 0; y < height - 1; y += 2) { 2612 for (y = 0; y < height - 1; y += 2) {
2556 // Split Y from UV. 2613 // Split Y from UV.
2557 SplitUVRow(src_yuy2, rows, rows + awidth, awidth); 2614 SplitUVRow(src_yuy2, rows, rows + awidth, awidth);
2558 memcpy(dst_y, rows, width); 2615 memcpy(dst_y, rows, width);
2559 SplitUVRow(src_yuy2 + src_stride_yuy2, rows, rows + awidth * 2, awidth); 2616 SplitUVRow(src_yuy2 + src_stride_yuy2, rows, rows + awidth * 2, awidth);
2560 memcpy(dst_y + dst_stride_y, rows, width); 2617 memcpy(dst_y + dst_stride_y, rows, width);
2561 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128); 2618 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128);
2562 src_yuy2 += src_stride_yuy2 * 2; 2619 src_yuy2 += src_stride_yuy2 * 2;
2563 dst_y += dst_stride_y * 2; 2620 dst_y += dst_stride_y * 2;
2564 dst_uv += dst_stride_uv; 2621 dst_uv += dst_stride_uv;
2565 } 2622 }
2566 if (height & 1) { 2623 if (height & 1) {
2567 // Split Y from UV. 2624 // Split Y from UV.
2568 SplitUVRow(src_yuy2, rows, dst_uv, awidth); 2625 SplitUVRow(src_yuy2, rows, rows + awidth, awidth);
2569 memcpy(dst_y, rows, width); 2626 memcpy(dst_y, rows, width);
2627 memcpy(dst_uv, rows + awidth, awidth);
2570 } 2628 }
2571 free_aligned_buffer_64(rows); 2629 free_aligned_buffer_64(rows);
2572 } 2630 }
2573 return 0; 2631 return 0;
2574 } 2632 }
2575 2633
2576 LIBYUV_API 2634 LIBYUV_API
2577 int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy, 2635 int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
2578 uint8* dst_y, int dst_stride_y, 2636 uint8* dst_y, int dst_stride_y,
2579 uint8* dst_uv, int dst_stride_uv, 2637 uint8* dst_uv, int dst_stride_uv,
2580 int width, int height) { 2638 int width, int height) {
2581 int y; 2639 int y;
2582 int halfwidth = (width + 1) >> 1; 2640 int halfwidth = (width + 1) >> 1;
2583 void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
2584 int width) = SplitUVRow_C;
2585 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 2641 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
2586 ptrdiff_t src_stride, int dst_width, 2642 ptrdiff_t src_stride, int dst_width,
2587 int source_y_fraction) = InterpolateRow_C; 2643 int source_y_fraction) = InterpolateRow_C;
2588 if (!src_uyvy || 2644 if (!src_uyvy ||
2589 !dst_y || !dst_uv || 2645 !dst_y || !dst_uv ||
2590 width <= 0 || height == 0) { 2646 width <= 0 || height == 0) {
2591 return -1; 2647 return -1;
2592 } 2648 }
2593 // Negative height means invert the image. 2649 // Negative height means invert the image.
2594 if (height < 0) { 2650 if (height < 0) {
2595 height = -height; 2651 height = -height;
2596 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 2652 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
2597 src_stride_uyvy = -src_stride_uyvy; 2653 src_stride_uyvy = -src_stride_uyvy;
2598 } 2654 }
2599 #if defined(HAS_SPLITUVROW_SSE2)
2600 if (TestCpuFlag(kCpuHasSSE2)) {
2601 SplitUVRow = SplitUVRow_Any_SSE2;
2602 if (IS_ALIGNED(width, 16)) {
2603 SplitUVRow = SplitUVRow_SSE2;
2604 }
2605 }
2606 #endif
2607 #if defined(HAS_SPLITUVROW_AVX2)
2608 if (TestCpuFlag(kCpuHasAVX2)) {
2609 SplitUVRow = SplitUVRow_Any_AVX2;
2610 if (IS_ALIGNED(width, 32)) {
2611 SplitUVRow = SplitUVRow_AVX2;
2612 }
2613 }
2614 #endif
2615 #if defined(HAS_SPLITUVROW_NEON)
2616 if (TestCpuFlag(kCpuHasNEON)) {
2617 SplitUVRow = SplitUVRow_Any_NEON;
2618 if (IS_ALIGNED(width, 16)) {
2619 SplitUVRow = SplitUVRow_NEON;
2620 }
2621 }
2622 #endif
2623 #if defined(HAS_INTERPOLATEROW_SSSE3) 2655 #if defined(HAS_INTERPOLATEROW_SSSE3)
2624 if (TestCpuFlag(kCpuHasSSSE3)) { 2656 if (TestCpuFlag(kCpuHasSSSE3)) {
2625 InterpolateRow = InterpolateRow_Any_SSSE3; 2657 InterpolateRow = InterpolateRow_Any_SSSE3;
2626 if (IS_ALIGNED(width, 16)) { 2658 if (IS_ALIGNED(width, 16)) {
2627 InterpolateRow = InterpolateRow_SSSE3; 2659 InterpolateRow = InterpolateRow_SSSE3;
2628 } 2660 }
2629 } 2661 }
2630 #endif 2662 #endif
2631 #if defined(HAS_INTERPOLATEROW_AVX2) 2663 #if defined(HAS_INTERPOLATEROW_AVX2)
2632 if (TestCpuFlag(kCpuHasAVX2)) { 2664 if (TestCpuFlag(kCpuHasAVX2)) {
(...skipping 10 matching lines...) Expand all
2643 InterpolateRow = InterpolateRow_NEON; 2675 InterpolateRow = InterpolateRow_NEON;
2644 } 2676 }
2645 } 2677 }
2646 #endif 2678 #endif
2647 2679
2648 { 2680 {
2649 int awidth = halfwidth * 2; 2681 int awidth = halfwidth * 2;
2650 // row of y and 2 rows of uv 2682 // row of y and 2 rows of uv
2651 align_buffer_64(rows, awidth * 3); 2683 align_buffer_64(rows, awidth * 3);
2652 2684
2685 SplitUVRowFunction SplitUVRow = GetOptimizedSplitUVRowFunction(
2686 src_uyvy, src_stride_uyvy,
2687 rows, awidth,
2688 rows, awidth,
2689 awidth);
2690
2653 for (y = 0; y < height - 1; y += 2) { 2691 for (y = 0; y < height - 1; y += 2) {
2654 // Split Y from UV. 2692 // Split Y from UV.
2655 SplitUVRow(src_uyvy, rows + awidth, rows, awidth); 2693 SplitUVRow(src_uyvy, rows + awidth, rows, awidth);
2656 memcpy(dst_y, rows, width); 2694 memcpy(dst_y, rows, width);
2657 SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth * 2, rows, awidth); 2695 SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth * 2, rows, awidth);
2658 memcpy(dst_y + dst_stride_y, rows, width); 2696 memcpy(dst_y + dst_stride_y, rows, width);
2659 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128); 2697 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128);
2660 src_uyvy += src_stride_uyvy * 2; 2698 src_uyvy += src_stride_uyvy * 2;
2661 dst_y += dst_stride_y * 2; 2699 dst_y += dst_stride_y * 2;
2662 dst_uv += dst_stride_uv; 2700 dst_uv += dst_stride_uv;
2663 } 2701 }
2664 if (height & 1) { 2702 if (height & 1) {
2665 // Split Y from UV. 2703 // Split Y from UV.
2666 SplitUVRow(src_uyvy, dst_uv, rows, awidth); 2704 SplitUVRow(src_uyvy, rows + awidth, rows, awidth);
2667 memcpy(dst_y, rows, width); 2705 memcpy(dst_y, rows, width);
2706 memcpy(dst_uv, rows + awidth, awidth);
2668 } 2707 }
2669 free_aligned_buffer_64(rows); 2708 free_aligned_buffer_64(rows);
2670 } 2709 }
2671 return 0; 2710 return 0;
2672 } 2711 }
2673 2712
2674 #ifdef __cplusplus 2713 #ifdef __cplusplus
2675 } // extern "C" 2714 } // extern "C"
2676 } // namespace libyuv 2715 } // namespace libyuv
2677 #endif 2716 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698