Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(574)

Side by Side Diff: source/libvpx/vp9/encoder/vp9_resize.c

Issue 668403002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_resize.h ('k') | source/libvpx/vp9/encoder/vp9_sad.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2014 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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 inlength ? inlength - 1 : 305 inlength ? inlength - 1 :
306 int_pel - INTERP_TAPS / 2 + 1 + k)]; 306 int_pel - INTERP_TAPS / 2 + 1 + k)];
307 *optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); 307 *optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
308 } 308 }
309 } 309 }
310 } 310 }
311 311
312 static void down2_symeven(const uint8_t *const input, int length, 312 static void down2_symeven(const uint8_t *const input, int length,
313 uint8_t *output) { 313 uint8_t *output) {
314 // Actual filter len = 2 * filter_len_half. 314 // Actual filter len = 2 * filter_len_half.
315 static const int16_t *filter = vp9_down2_symeven_half_filter; 315 const int16_t *filter = vp9_down2_symeven_half_filter;
316 const int filter_len_half = sizeof(vp9_down2_symeven_half_filter) / 2; 316 const int filter_len_half = sizeof(vp9_down2_symeven_half_filter) / 2;
317 int i, j; 317 int i, j;
318 uint8_t *optr = output; 318 uint8_t *optr = output;
319 int l1 = filter_len_half; 319 int l1 = filter_len_half;
320 int l2 = (length - filter_len_half); 320 int l2 = (length - filter_len_half);
321 l1 += (l1 & 1); 321 l1 += (l1 & 1);
322 l2 += (l2 & 1); 322 l2 += (l2 & 1);
323 if (l1 > l2) { 323 if (l1 > l2) {
324 // Short input length. 324 // Short input length.
325 for (i = 0; i < length; i += 2) { 325 for (i = 0; i < length; i += 2) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 } 361 }
362 sum >>= FILTER_BITS; 362 sum >>= FILTER_BITS;
363 *optr++ = clip_pixel(sum); 363 *optr++ = clip_pixel(sum);
364 } 364 }
365 } 365 }
366 } 366 }
367 367
368 static void down2_symodd(const uint8_t *const input, int length, 368 static void down2_symodd(const uint8_t *const input, int length,
369 uint8_t *output) { 369 uint8_t *output) {
370 // Actual filter len = 2 * filter_len_half - 1. 370 // Actual filter len = 2 * filter_len_half - 1.
371 static const int16_t *filter = vp9_down2_symodd_half_filter; 371 const int16_t *filter = vp9_down2_symodd_half_filter;
372 const int filter_len_half = sizeof(vp9_down2_symodd_half_filter) / 2; 372 const int filter_len_half = sizeof(vp9_down2_symodd_half_filter) / 2;
373 int i, j; 373 int i, j;
374 uint8_t *optr = output; 374 uint8_t *optr = output;
375 int l1 = filter_len_half - 1; 375 int l1 = filter_len_half - 1;
376 int l2 = (length - filter_len_half + 1); 376 int l2 = (length - filter_len_half + 1);
377 l1 += (l1 & 1); 377 l1 += (l1 & 1);
378 l2 += (l2 & 1); 378 l2 += (l2 & 1);
379 if (l1 > l2) { 379 if (l1 > l2) {
380 // Short input length. 380 // Short input length.
381 for (i = 0; i < length; i += 2) { 381 for (i = 0; i < length; i += 2) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 for (i = 0; i < width2; ++i) { 522 for (i = 0; i < width2; ++i) {
523 fill_col_to_arr(intbuf + i, width2, height, arrbuf); 523 fill_col_to_arr(intbuf + i, width2, height, arrbuf);
524 resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf); 524 resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf);
525 fill_arr_to_col(output + i, out_stride, height2, arrbuf + height); 525 fill_arr_to_col(output + i, out_stride, height2, arrbuf + height);
526 } 526 }
527 free(intbuf); 527 free(intbuf);
528 free(tmpbuf); 528 free(tmpbuf);
529 free(arrbuf); 529 free(arrbuf);
530 } 530 }
531 531
532 #if CONFIG_VP9_HIGHBITDEPTH
533 static void highbd_interpolate(const uint16_t *const input, int inlength,
534 uint16_t *output, int outlength, int bd) {
535 const int64_t delta =
536 (((uint64_t)inlength << 32) + outlength / 2) / outlength;
537 const int64_t offset = inlength > outlength ?
538 (((int64_t)(inlength - outlength) << 31) + outlength / 2) / outlength :
539 -(((int64_t)(outlength - inlength) << 31) + outlength / 2) / outlength;
540 uint16_t *optr = output;
541 int x, x1, x2, sum, k, int_pel, sub_pel;
542 int64_t y;
543
544 const interp_kernel *interp_filters =
545 choose_interp_filter(inlength, outlength);
546
547 x = 0;
548 y = offset;
549 while ((y >> INTERP_PRECISION_BITS) < (INTERP_TAPS / 2 - 1)) {
550 x++;
551 y += delta;
552 }
553 x1 = x;
554 x = outlength - 1;
555 y = delta * x + offset;
556 while ((y >> INTERP_PRECISION_BITS) +
557 (int64_t)(INTERP_TAPS / 2) >= inlength) {
558 x--;
559 y -= delta;
560 }
561 x2 = x;
562 if (x1 > x2) {
563 for (x = 0, y = offset; x < outlength; ++x, y += delta) {
564 const int16_t *filter;
565 int_pel = y >> INTERP_PRECISION_BITS;
566 sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
567 filter = interp_filters[sub_pel];
568 sum = 0;
569 for (k = 0; k < INTERP_TAPS; ++k) {
570 const int pk = int_pel - INTERP_TAPS / 2 + 1 + k;
571 sum += filter[k] *
572 input[(pk < 0 ? 0 : (pk >= inlength ? inlength - 1 : pk))];
573 }
574 *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd);
575 }
576 } else {
577 // Initial part.
578 for (x = 0, y = offset; x < x1; ++x, y += delta) {
579 const int16_t *filter;
580 int_pel = y >> INTERP_PRECISION_BITS;
581 sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
582 filter = interp_filters[sub_pel];
583 sum = 0;
584 for (k = 0; k < INTERP_TAPS; ++k)
585 sum += filter[k] *
586 input[(int_pel - INTERP_TAPS / 2 + 1 + k < 0 ?
587 0 : int_pel - INTERP_TAPS / 2 + 1 + k)];
588 *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd);
589 }
590 // Middle part.
591 for (; x <= x2; ++x, y += delta) {
592 const int16_t *filter;
593 int_pel = y >> INTERP_PRECISION_BITS;
594 sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
595 filter = interp_filters[sub_pel];
596 sum = 0;
597 for (k = 0; k < INTERP_TAPS; ++k)
598 sum += filter[k] * input[int_pel - INTERP_TAPS / 2 + 1 + k];
599 *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd);
600 }
601 // End part.
602 for (; x < outlength; ++x, y += delta) {
603 const int16_t *filter;
604 int_pel = y >> INTERP_PRECISION_BITS;
605 sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK;
606 filter = interp_filters[sub_pel];
607 sum = 0;
608 for (k = 0; k < INTERP_TAPS; ++k)
609 sum += filter[k] * input[(int_pel - INTERP_TAPS / 2 + 1 + k >=
610 inlength ? inlength - 1 :
611 int_pel - INTERP_TAPS / 2 + 1 + k)];
612 *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd);
613 }
614 }
615 }
616
617 static void highbd_down2_symeven(const uint16_t *const input, int length,
618 uint16_t *output, int bd) {
619 // Actual filter len = 2 * filter_len_half.
620 static const int16_t *filter = vp9_down2_symeven_half_filter;
621 const int filter_len_half = sizeof(vp9_down2_symeven_half_filter) / 2;
622 int i, j;
623 uint16_t *optr = output;
624 int l1 = filter_len_half;
625 int l2 = (length - filter_len_half);
626 l1 += (l1 & 1);
627 l2 += (l2 & 1);
628 if (l1 > l2) {
629 // Short input length.
630 for (i = 0; i < length; i += 2) {
631 int sum = (1 << (FILTER_BITS - 1));
632 for (j = 0; j < filter_len_half; ++j) {
633 sum += (input[(i - j < 0 ? 0 : i - j)] +
634 input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) *
635 filter[j];
636 }
637 sum >>= FILTER_BITS;
638 *optr++ = clip_pixel_highbd(sum, bd);
639 }
640 } else {
641 // Initial part.
642 for (i = 0; i < l1; i += 2) {
643 int sum = (1 << (FILTER_BITS - 1));
644 for (j = 0; j < filter_len_half; ++j) {
645 sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + 1 + j]) * filter[j];
646 }
647 sum >>= FILTER_BITS;
648 *optr++ = clip_pixel_highbd(sum, bd);
649 }
650 // Middle part.
651 for (; i < l2; i += 2) {
652 int sum = (1 << (FILTER_BITS - 1));
653 for (j = 0; j < filter_len_half; ++j) {
654 sum += (input[i - j] + input[i + 1 + j]) * filter[j];
655 }
656 sum >>= FILTER_BITS;
657 *optr++ = clip_pixel_highbd(sum, bd);
658 }
659 // End part.
660 for (; i < length; i += 2) {
661 int sum = (1 << (FILTER_BITS - 1));
662 for (j = 0; j < filter_len_half; ++j) {
663 sum += (input[i - j] +
664 input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) *
665 filter[j];
666 }
667 sum >>= FILTER_BITS;
668 *optr++ = clip_pixel_highbd(sum, bd);
669 }
670 }
671 }
672
673 static void highbd_down2_symodd(const uint16_t *const input, int length,
674 uint16_t *output, int bd) {
675 // Actual filter len = 2 * filter_len_half - 1.
676 static const int16_t *filter = vp9_down2_symodd_half_filter;
677 const int filter_len_half = sizeof(vp9_down2_symodd_half_filter) / 2;
678 int i, j;
679 uint16_t *optr = output;
680 int l1 = filter_len_half - 1;
681 int l2 = (length - filter_len_half + 1);
682 l1 += (l1 & 1);
683 l2 += (l2 & 1);
684 if (l1 > l2) {
685 // Short input length.
686 for (i = 0; i < length; i += 2) {
687 int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0];
688 for (j = 1; j < filter_len_half; ++j) {
689 sum += (input[(i - j < 0 ? 0 : i - j)] +
690 input[(i + j >= length ? length - 1 : i + j)]) *
691 filter[j];
692 }
693 sum >>= FILTER_BITS;
694 *optr++ = clip_pixel_highbd(sum, bd);
695 }
696 } else {
697 // Initial part.
698 for (i = 0; i < l1; i += 2) {
699 int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0];
700 for (j = 1; j < filter_len_half; ++j) {
701 sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + j]) * filter[j];
702 }
703 sum >>= FILTER_BITS;
704 *optr++ = clip_pixel_highbd(sum, bd);
705 }
706 // Middle part.
707 for (; i < l2; i += 2) {
708 int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0];
709 for (j = 1; j < filter_len_half; ++j) {
710 sum += (input[i - j] + input[i + j]) * filter[j];
711 }
712 sum >>= FILTER_BITS;
713 *optr++ = clip_pixel_highbd(sum, bd);
714 }
715 // End part.
716 for (; i < length; i += 2) {
717 int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0];
718 for (j = 1; j < filter_len_half; ++j) {
719 sum += (input[i - j] + input[(i + j >= length ? length - 1 : i + j)]) *
720 filter[j];
721 }
722 sum >>= FILTER_BITS;
723 *optr++ = clip_pixel_highbd(sum, bd);
724 }
725 }
726 }
727
728 static void highbd_resize_multistep(const uint16_t *const input,
729 int length,
730 uint16_t *output,
731 int olength,
732 uint16_t *buf,
733 int bd) {
734 int steps;
735 if (length == olength) {
736 memcpy(output, input, sizeof(uint16_t) * length);
737 return;
738 }
739 steps = get_down2_steps(length, olength);
740
741 if (steps > 0) {
742 int s;
743 uint16_t *out = NULL;
744 uint16_t *tmpbuf = NULL;
745 uint16_t *otmp, *otmp2;
746 int filteredlength = length;
747 if (!tmpbuf) {
748 tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) * length);
749 otmp = tmpbuf;
750 } else {
751 otmp = buf;
752 }
753 otmp2 = otmp + get_down2_length(length, 1);
754 for (s = 0; s < steps; ++s) {
755 const int proj_filteredlength = get_down2_length(filteredlength, 1);
756 const uint16_t *const in = (s == 0 ? input : out);
757 if (s == steps - 1 && proj_filteredlength == olength)
758 out = output;
759 else
760 out = (s & 1 ? otmp2 : otmp);
761 if (filteredlength & 1)
762 highbd_down2_symodd(in, filteredlength, out, bd);
763 else
764 highbd_down2_symeven(in, filteredlength, out, bd);
765 filteredlength = proj_filteredlength;
766 }
767 if (filteredlength != olength) {
768 highbd_interpolate(out, filteredlength, output, olength, bd);
769 }
770 if (tmpbuf)
771 free(tmpbuf);
772 } else {
773 highbd_interpolate(input, length, output, olength, bd);
774 }
775 }
776
777 static void highbd_fill_col_to_arr(uint16_t *img, int stride, int len,
778 uint16_t *arr) {
779 int i;
780 uint16_t *iptr = img;
781 uint16_t *aptr = arr;
782 for (i = 0; i < len; ++i, iptr += stride) {
783 *aptr++ = *iptr;
784 }
785 }
786
787 static void highbd_fill_arr_to_col(uint16_t *img, int stride, int len,
788 uint16_t *arr) {
789 int i;
790 uint16_t *iptr = img;
791 uint16_t *aptr = arr;
792 for (i = 0; i < len; ++i, iptr += stride) {
793 *iptr = *aptr++;
794 }
795 }
796
797 void vp9_highbd_resize_plane(const uint8_t *const input,
798 int height,
799 int width,
800 int in_stride,
801 uint8_t *output,
802 int height2,
803 int width2,
804 int out_stride,
805 int bd) {
806 int i;
807 uint16_t *intbuf = (uint16_t *)malloc(sizeof(uint16_t) * width2 * height);
808 uint16_t *tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) *
809 (width < height ? height : width));
810 uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * (height + height2));
811 for (i = 0; i < height; ++i) {
812 highbd_resize_multistep(CONVERT_TO_SHORTPTR(input + in_stride * i), width,
813 intbuf + width2 * i, width2, tmpbuf, bd);
814 }
815 for (i = 0; i < width2; ++i) {
816 highbd_fill_col_to_arr(intbuf + i, width2, height, arrbuf);
817 highbd_resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf,
818 bd);
819 highbd_fill_arr_to_col(CONVERT_TO_SHORTPTR(output + i), out_stride, height2,
820 arrbuf + height);
821 }
822 free(intbuf);
823 free(tmpbuf);
824 free(arrbuf);
825 }
826 #endif // CONFIG_VP9_HIGHBITDEPTH
827
532 void vp9_resize_frame420(const uint8_t *const y, 828 void vp9_resize_frame420(const uint8_t *const y,
533 int y_stride, 829 int y_stride,
534 const uint8_t *const u, const uint8_t *const v, 830 const uint8_t *const u, const uint8_t *const v,
535 int uv_stride, 831 int uv_stride,
536 int height, int width, 832 int height, int width,
537 uint8_t *oy, int oy_stride, 833 uint8_t *oy, int oy_stride,
538 uint8_t *ou, uint8_t *ov, int ouv_stride, 834 uint8_t *ou, uint8_t *ov, int ouv_stride,
539 int oheight, int owidth) { 835 int oheight, int owidth) {
540 vp9_resize_plane(y, height, width, y_stride, 836 vp9_resize_plane(y, height, width, y_stride,
541 oy, oheight, owidth, oy_stride); 837 oy, oheight, owidth, oy_stride);
(...skipping 25 matching lines...) Expand all
567 uint8_t *oy, int oy_stride, 863 uint8_t *oy, int oy_stride,
568 uint8_t *ou, uint8_t *ov, int ouv_stride, 864 uint8_t *ou, uint8_t *ov, int ouv_stride,
569 int oheight, int owidth) { 865 int oheight, int owidth) {
570 vp9_resize_plane(y, height, width, y_stride, 866 vp9_resize_plane(y, height, width, y_stride,
571 oy, oheight, owidth, oy_stride); 867 oy, oheight, owidth, oy_stride);
572 vp9_resize_plane(u, height, width, uv_stride, 868 vp9_resize_plane(u, height, width, uv_stride,
573 ou, oheight, owidth, ouv_stride); 869 ou, oheight, owidth, ouv_stride);
574 vp9_resize_plane(v, height, width, uv_stride, 870 vp9_resize_plane(v, height, width, uv_stride,
575 ov, oheight, owidth, ouv_stride); 871 ov, oheight, owidth, ouv_stride);
576 } 872 }
873
874 #if CONFIG_VP9_HIGHBITDEPTH
875 void vp9_highbd_resize_frame420(const uint8_t *const y,
876 int y_stride,
877 const uint8_t *const u, const uint8_t *const v,
878 int uv_stride,
879 int height, int width,
880 uint8_t *oy, int oy_stride,
881 uint8_t *ou, uint8_t *ov, int ouv_stride,
882 int oheight, int owidth, int bd) {
883 vp9_highbd_resize_plane(y, height, width, y_stride,
884 oy, oheight, owidth, oy_stride, bd);
885 vp9_highbd_resize_plane(u, height / 2, width / 2, uv_stride,
886 ou, oheight / 2, owidth / 2, ouv_stride, bd);
887 vp9_highbd_resize_plane(v, height / 2, width / 2, uv_stride,
888 ov, oheight / 2, owidth / 2, ouv_stride, bd);
889 }
890
891 void vp9_highbd_resize_frame422(const uint8_t *const y, int y_stride,
892 const uint8_t *const u, const uint8_t *const v,
893 int uv_stride,
894 int height, int width,
895 uint8_t *oy, int oy_stride,
896 uint8_t *ou, uint8_t *ov, int ouv_stride,
897 int oheight, int owidth, int bd) {
898 vp9_highbd_resize_plane(y, height, width, y_stride,
899 oy, oheight, owidth, oy_stride, bd);
900 vp9_highbd_resize_plane(u, height, width / 2, uv_stride,
901 ou, oheight, owidth / 2, ouv_stride, bd);
902 vp9_highbd_resize_plane(v, height, width / 2, uv_stride,
903 ov, oheight, owidth / 2, ouv_stride, bd);
904 }
905
906 void vp9_highbd_resize_frame444(const uint8_t *const y, int y_stride,
907 const uint8_t *const u, const uint8_t *const v,
908 int uv_stride,
909 int height, int width,
910 uint8_t *oy, int oy_stride,
911 uint8_t *ou, uint8_t *ov, int ouv_stride,
912 int oheight, int owidth, int bd) {
913 vp9_highbd_resize_plane(y, height, width, y_stride,
914 oy, oheight, owidth, oy_stride, bd);
915 vp9_highbd_resize_plane(u, height, width, uv_stride,
916 ou, oheight, owidth, ouv_stride, bd);
917 vp9_highbd_resize_plane(v, height, width, uv_stride,
918 ov, oheight, owidth, ouv_stride, bd);
919 }
920 #endif // CONFIG_VP9_HIGHBITDEPTH
OLDNEW
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_resize.h ('k') | source/libvpx/vp9/encoder/vp9_sad.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698