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