| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |