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

Side by Side Diff: source/planar_functions.cc

Issue 2266533003: Add SplitUVPlanes and MergeUVPlanes (Closed) Base URL: https://chromium.googlesource.com/libyuv/libyuv@master
Patch Set: . Created 4 years, 4 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.
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 2425 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 // TODO(fbarchard): Consider if width is even Y channel can be split 2475 // TODO(fbarchard): Consider if width is even Y channel can be split
2470 // directly. A SplitUVRow_Odd function could copy the remaining chroma. 2476 // directly. A SplitUVRow_Odd function could copy the remaining chroma.
2471 2477
2472 LIBYUV_API 2478 LIBYUV_API
2473 int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2, 2479 int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
2474 uint8* dst_y, int dst_stride_y, 2480 uint8* dst_y, int dst_stride_y,
2475 uint8* dst_uv, int dst_stride_uv, 2481 uint8* dst_uv, int dst_stride_uv,
2476 int width, int height) { 2482 int width, int height) {
2477 int y; 2483 int y;
2478 int halfwidth = (width + 1) >> 1; 2484 int halfwidth = (width + 1) >> 1;
2479 void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
2480 int width) = SplitUVRow_C;
2481 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 2485 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
2482 ptrdiff_t src_stride, int dst_width, 2486 ptrdiff_t src_stride, int dst_width,
2483 int source_y_fraction) = InterpolateRow_C; 2487 int source_y_fraction) = InterpolateRow_C;
2484 if (!src_yuy2 || 2488 if (!src_yuy2 ||
2485 !dst_y || !dst_uv || 2489 !dst_y || !dst_uv ||
2486 width <= 0 || height == 0) { 2490 width <= 0 || height == 0) {
2487 return -1; 2491 return -1;
2488 } 2492 }
2489 // Negative height means invert the image. 2493 // Negative height means invert the image.
2490 if (height < 0) { 2494 if (height < 0) {
2491 height = -height; 2495 height = -height;
2492 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 2496 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
2493 src_stride_yuy2 = -src_stride_yuy2; 2497 src_stride_yuy2 = -src_stride_yuy2;
2494 } 2498 }
2495 #if defined(HAS_SPLITUVROW_SSE2)
2496 if (TestCpuFlag(kCpuHasSSE2)) {
2497 SplitUVRow = SplitUVRow_Any_SSE2;
2498 if (IS_ALIGNED(width, 16)) {
2499 SplitUVRow = SplitUVRow_SSE2;
2500 }
2501 }
2502 #endif
2503 #if defined(HAS_SPLITUVROW_AVX2)
2504 if (TestCpuFlag(kCpuHasAVX2)) {
2505 SplitUVRow = SplitUVRow_Any_AVX2;
2506 if (IS_ALIGNED(width, 32)) {
2507 SplitUVRow = SplitUVRow_AVX2;
2508 }
2509 }
2510 #endif
2511 #if defined(HAS_SPLITUVROW_NEON)
2512 if (TestCpuFlag(kCpuHasNEON)) {
2513 SplitUVRow = SplitUVRow_Any_NEON;
2514 if (IS_ALIGNED(width, 16)) {
2515 SplitUVRow = SplitUVRow_NEON;
2516 }
2517 }
2518 #endif
2519 #if defined(HAS_INTERPOLATEROW_SSSE3) 2499 #if defined(HAS_INTERPOLATEROW_SSSE3)
2520 if (TestCpuFlag(kCpuHasSSSE3)) { 2500 if (TestCpuFlag(kCpuHasSSSE3)) {
2521 InterpolateRow = InterpolateRow_Any_SSSE3; 2501 InterpolateRow = InterpolateRow_Any_SSSE3;
2522 if (IS_ALIGNED(width, 16)) { 2502 if (IS_ALIGNED(width, 16)) {
2523 InterpolateRow = InterpolateRow_SSSE3; 2503 InterpolateRow = InterpolateRow_SSSE3;
2524 } 2504 }
2525 } 2505 }
2526 #endif 2506 #endif
2527 #if defined(HAS_INTERPOLATEROW_AVX2) 2507 #if defined(HAS_INTERPOLATEROW_AVX2)
2528 if (TestCpuFlag(kCpuHasAVX2)) { 2508 if (TestCpuFlag(kCpuHasAVX2)) {
(...skipping 10 matching lines...) Expand all
2539 InterpolateRow = InterpolateRow_NEON; 2519 InterpolateRow = InterpolateRow_NEON;
2540 } 2520 }
2541 } 2521 }
2542 #endif 2522 #endif
2543 2523
2544 { 2524 {
2545 int awidth = halfwidth * 2; 2525 int awidth = halfwidth * 2;
2546 // row of y and 2 rows of uv 2526 // row of y and 2 rows of uv
2547 align_buffer_64(rows, awidth * 3); 2527 align_buffer_64(rows, awidth * 3);
2548 2528
2529 SplitUVRowFunction SplitUVRow = GetOptimizedSplitUVRowFunction(
2530 src_yuy2, src_stride_yuy2,
2531 rows, awidth,
2532 rows, awidth,
2533 awidth);
2534
2549 for (y = 0; y < height - 1; y += 2) { 2535 for (y = 0; y < height - 1; y += 2) {
2550 // Split Y from UV. 2536 // Split Y from UV.
2551 SplitUVRow(src_yuy2, rows, rows + awidth, awidth); 2537 SplitUVRow(src_yuy2, rows, rows + awidth, awidth);
2552 memcpy(dst_y, rows, width); 2538 memcpy(dst_y, rows, width);
2553 SplitUVRow(src_yuy2 + src_stride_yuy2, rows, rows + awidth * 2, awidth); 2539 SplitUVRow(src_yuy2 + src_stride_yuy2, rows, rows + awidth * 2, awidth);
2554 memcpy(dst_y + dst_stride_y, rows, width); 2540 memcpy(dst_y + dst_stride_y, rows, width);
2555 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128); 2541 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128);
2556 src_yuy2 += src_stride_yuy2 * 2; 2542 src_yuy2 += src_stride_yuy2 * 2;
2557 dst_y += dst_stride_y * 2; 2543 dst_y += dst_stride_y * 2;
2558 dst_uv += dst_stride_uv; 2544 dst_uv += dst_stride_uv;
2559 } 2545 }
2560 if (height & 1) { 2546 if (height & 1) {
2561 // Split Y from UV. 2547 // Split Y from UV.
2562 SplitUVRow(src_yuy2, rows, dst_uv, awidth); 2548 SplitUVRow(src_yuy2, rows, rows + awidth, awidth);
2563 memcpy(dst_y, rows, width); 2549 memcpy(dst_y, rows, width);
2550 memcpy(dst_uv, rows + awidth, awidth);
2564 } 2551 }
2565 free_aligned_buffer_64(rows); 2552 free_aligned_buffer_64(rows);
2566 } 2553 }
2567 return 0; 2554 return 0;
2568 } 2555 }
2569 2556
2570 LIBYUV_API 2557 LIBYUV_API
2571 int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy, 2558 int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
2572 uint8* dst_y, int dst_stride_y, 2559 uint8* dst_y, int dst_stride_y,
2573 uint8* dst_uv, int dst_stride_uv, 2560 uint8* dst_uv, int dst_stride_uv,
2574 int width, int height) { 2561 int width, int height) {
2575 int y; 2562 int y;
2576 int halfwidth = (width + 1) >> 1; 2563 int halfwidth = (width + 1) >> 1;
2577 void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
2578 int width) = SplitUVRow_C;
2579 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 2564 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr,
2580 ptrdiff_t src_stride, int dst_width, 2565 ptrdiff_t src_stride, int dst_width,
2581 int source_y_fraction) = InterpolateRow_C; 2566 int source_y_fraction) = InterpolateRow_C;
2582 if (!src_uyvy || 2567 if (!src_uyvy ||
2583 !dst_y || !dst_uv || 2568 !dst_y || !dst_uv ||
2584 width <= 0 || height == 0) { 2569 width <= 0 || height == 0) {
2585 return -1; 2570 return -1;
2586 } 2571 }
2587 // Negative height means invert the image. 2572 // Negative height means invert the image.
2588 if (height < 0) { 2573 if (height < 0) {
2589 height = -height; 2574 height = -height;
2590 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 2575 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
2591 src_stride_uyvy = -src_stride_uyvy; 2576 src_stride_uyvy = -src_stride_uyvy;
2592 } 2577 }
2593 #if defined(HAS_SPLITUVROW_SSE2)
2594 if (TestCpuFlag(kCpuHasSSE2)) {
2595 SplitUVRow = SplitUVRow_Any_SSE2;
2596 if (IS_ALIGNED(width, 16)) {
2597 SplitUVRow = SplitUVRow_SSE2;
2598 }
2599 }
2600 #endif
2601 #if defined(HAS_SPLITUVROW_AVX2)
2602 if (TestCpuFlag(kCpuHasAVX2)) {
2603 SplitUVRow = SplitUVRow_Any_AVX2;
2604 if (IS_ALIGNED(width, 32)) {
2605 SplitUVRow = SplitUVRow_AVX2;
2606 }
2607 }
2608 #endif
2609 #if defined(HAS_SPLITUVROW_NEON)
2610 if (TestCpuFlag(kCpuHasNEON)) {
2611 SplitUVRow = SplitUVRow_Any_NEON;
2612 if (IS_ALIGNED(width, 16)) {
2613 SplitUVRow = SplitUVRow_NEON;
2614 }
2615 }
2616 #endif
2617 #if defined(HAS_INTERPOLATEROW_SSSE3) 2578 #if defined(HAS_INTERPOLATEROW_SSSE3)
2618 if (TestCpuFlag(kCpuHasSSSE3)) { 2579 if (TestCpuFlag(kCpuHasSSSE3)) {
2619 InterpolateRow = InterpolateRow_Any_SSSE3; 2580 InterpolateRow = InterpolateRow_Any_SSSE3;
2620 if (IS_ALIGNED(width, 16)) { 2581 if (IS_ALIGNED(width, 16)) {
2621 InterpolateRow = InterpolateRow_SSSE3; 2582 InterpolateRow = InterpolateRow_SSSE3;
2622 } 2583 }
2623 } 2584 }
2624 #endif 2585 #endif
2625 #if defined(HAS_INTERPOLATEROW_AVX2) 2586 #if defined(HAS_INTERPOLATEROW_AVX2)
2626 if (TestCpuFlag(kCpuHasAVX2)) { 2587 if (TestCpuFlag(kCpuHasAVX2)) {
(...skipping 10 matching lines...) Expand all
2637 InterpolateRow = InterpolateRow_NEON; 2598 InterpolateRow = InterpolateRow_NEON;
2638 } 2599 }
2639 } 2600 }
2640 #endif 2601 #endif
2641 2602
2642 { 2603 {
2643 int awidth = halfwidth * 2; 2604 int awidth = halfwidth * 2;
2644 // row of y and 2 rows of uv 2605 // row of y and 2 rows of uv
2645 align_buffer_64(rows, awidth * 3); 2606 align_buffer_64(rows, awidth * 3);
2646 2607
2608 SplitUVRowFunction SplitUVRow = GetOptimizedSplitUVRowFunction(
2609 src_uyvy, src_stride_uyvy,
2610 rows, awidth,
2611 rows, awidth,
2612 awidth);
2613
2647 for (y = 0; y < height - 1; y += 2) { 2614 for (y = 0; y < height - 1; y += 2) {
2648 // Split Y from UV. 2615 // Split Y from UV.
2649 SplitUVRow(src_uyvy, rows + awidth, rows, awidth); 2616 SplitUVRow(src_uyvy, rows + awidth, rows, awidth);
2650 memcpy(dst_y, rows, width); 2617 memcpy(dst_y, rows, width);
2651 SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth * 2, rows, awidth); 2618 SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth * 2, rows, awidth);
2652 memcpy(dst_y + dst_stride_y, rows, width); 2619 memcpy(dst_y + dst_stride_y, rows, width);
2653 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128); 2620 InterpolateRow(dst_uv, rows + awidth, awidth, awidth, 128);
2654 src_uyvy += src_stride_uyvy * 2; 2621 src_uyvy += src_stride_uyvy * 2;
2655 dst_y += dst_stride_y * 2; 2622 dst_y += dst_stride_y * 2;
2656 dst_uv += dst_stride_uv; 2623 dst_uv += dst_stride_uv;
2657 } 2624 }
2658 if (height & 1) { 2625 if (height & 1) {
2659 // Split Y from UV. 2626 // Split Y from UV.
2660 SplitUVRow(src_uyvy, dst_uv, rows, awidth); 2627 SplitUVRow(src_uyvy, rows + awidth, rows, awidth);
2661 memcpy(dst_y, rows, width); 2628 memcpy(dst_y, rows, width);
2629 memcpy(dst_uv, rows + awidth, awidth);
2662 } 2630 }
2663 free_aligned_buffer_64(rows); 2631 free_aligned_buffer_64(rows);
2664 } 2632 }
2665 return 0; 2633 return 0;
2666 } 2634 }
2667 2635
2668 #ifdef __cplusplus 2636 #ifdef __cplusplus
2669 } // extern "C" 2637 } // extern "C"
2670 } // namespace libyuv 2638 } // namespace libyuv
2671 #endif 2639 #endif
OLDNEW
« source/convert.cc ('K') | « source/convert_from_argb.cc ('k') | source/row_common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698