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 |