| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM 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 12 matching lines...) Expand all Loading... |
| 23 DCT_ADST, // H | 23 DCT_ADST, // H |
| 24 DCT_DCT, // D45 | 24 DCT_DCT, // D45 |
| 25 ADST_ADST, // D135 | 25 ADST_ADST, // D135 |
| 26 ADST_DCT, // D117 | 26 ADST_DCT, // D117 |
| 27 DCT_ADST, // D153 | 27 DCT_ADST, // D153 |
| 28 DCT_ADST, // D207 | 28 DCT_ADST, // D207 |
| 29 ADST_DCT, // D63 | 29 ADST_DCT, // D63 |
| 30 ADST_ADST, // TM | 30 ADST_ADST, // TM |
| 31 }; | 31 }; |
| 32 | 32 |
| 33 enum { |
| 34 NEED_LEFT = 1 << 1, |
| 35 NEED_ABOVE = 1 << 2, |
| 36 NEED_ABOVERIGHT = 1 << 3, |
| 37 }; |
| 38 |
| 39 static const uint8_t extend_modes[INTRA_MODES] = { |
| 40 NEED_ABOVE | NEED_LEFT, // DC |
| 41 NEED_ABOVE, // V |
| 42 NEED_LEFT, // H |
| 43 NEED_ABOVERIGHT, // D45 |
| 44 NEED_LEFT | NEED_ABOVE, // D135 |
| 45 NEED_LEFT | NEED_ABOVE, // D117 |
| 46 NEED_LEFT | NEED_ABOVE, // D153 |
| 47 NEED_LEFT, // D207 |
| 48 NEED_ABOVERIGHT, // D63 |
| 49 NEED_LEFT | NEED_ABOVE, // TM |
| 50 }; |
| 51 |
| 33 // This serves as a wrapper function, so that all the prediction functions | 52 // This serves as a wrapper function, so that all the prediction functions |
| 34 // can be unified and accessed as a pointer array. Note that the boundary | 53 // can be unified and accessed as a pointer array. Note that the boundary |
| 35 // above and left are not necessarily used all the time. | 54 // above and left are not necessarily used all the time. |
| 36 #define intra_pred_sized(type, size) \ | 55 #define intra_pred_sized(type, size) \ |
| 37 void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \ | 56 void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \ |
| 38 ptrdiff_t stride, \ | 57 ptrdiff_t stride, \ |
| 39 const uint8_t *above, \ | 58 const uint8_t *above, \ |
| 40 const uint8_t *left) { \ | 59 const uint8_t *left) { \ |
| 41 type##_predictor(dst, stride, size, above, left); \ | 60 type##_predictor(dst, stride, size, above, left); \ |
| 42 } | 61 } |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 } | 238 } |
| 220 } | 239 } |
| 221 | 240 |
| 222 static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, | 241 static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, |
| 223 int bs, const uint16_t *above, | 242 int bs, const uint16_t *above, |
| 224 const uint16_t *left, int bd) { | 243 const uint16_t *left, int bd) { |
| 225 int r; | 244 int r; |
| 226 (void) left; | 245 (void) left; |
| 227 (void) bd; | 246 (void) bd; |
| 228 for (r = 0; r < bs; r++) { | 247 for (r = 0; r < bs; r++) { |
| 229 vpx_memcpy(dst, above, bs * sizeof(uint16_t)); | 248 memcpy(dst, above, bs * sizeof(uint16_t)); |
| 230 dst += stride; | 249 dst += stride; |
| 231 } | 250 } |
| 232 } | 251 } |
| 233 | 252 |
| 234 static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, | 253 static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, |
| 235 int bs, const uint16_t *above, | 254 int bs, const uint16_t *above, |
| 236 const uint16_t *left, int bd) { | 255 const uint16_t *left, int bd) { |
| 237 int r; | 256 int r; |
| 238 (void) above; | 257 (void) above; |
| 239 (void) bd; | 258 (void) bd; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 481 } |
| 463 } | 482 } |
| 464 intra_pred_allsizes(d153) | 483 intra_pred_allsizes(d153) |
| 465 | 484 |
| 466 static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs, | 485 static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs, |
| 467 const uint8_t *above, const uint8_t *left) { | 486 const uint8_t *above, const uint8_t *left) { |
| 468 int r; | 487 int r; |
| 469 (void) left; | 488 (void) left; |
| 470 | 489 |
| 471 for (r = 0; r < bs; r++) { | 490 for (r = 0; r < bs; r++) { |
| 472 vpx_memcpy(dst, above, bs); | 491 memcpy(dst, above, bs); |
| 473 dst += stride; | 492 dst += stride; |
| 474 } | 493 } |
| 475 } | 494 } |
| 476 intra_pred_allsizes(v) | 495 intra_pred_allsizes(v) |
| 477 | 496 |
| 478 static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs, | 497 static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs, |
| 479 const uint8_t *above, const uint8_t *left) { | 498 const uint8_t *above, const uint8_t *left) { |
| 480 int r; | 499 int r; |
| 481 (void) above; | 500 (void) above; |
| 482 | 501 |
| 483 for (r = 0; r < bs; r++) { | 502 for (r = 0; r < bs; r++) { |
| 484 vpx_memset(dst, left[r], bs); | 503 memset(dst, left[r], bs); |
| 485 dst += stride; | 504 dst += stride; |
| 486 } | 505 } |
| 487 } | 506 } |
| 488 intra_pred_allsizes(h) | 507 intra_pred_allsizes(h) |
| 489 | 508 |
| 490 static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs, | 509 static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs, |
| 491 const uint8_t *above, const uint8_t *left) { | 510 const uint8_t *above, const uint8_t *left) { |
| 492 int r, c; | 511 int r, c; |
| 493 int ytop_left = above[-1]; | 512 int ytop_left = above[-1]; |
| 494 | 513 |
| 495 for (r = 0; r < bs; r++) { | 514 for (r = 0; r < bs; r++) { |
| 496 for (c = 0; c < bs; c++) | 515 for (c = 0; c < bs; c++) |
| 497 dst[c] = clip_pixel(left[r] + above[c] - ytop_left); | 516 dst[c] = clip_pixel(left[r] + above[c] - ytop_left); |
| 498 dst += stride; | 517 dst += stride; |
| 499 } | 518 } |
| 500 } | 519 } |
| 501 intra_pred_allsizes(tm) | 520 intra_pred_allsizes(tm) |
| 502 | 521 |
| 503 static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs, | 522 static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs, |
| 504 const uint8_t *above, const uint8_t *left) { | 523 const uint8_t *above, const uint8_t *left) { |
| 505 int r; | 524 int r; |
| 506 (void) above; | 525 (void) above; |
| 507 (void) left; | 526 (void) left; |
| 508 | 527 |
| 509 for (r = 0; r < bs; r++) { | 528 for (r = 0; r < bs; r++) { |
| 510 vpx_memset(dst, 128, bs); | 529 memset(dst, 128, bs); |
| 511 dst += stride; | 530 dst += stride; |
| 512 } | 531 } |
| 513 } | 532 } |
| 514 intra_pred_allsizes(dc_128) | 533 intra_pred_allsizes(dc_128) |
| 515 | 534 |
| 516 static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs, | 535 static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs, |
| 517 const uint8_t *above, | 536 const uint8_t *above, |
| 518 const uint8_t *left) { | 537 const uint8_t *left) { |
| 519 int i, r, expected_dc, sum = 0; | 538 int i, r, expected_dc, sum = 0; |
| 520 (void) above; | 539 (void) above; |
| 521 | 540 |
| 522 for (i = 0; i < bs; i++) | 541 for (i = 0; i < bs; i++) |
| 523 sum += left[i]; | 542 sum += left[i]; |
| 524 expected_dc = (sum + (bs >> 1)) / bs; | 543 expected_dc = (sum + (bs >> 1)) / bs; |
| 525 | 544 |
| 526 for (r = 0; r < bs; r++) { | 545 for (r = 0; r < bs; r++) { |
| 527 vpx_memset(dst, expected_dc, bs); | 546 memset(dst, expected_dc, bs); |
| 528 dst += stride; | 547 dst += stride; |
| 529 } | 548 } |
| 530 } | 549 } |
| 531 intra_pred_allsizes(dc_left) | 550 intra_pred_allsizes(dc_left) |
| 532 | 551 |
| 533 static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs, | 552 static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs, |
| 534 const uint8_t *above, const uint8_t *left) { | 553 const uint8_t *above, const uint8_t *left) { |
| 535 int i, r, expected_dc, sum = 0; | 554 int i, r, expected_dc, sum = 0; |
| 536 (void) left; | 555 (void) left; |
| 537 | 556 |
| 538 for (i = 0; i < bs; i++) | 557 for (i = 0; i < bs; i++) |
| 539 sum += above[i]; | 558 sum += above[i]; |
| 540 expected_dc = (sum + (bs >> 1)) / bs; | 559 expected_dc = (sum + (bs >> 1)) / bs; |
| 541 | 560 |
| 542 for (r = 0; r < bs; r++) { | 561 for (r = 0; r < bs; r++) { |
| 543 vpx_memset(dst, expected_dc, bs); | 562 memset(dst, expected_dc, bs); |
| 544 dst += stride; | 563 dst += stride; |
| 545 } | 564 } |
| 546 } | 565 } |
| 547 intra_pred_allsizes(dc_top) | 566 intra_pred_allsizes(dc_top) |
| 548 | 567 |
| 549 static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs, | 568 static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs, |
| 550 const uint8_t *above, const uint8_t *left) { | 569 const uint8_t *above, const uint8_t *left) { |
| 551 int i, r, expected_dc, sum = 0; | 570 int i, r, expected_dc, sum = 0; |
| 552 const int count = 2 * bs; | 571 const int count = 2 * bs; |
| 553 | 572 |
| 554 for (i = 0; i < bs; i++) { | 573 for (i = 0; i < bs; i++) { |
| 555 sum += above[i]; | 574 sum += above[i]; |
| 556 sum += left[i]; | 575 sum += left[i]; |
| 557 } | 576 } |
| 558 | 577 |
| 559 expected_dc = (sum + (count >> 1)) / count; | 578 expected_dc = (sum + (count >> 1)) / count; |
| 560 | 579 |
| 561 for (r = 0; r < bs; r++) { | 580 for (r = 0; r < bs; r++) { |
| 562 vpx_memset(dst, expected_dc, bs); | 581 memset(dst, expected_dc, bs); |
| 563 dst += stride; | 582 dst += stride; |
| 564 } | 583 } |
| 565 } | 584 } |
| 566 intra_pred_allsizes(dc) | 585 intra_pred_allsizes(dc) |
| 567 #undef intra_pred_allsizes | 586 #undef intra_pred_allsizes |
| 568 | 587 |
| 569 typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride, | 588 typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride, |
| 570 const uint8_t *above, const uint8_t *left); | 589 const uint8_t *above, const uint8_t *left); |
| 571 | 590 |
| 572 static intra_pred_fn pred[INTRA_MODES][TX_SIZES]; | 591 static intra_pred_fn pred[INTRA_MODES][TX_SIZES]; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 PREDICTION_MODE mode, | 650 PREDICTION_MODE mode, |
| 632 TX_SIZE tx_size, | 651 TX_SIZE tx_size, |
| 633 int up_available, | 652 int up_available, |
| 634 int left_available, | 653 int left_available, |
| 635 int right_available, | 654 int right_available, |
| 636 int x, int y, | 655 int x, int y, |
| 637 int plane, int bd) { | 656 int plane, int bd) { |
| 638 int i; | 657 int i; |
| 639 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); | 658 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); |
| 640 uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); | 659 uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); |
| 641 DECLARE_ALIGNED_ARRAY(16, uint16_t, left_col, 64); | 660 DECLARE_ALIGNED(16, uint16_t, left_col[32]); |
| 642 DECLARE_ALIGNED_ARRAY(16, uint16_t, above_data, 128 + 16); | 661 DECLARE_ALIGNED(16, uint16_t, above_data[128 + 16]); |
| 643 uint16_t *above_row = above_data + 16; | 662 uint16_t *above_row = above_data + 16; |
| 644 const uint16_t *const_above_row = above_row; | 663 const uint16_t *const_above_row = above_row; |
| 645 const int bs = 4 << tx_size; | 664 const int bs = 4 << tx_size; |
| 646 int frame_width, frame_height; | 665 int frame_width, frame_height; |
| 647 int x0, y0; | 666 int x0, y0; |
| 648 const struct macroblockd_plane *const pd = &xd->plane[plane]; | 667 const struct macroblockd_plane *const pd = &xd->plane[plane]; |
| 649 // int base=128; | 668 // int base=128; |
| 650 int base = 128 << (bd - 8); | 669 int base = 128 << (bd - 8); |
| 651 // 127 127 127 .. 127 127 127 127 127 127 | 670 // 127 127 127 .. 127 127 127 127 127 127 |
| 652 // 129 A B .. Y Z | 671 // 129 A B .. Y Z |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 } | 711 } |
| 693 | 712 |
| 694 // TODO(hkuang) do not extend 2*bs pixels for all modes. | 713 // TODO(hkuang) do not extend 2*bs pixels for all modes. |
| 695 // above | 714 // above |
| 696 if (up_available) { | 715 if (up_available) { |
| 697 const uint16_t *above_ref = ref - ref_stride; | 716 const uint16_t *above_ref = ref - ref_stride; |
| 698 if (xd->mb_to_right_edge < 0) { | 717 if (xd->mb_to_right_edge < 0) { |
| 699 /* slower path if the block needs border extension */ | 718 /* slower path if the block needs border extension */ |
| 700 if (x0 + 2 * bs <= frame_width) { | 719 if (x0 + 2 * bs <= frame_width) { |
| 701 if (right_available && bs == 4) { | 720 if (right_available && bs == 4) { |
| 702 vpx_memcpy(above_row, above_ref, 2 * bs * sizeof(uint16_t)); | 721 memcpy(above_row, above_ref, 2 * bs * sizeof(uint16_t)); |
| 703 } else { | 722 } else { |
| 704 vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t)); | 723 memcpy(above_row, above_ref, bs * sizeof(uint16_t)); |
| 705 vpx_memset16(above_row + bs, above_row[bs - 1], bs); | 724 vpx_memset16(above_row + bs, above_row[bs - 1], bs); |
| 706 } | 725 } |
| 707 } else if (x0 + bs <= frame_width) { | 726 } else if (x0 + bs <= frame_width) { |
| 708 const int r = frame_width - x0; | 727 const int r = frame_width - x0; |
| 709 if (right_available && bs == 4) { | 728 if (right_available && bs == 4) { |
| 710 vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t)); | 729 memcpy(above_row, above_ref, r * sizeof(uint16_t)); |
| 711 vpx_memset16(above_row + r, above_row[r - 1], | 730 vpx_memset16(above_row + r, above_row[r - 1], |
| 712 x0 + 2 * bs - frame_width); | 731 x0 + 2 * bs - frame_width); |
| 713 } else { | 732 } else { |
| 714 vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t)); | 733 memcpy(above_row, above_ref, bs * sizeof(uint16_t)); |
| 715 vpx_memset16(above_row + bs, above_row[bs - 1], bs); | 734 vpx_memset16(above_row + bs, above_row[bs - 1], bs); |
| 716 } | 735 } |
| 717 } else if (x0 <= frame_width) { | 736 } else if (x0 <= frame_width) { |
| 718 const int r = frame_width - x0; | 737 const int r = frame_width - x0; |
| 719 vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t)); | 738 memcpy(above_row, above_ref, r * sizeof(uint16_t)); |
| 720 vpx_memset16(above_row + r, above_row[r - 1], | 739 vpx_memset16(above_row + r, above_row[r - 1], |
| 721 x0 + 2 * bs - frame_width); | 740 x0 + 2 * bs - frame_width); |
| 722 } | 741 } |
| 723 // TODO(Peter) this value should probably change for high bitdepth | 742 // TODO(Peter) this value should probably change for high bitdepth |
| 724 above_row[-1] = left_available ? above_ref[-1] : (base+1); | 743 above_row[-1] = left_available ? above_ref[-1] : (base+1); |
| 725 } else { | 744 } else { |
| 726 /* faster path if the block does not need extension */ | 745 /* faster path if the block does not need extension */ |
| 727 if (bs == 4 && right_available && left_available) { | 746 if (bs == 4 && right_available && left_available) { |
| 728 const_above_row = above_ref; | 747 const_above_row = above_ref; |
| 729 } else { | 748 } else { |
| 730 vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t)); | 749 memcpy(above_row, above_ref, bs * sizeof(uint16_t)); |
| 731 if (bs == 4 && right_available) | 750 if (bs == 4 && right_available) |
| 732 vpx_memcpy(above_row + bs, above_ref + bs, bs * sizeof(uint16_t)); | 751 memcpy(above_row + bs, above_ref + bs, bs * sizeof(uint16_t)); |
| 733 else | 752 else |
| 734 vpx_memset16(above_row + bs, above_row[bs - 1], bs); | 753 vpx_memset16(above_row + bs, above_row[bs - 1], bs); |
| 735 // TODO(Peter): this value should probably change for high bitdepth | 754 // TODO(Peter): this value should probably change for high bitdepth |
| 736 above_row[-1] = left_available ? above_ref[-1] : (base+1); | 755 above_row[-1] = left_available ? above_ref[-1] : (base+1); |
| 737 } | 756 } |
| 738 } | 757 } |
| 739 } else { | 758 } else { |
| 740 vpx_memset16(above_row, base - 1, bs * 2); | 759 vpx_memset16(above_row, base - 1, bs * 2); |
| 741 // TODO(Peter): this value should probably change for high bitdepth | 760 // TODO(Peter): this value should probably change for high bitdepth |
| 742 above_row[-1] = base - 1; | 761 above_row[-1] = base - 1; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 754 } | 773 } |
| 755 #endif // CONFIG_VP9_HIGHBITDEPTH | 774 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 756 | 775 |
| 757 static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref, | 776 static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref, |
| 758 int ref_stride, uint8_t *dst, int dst_stride, | 777 int ref_stride, uint8_t *dst, int dst_stride, |
| 759 PREDICTION_MODE mode, TX_SIZE tx_size, | 778 PREDICTION_MODE mode, TX_SIZE tx_size, |
| 760 int up_available, int left_available, | 779 int up_available, int left_available, |
| 761 int right_available, int x, int y, | 780 int right_available, int x, int y, |
| 762 int plane) { | 781 int plane) { |
| 763 int i; | 782 int i; |
| 764 DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64); | 783 DECLARE_ALIGNED(16, uint8_t, left_col[32]); |
| 765 DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16); | 784 DECLARE_ALIGNED(16, uint8_t, above_data[128 + 16]); |
| 766 uint8_t *above_row = above_data + 16; | 785 uint8_t *above_row = above_data + 16; |
| 767 const uint8_t *const_above_row = above_row; | 786 const uint8_t *const_above_row = above_row; |
| 768 const int bs = 4 << tx_size; | 787 const int bs = 4 << tx_size; |
| 769 int frame_width, frame_height; | 788 int frame_width, frame_height; |
| 770 int x0, y0; | 789 int x0, y0; |
| 771 const struct macroblockd_plane *const pd = &xd->plane[plane]; | 790 const struct macroblockd_plane *const pd = &xd->plane[plane]; |
| 772 | 791 |
| 773 // 127 127 127 .. 127 127 127 127 127 127 | 792 // 127 127 127 .. 127 127 127 127 127 127 |
| 774 // 129 A B .. Y Z | 793 // 129 A B .. Y Z |
| 775 // 129 C D .. W X | 794 // 129 C D .. W X |
| 776 // 129 E F .. U V | 795 // 129 E F .. U V |
| 777 // 129 G H .. S T T T T T | 796 // 129 G H .. S T T T T T |
| 778 // .. | 797 // .. |
| 779 | 798 |
| 780 // Get current frame pointer, width and height. | 799 // Get current frame pointer, width and height. |
| 781 if (plane == 0) { | 800 if (plane == 0) { |
| 782 frame_width = xd->cur_buf->y_width; | 801 frame_width = xd->cur_buf->y_width; |
| 783 frame_height = xd->cur_buf->y_height; | 802 frame_height = xd->cur_buf->y_height; |
| 784 } else { | 803 } else { |
| 785 frame_width = xd->cur_buf->uv_width; | 804 frame_width = xd->cur_buf->uv_width; |
| 786 frame_height = xd->cur_buf->uv_height; | 805 frame_height = xd->cur_buf->uv_height; |
| 787 } | 806 } |
| 788 | 807 |
| 789 // Get block position in current frame. | 808 // Get block position in current frame. |
| 790 x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; | 809 x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; |
| 791 y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; | 810 y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; |
| 792 | 811 |
| 793 vpx_memset(left_col, 129, 64); | 812 // NEED_LEFT |
| 794 | 813 if (extend_modes[mode] & NEED_LEFT) { |
| 795 // left | 814 if (left_available) { |
| 796 if (left_available) { | 815 if (xd->mb_to_bottom_edge < 0) { |
| 797 if (xd->mb_to_bottom_edge < 0) { | 816 /* slower path if the block needs border extension */ |
| 798 /* slower path if the block needs border extension */ | 817 if (y0 + bs <= frame_height) { |
| 799 if (y0 + bs <= frame_height) { | 818 for (i = 0; i < bs; ++i) |
| 819 left_col[i] = ref[i * ref_stride - 1]; |
| 820 } else { |
| 821 const int extend_bottom = frame_height - y0; |
| 822 for (i = 0; i < extend_bottom; ++i) |
| 823 left_col[i] = ref[i * ref_stride - 1]; |
| 824 for (; i < bs; ++i) |
| 825 left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1]; |
| 826 } |
| 827 } else { |
| 828 /* faster path if the block does not need extension */ |
| 800 for (i = 0; i < bs; ++i) | 829 for (i = 0; i < bs; ++i) |
| 801 left_col[i] = ref[i * ref_stride - 1]; | 830 left_col[i] = ref[i * ref_stride - 1]; |
| 802 } else { | |
| 803 const int extend_bottom = frame_height - y0; | |
| 804 for (i = 0; i < extend_bottom; ++i) | |
| 805 left_col[i] = ref[i * ref_stride - 1]; | |
| 806 for (; i < bs; ++i) | |
| 807 left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1]; | |
| 808 } | 831 } |
| 809 } else { | 832 } else { |
| 810 /* faster path if the block does not need extension */ | 833 memset(left_col, 129, bs); |
| 811 for (i = 0; i < bs; ++i) | |
| 812 left_col[i] = ref[i * ref_stride - 1]; | |
| 813 } | 834 } |
| 814 } | 835 } |
| 815 | 836 |
| 816 // TODO(hkuang) do not extend 2*bs pixels for all modes. | 837 // NEED_ABOVE |
| 817 // above | 838 if (extend_modes[mode] & NEED_ABOVE) { |
| 818 if (up_available) { | 839 if (up_available) { |
| 819 const uint8_t *above_ref = ref - ref_stride; | 840 const uint8_t *above_ref = ref - ref_stride; |
| 820 if (xd->mb_to_right_edge < 0) { | 841 if (xd->mb_to_right_edge < 0) { |
| 821 /* slower path if the block needs border extension */ | 842 /* slower path if the block needs border extension */ |
| 822 if (x0 + 2 * bs <= frame_width) { | 843 if (x0 + bs <= frame_width) { |
| 823 if (right_available && bs == 4) { | 844 memcpy(above_row, above_ref, bs); |
| 824 vpx_memcpy(above_row, above_ref, 2 * bs); | 845 } else if (x0 <= frame_width) { |
| 846 const int r = frame_width - x0; |
| 847 memcpy(above_row, above_ref, r); |
| 848 memset(above_row + r, above_row[r - 1], x0 + bs - frame_width); |
| 849 } |
| 850 } else { |
| 851 /* faster path if the block does not need extension */ |
| 852 if (bs == 4 && right_available && left_available) { |
| 853 const_above_row = above_ref; |
| 825 } else { | 854 } else { |
| 826 vpx_memcpy(above_row, above_ref, bs); | 855 memcpy(above_row, above_ref, bs); |
| 827 vpx_memset(above_row + bs, above_row[bs - 1], bs); | |
| 828 } | 856 } |
| 829 } else if (x0 + bs <= frame_width) { | |
| 830 const int r = frame_width - x0; | |
| 831 if (right_available && bs == 4) { | |
| 832 vpx_memcpy(above_row, above_ref, r); | |
| 833 vpx_memset(above_row + r, above_row[r - 1], | |
| 834 x0 + 2 * bs - frame_width); | |
| 835 } else { | |
| 836 vpx_memcpy(above_row, above_ref, bs); | |
| 837 vpx_memset(above_row + bs, above_row[bs - 1], bs); | |
| 838 } | |
| 839 } else if (x0 <= frame_width) { | |
| 840 const int r = frame_width - x0; | |
| 841 vpx_memcpy(above_row, above_ref, r); | |
| 842 vpx_memset(above_row + r, above_row[r - 1], | |
| 843 x0 + 2 * bs - frame_width); | |
| 844 } | 857 } |
| 845 above_row[-1] = left_available ? above_ref[-1] : 129; | 858 above_row[-1] = left_available ? above_ref[-1] : 129; |
| 846 } else { | 859 } else { |
| 847 /* faster path if the block does not need extension */ | 860 memset(above_row, 127, bs); |
| 848 if (bs == 4 && right_available && left_available) { | 861 above_row[-1] = 127; |
| 849 const_above_row = above_ref; | 862 } |
| 863 } |
| 864 |
| 865 // NEED_ABOVERIGHT |
| 866 if (extend_modes[mode] & NEED_ABOVERIGHT) { |
| 867 if (up_available) { |
| 868 const uint8_t *above_ref = ref - ref_stride; |
| 869 if (xd->mb_to_right_edge < 0) { |
| 870 /* slower path if the block needs border extension */ |
| 871 if (x0 + 2 * bs <= frame_width) { |
| 872 if (right_available && bs == 4) { |
| 873 memcpy(above_row, above_ref, 2 * bs); |
| 874 } else { |
| 875 memcpy(above_row, above_ref, bs); |
| 876 memset(above_row + bs, above_row[bs - 1], bs); |
| 877 } |
| 878 } else if (x0 + bs <= frame_width) { |
| 879 const int r = frame_width - x0; |
| 880 if (right_available && bs == 4) { |
| 881 memcpy(above_row, above_ref, r); |
| 882 memset(above_row + r, above_row[r - 1], x0 + 2 * bs - frame_width); |
| 883 } else { |
| 884 memcpy(above_row, above_ref, bs); |
| 885 memset(above_row + bs, above_row[bs - 1], bs); |
| 886 } |
| 887 } else if (x0 <= frame_width) { |
| 888 const int r = frame_width - x0; |
| 889 memcpy(above_row, above_ref, r); |
| 890 memset(above_row + r, above_row[r - 1], x0 + 2 * bs - frame_width); |
| 891 } |
| 850 } else { | 892 } else { |
| 851 vpx_memcpy(above_row, above_ref, bs); | 893 /* faster path if the block does not need extension */ |
| 852 if (bs == 4 && right_available) | 894 if (bs == 4 && right_available && left_available) { |
| 853 vpx_memcpy(above_row + bs, above_ref + bs, bs); | 895 const_above_row = above_ref; |
| 854 else | 896 } else { |
| 855 vpx_memset(above_row + bs, above_row[bs - 1], bs); | 897 memcpy(above_row, above_ref, bs); |
| 856 above_row[-1] = left_available ? above_ref[-1] : 129; | 898 if (bs == 4 && right_available) |
| 899 memcpy(above_row + bs, above_ref + bs, bs); |
| 900 else |
| 901 memset(above_row + bs, above_row[bs - 1], bs); |
| 902 } |
| 857 } | 903 } |
| 904 above_row[-1] = left_available ? above_ref[-1] : 129; |
| 905 } else { |
| 906 memset(above_row, 127, bs * 2); |
| 907 above_row[-1] = 127; |
| 858 } | 908 } |
| 859 } else { | |
| 860 vpx_memset(above_row, 127, bs * 2); | |
| 861 above_row[-1] = 127; | |
| 862 } | 909 } |
| 863 | 910 |
| 864 // predict | 911 // predict |
| 865 if (mode == DC_PRED) { | 912 if (mode == DC_PRED) { |
| 866 dc_pred[left_available][up_available][tx_size](dst, dst_stride, | 913 dc_pred[left_available][up_available][tx_size](dst, dst_stride, |
| 867 const_above_row, left_col); | 914 const_above_row, left_col); |
| 868 } else { | 915 } else { |
| 869 pred[mode][tx_size](dst, dst_stride, const_above_row, left_col); | 916 pred[mode][tx_size](dst, dst_stride, const_above_row, left_col); |
| 870 } | 917 } |
| 871 } | 918 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 892 return; | 939 return; |
| 893 } | 940 } |
| 894 #endif | 941 #endif |
| 895 build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size, | 942 build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size, |
| 896 have_top, have_left, have_right, x, y, plane); | 943 have_top, have_left, have_right, x, y, plane); |
| 897 } | 944 } |
| 898 | 945 |
| 899 void vp9_init_intra_predictors() { | 946 void vp9_init_intra_predictors() { |
| 900 once(vp9_init_intra_predictors_internal); | 947 once(vp9_init_intra_predictors_internal); |
| 901 } | 948 } |
| OLD | NEW |