OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The LibYuv Project Authors. All rights reserved. | 2 * Copyright 2012 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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 return 0; | 359 return 0; |
360 } | 360 } |
361 | 361 |
362 LIBYUV_API | 362 LIBYUV_API |
363 int I420ToNV12(const uint8* src_y, int src_stride_y, | 363 int I420ToNV12(const uint8* src_y, int src_stride_y, |
364 const uint8* src_u, int src_stride_u, | 364 const uint8* src_u, int src_stride_u, |
365 const uint8* src_v, int src_stride_v, | 365 const uint8* src_v, int src_stride_v, |
366 uint8* dst_y, int dst_stride_y, | 366 uint8* dst_y, int dst_stride_y, |
367 uint8* dst_uv, int dst_stride_uv, | 367 uint8* dst_uv, int dst_stride_uv, |
368 int width, int height) { | 368 int width, int height) { |
369 int y; | |
370 void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv, | |
371 int width) = MergeUVRow_C; | |
372 // Coalesce rows. | |
373 int halfwidth = (width + 1) >> 1; | |
374 int halfheight = (height + 1) >> 1; | |
375 if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || | 369 if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || |
376 width <= 0 || height == 0) { | 370 width <= 0 || height == 0) { |
377 return -1; | 371 return -1; |
378 } | 372 } |
| 373 int halfwidth = (width + 1) / 2; |
| 374 int halfheight = height > 0 ? (height + 1) / 2 : (height - 1) / 2; |
| 375 CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); |
| 376 return MergeUVPlanes(src_u, src_stride_u, |
| 377 src_v, src_stride_v, |
| 378 dst_uv, dst_stride_uv, |
| 379 halfwidth, halfheight); |
| 380 } |
| 381 |
| 382 LIBYUV_API |
| 383 int MergeUVPlanes(const uint8* src_u, int src_stride_u, |
| 384 const uint8* src_v, int src_stride_v, |
| 385 uint8* dst_uv, int dst_stride_uv, |
| 386 int width, int height) { |
| 387 if (!src_u || !src_v || !dst_uv || width <= 0 || height == 0) { |
| 388 return -1; |
| 389 } |
379 // Negative height means invert the image. | 390 // Negative height means invert the image. |
380 if (height < 0) { | 391 if (height < 0) { |
381 height = -height; | 392 height = -height; |
382 halfheight = (height + 1) >> 1; | 393 dst_uv = dst_uv + (height - 1) * dst_stride_uv; |
383 dst_y = dst_y + (height - 1) * dst_stride_y; | |
384 dst_uv = dst_uv + (halfheight - 1) * dst_stride_uv; | |
385 dst_stride_y = -dst_stride_y; | |
386 dst_stride_uv = -dst_stride_uv; | 394 dst_stride_uv = -dst_stride_uv; |
387 } | 395 } |
388 if (src_stride_y == width && | 396 // Coalesce rows. |
389 dst_stride_y == width) { | 397 if (src_stride_u == width && |
| 398 src_stride_v == width && |
| 399 dst_stride_uv == width * 2) { |
390 width *= height; | 400 width *= height; |
391 height = 1; | 401 height = 1; |
392 src_stride_y = dst_stride_y = 0; | |
393 } | |
394 // Coalesce rows. | |
395 if (src_stride_u == halfwidth && | |
396 src_stride_v == halfwidth && | |
397 dst_stride_uv == halfwidth * 2) { | |
398 halfwidth *= halfheight; | |
399 halfheight = 1; | |
400 src_stride_u = src_stride_v = dst_stride_uv = 0; | 402 src_stride_u = src_stride_v = dst_stride_uv = 0; |
401 } | 403 } |
402 #if defined(HAS_MERGEUVROW_SSE2) | 404 MergeUVRowFunction MergeUVRow_ = GetOptimizedMergeUVRowFunction(width); |
403 if (TestCpuFlag(kCpuHasSSE2)) { | |
404 MergeUVRow_ = MergeUVRow_Any_SSE2; | |
405 if (IS_ALIGNED(halfwidth, 16)) { | |
406 MergeUVRow_ = MergeUVRow_SSE2; | |
407 } | |
408 } | |
409 #endif | |
410 #if defined(HAS_MERGEUVROW_AVX2) | |
411 if (TestCpuFlag(kCpuHasAVX2)) { | |
412 MergeUVRow_ = MergeUVRow_Any_AVX2; | |
413 if (IS_ALIGNED(halfwidth, 32)) { | |
414 MergeUVRow_ = MergeUVRow_AVX2; | |
415 } | |
416 } | |
417 #endif | |
418 #if defined(HAS_MERGEUVROW_NEON) | |
419 if (TestCpuFlag(kCpuHasNEON)) { | |
420 MergeUVRow_ = MergeUVRow_Any_NEON; | |
421 if (IS_ALIGNED(halfwidth, 16)) { | |
422 MergeUVRow_ = MergeUVRow_NEON; | |
423 } | |
424 } | |
425 #endif | |
426 | 405 |
427 CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); | 406 for (int y = 0; y < height; ++y) { |
428 for (y = 0; y < halfheight; ++y) { | |
429 // Merge a row of U and V into a row of UV. | 407 // Merge a row of U and V into a row of UV. |
430 MergeUVRow_(src_u, src_v, dst_uv, halfwidth); | 408 MergeUVRow_(src_u, src_v, dst_uv, width); |
431 src_u += src_stride_u; | 409 src_u += src_stride_u; |
432 src_v += src_stride_v; | 410 src_v += src_stride_v; |
433 dst_uv += dst_stride_uv; | 411 dst_uv += dst_stride_uv; |
434 } | 412 } |
435 return 0; | 413 return 0; |
436 } | 414 } |
437 | 415 |
438 LIBYUV_API | 416 LIBYUV_API |
439 int I420ToNV21(const uint8* src_y, int src_stride_y, | 417 int I420ToNV21(const uint8* src_y, int src_stride_y, |
440 const uint8* src_u, int src_stride_u, | 418 const uint8* src_u, int src_stride_u, |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 default: | 1135 default: |
1158 return -1; // unknown fourcc - return failure code. | 1136 return -1; // unknown fourcc - return failure code. |
1159 } | 1137 } |
1160 return r; | 1138 return r; |
1161 } | 1139 } |
1162 | 1140 |
1163 #ifdef __cplusplus | 1141 #ifdef __cplusplus |
1164 } // extern "C" | 1142 } // extern "C" |
1165 } // namespace libyuv | 1143 } // namespace libyuv |
1166 #endif | 1144 #endif |
OLD | NEW |