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

Side by Side Diff: source/libvpx/vpx_scale/generic/vpxscale.c

Issue 11555023: libvpx: Add VP9 decoder. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 8 years 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
OLDNEW
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
11 11
12 /**************************************************************************** 12 /****************************************************************************
13 * 13 *
14 * Module Title : scale.c 14 * Module Title : scale.c
15 * 15 *
16 * Description : Image scaling functions. 16 * Description : Image scaling functions.
17 * 17 *
18 ***************************************************************************/ 18 ***************************************************************************/
19 19
20 /**************************************************************************** 20 /****************************************************************************
21 * Header Files 21 * Header Files
22 ****************************************************************************/ 22 ****************************************************************************/
23 #include "./vpx_rtcd.h" 23 #include "./vpx_scale_rtcd.h"
24 #include "vpx_mem/vpx_mem.h" 24 #include "vpx_mem/vpx_mem.h"
25 #include "vpx_scale/yv12config.h" 25 #include "vpx_scale/yv12config.h"
26 #include "vpx_scale/scale_mode.h"
27 26
28 typedef struct { 27 typedef struct {
29 int expanded_frame_width; 28 int expanded_frame_width;
30 int expanded_frame_height; 29 int expanded_frame_height;
31 30
32 int HScale; 31 int HScale;
33 int HRatio; 32 int HRatio;
34 int VScale; 33 int VScale;
35 int VRatio; 34 int VRatio;
36 35
37 YV12_BUFFER_CONFIG *src_yuv_config; 36 YV12_BUFFER_CONFIG *src_yuv_config;
38 YV12_BUFFER_CONFIG *dst_yuv_config; 37 YV12_BUFFER_CONFIG *dst_yuv_config;
39 38
40 } SCALE_VARS; 39 } SCALE_VARS;
41 40
42 /**************************************************************************** 41 /****************************************************************************
43 * 42 *
44 * ROUTINE : horizontal_line_copy
45 *
46 * INPUTS : None
47 *
48 *
49 * OUTPUTS : None.
50 *
51 * RETURNS : None
52 *
53 * FUNCTION : 1 to 1 scaling up for a horizontal line of pixles
54 *
55 * SPECIAL NOTES : None.
56 *
57 * ERRORS : None.
58 *
59 ****************************************************************************/
60 static
61 void horizontal_line_copy(
62 const unsigned char *source,
63 unsigned int source_width,
64 unsigned char *dest,
65 unsigned int dest_width
66 ) {
67 (void) dest_width;
68
69 duck_memcpy(dest, source, source_width);
70 }
71 /****************************************************************************
72 *
73 * ROUTINE : null_scale
74 *
75 * INPUTS : None
76 *
77 *
78 * OUTPUTS : None.
79 *
80 * RETURNS : None
81 *
82 * FUNCTION : 1 to 1 scaling up for a vertical band
83 *
84 * SPECIAL NOTES : None.
85 *
86 * ERRORS : None.
87 *
88 ****************************************************************************/
89 static
90 void null_scale(
91 unsigned char *dest,
92 unsigned int dest_pitch,
93 unsigned int dest_width
94 ) {
95 (void) dest;
96 (void) dest_pitch;
97 (void) dest_width;
98
99 return;
100 }
101
102 /****************************************************************************
103 *
104 * ROUTINE : scale1d_2t1_i 43 * ROUTINE : scale1d_2t1_i
105 * 44 *
106 * INPUTS : const unsigned char *source : Pointer to data to be scaled. 45 * INPUTS : const unsigned char *source : Pointer to data to be scaled.
107 * int source_step : Number of pixels to step on i n source. 46 * int source_step : Number of pixels to step on i n source.
108 * unsigned int source_scale : Scale for source (UNUSED). 47 * unsigned int source_scale : Scale for source (UNUSED).
109 * unsigned int source_length : Length of source (UNUSED). 48 * unsigned int source_length : Length of source (UNUSED).
110 * unsigned char *dest : Pointer to output data array. 49 * unsigned char *dest : Pointer to output data array.
111 * int dest_step : Number of pixels to step on i n destination. 50 * int dest_step : Number of pixels to step on i n destination.
112 * unsigned int dest_scale : Scale for destination (UNUSED ). 51 * unsigned int dest_scale : Scale for destination (UNUSED ).
113 * unsigned int dest_length : Length of destination. 52 * unsigned int dest_length : Length of destination.
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced); 521 temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
583 522
584 if (dw / 2 < (int)dst->uv_width) 523 if (dw / 2 < (int)dst->uv_width)
585 for (i = 0; i < dst->uv_height; i++) 524 for (i = 0; i < dst->uv_height; i++)
586 duck_memset(dst->v_buffer + i * dst->uv_stride + dw / 2 - 1, dst->v_buffer [i * dst->uv_stride + dw / 2 - 2], dst->uv_width - dw / 2 + 1); 525 duck_memset(dst->v_buffer + i * dst->uv_stride + dw / 2 - 1, dst->v_buffer [i * dst->uv_stride + dw / 2 - 2], dst->uv_width - dw / 2 + 1);
587 526
588 if (dh / 2 < (int) dst->uv_height) 527 if (dh / 2 < (int) dst->uv_height)
589 for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++) 528 for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
590 duck_memcpy(dst->v_buffer + i * dst->uv_stride, dst->v_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width); 529 duck_memcpy(dst->v_buffer + i * dst->uv_stride, dst->v_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
591 } 530 }
592 /****************************************************************************
593 *
594 * ROUTINE : any_ratio_2d_scale
595 *
596 * INPUTS : SCALE_INSTANCE *si : Pointer to post-processor instance (NOT USED).
597 * const unsigned char *source : Pointer to source image.
598 * unsigned int source_pitch : Stride of source image.
599 * unsigned int source_width : Width of source image.
600 * unsigned int source_height : Height of source image (NOT U SED).
601 * unsigned char *dest : Pointer to destination image.
602 * unsigned int dest_pitch : Stride of destination image.
603 * unsigned int dest_width : Width of destination image.
604 * unsigned int dest_height : Height of destination image.
605 *
606 * OUTPUTS : None.
607 *
608 * RETURNS : int: 1 if image scaled, 0 if image could not be scaled.
609 *
610 * FUNCTION : Scale the image with changing apect ratio.
611 *
612 * SPECIAL NOTES : This scaling is a bi-linear scaling. Need to re-work the
613 * whole function for new scaling algorithm.
614 *
615 ****************************************************************************/
616 static
617 int any_ratio_2d_scale
618 (
619 SCALE_VARS *si,
620 const unsigned char *source,
621 int source_pitch,
622 unsigned int source_width,
623 unsigned int source_height,
624 unsigned char *dest,
625 unsigned int dest_pitch,
626 unsigned int dest_width,
627 unsigned int dest_height
628 ) {
629 unsigned int i, k;
630 unsigned int src_band_height = 0;
631 unsigned int dest_band_height = 0;
632
633 /* suggested scale factors */
634 int hs = si->HScale;
635 int hr = si->HRatio;
636 int vs = si->VScale;
637 int vr = si->VRatio;
638
639 /* assume the ratios are scalable instead of should be centered */
640 int ratio_scalable = 1;
641
642 const unsigned char *source_base = ((source_pitch >= 0) ? source : (source + ( (source_height - 1) * source_pitch)));
643 const unsigned char *line_src;
644
645 void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
646 void (*vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NULL;
647 void (*last_vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NU LL;
648
649 (void) si;
650
651 /* find out the ratio for each direction */
652 switch (hr * 30 / hs) {
653 case 24:
654 /* 4-5 Scale in Width direction */
655 horiz_line_scale = vp8_horizontal_line_4_5_scale;
656 break;
657 case 22:
658 /* 3-4 Scale in Width direction */
659 horiz_line_scale = vp8_horizontal_line_3_4_scale;
660 break;
661
662 case 20:
663 /* 4-5 Scale in Width direction */
664 horiz_line_scale = vp8_horizontal_line_2_3_scale;
665 break;
666 case 18:
667 /* 3-5 Scale in Width direction */
668 horiz_line_scale = vp8_horizontal_line_3_5_scale;
669 break;
670 case 15:
671 /* 1-2 Scale in Width direction */
672 horiz_line_scale = vp8_horizontal_line_1_2_scale;
673 break;
674 case 30:
675 /* no scale in Width direction */
676 horiz_line_scale = horizontal_line_copy;
677 break;
678 default:
679 /* The ratio is not acceptable now */
680 /* throw("The ratio is not acceptable for now!"); */
681 ratio_scalable = 0;
682 break;
683 }
684
685 switch (vr * 30 / vs) {
686 case 24:
687 /* 4-5 Scale in vertical direction */
688 vert_band_scale = vp8_vertical_band_4_5_scale;
689 last_vert_band_scale = vp8_last_vertical_band_4_5_scale;
690 src_band_height = 4;
691 dest_band_height = 5;
692 break;
693 case 22:
694 /* 3-4 Scale in vertical direction */
695 vert_band_scale = vp8_vertical_band_3_4_scale;
696 last_vert_band_scale = vp8_last_vertical_band_3_4_scale;
697 src_band_height = 3;
698 dest_band_height = 4;
699 break;
700 case 20:
701 /* 2-3 Scale in vertical direction */
702 vert_band_scale = vp8_vertical_band_2_3_scale;
703 last_vert_band_scale = vp8_last_vertical_band_2_3_scale;
704 src_band_height = 2;
705 dest_band_height = 3;
706 break;
707 case 18:
708 /* 3-5 Scale in vertical direction */
709 vert_band_scale = vp8_vertical_band_3_5_scale;
710 last_vert_band_scale = vp8_last_vertical_band_3_5_scale;
711 src_band_height = 3;
712 dest_band_height = 5;
713 break;
714 case 15:
715 /* 1-2 Scale in vertical direction */
716 vert_band_scale = vp8_vertical_band_1_2_scale;
717 last_vert_band_scale = vp8_last_vertical_band_1_2_scale;
718 src_band_height = 1;
719 dest_band_height = 2;
720 break;
721 case 30:
722 /* no scale in Width direction */
723 vert_band_scale = null_scale;
724 last_vert_band_scale = null_scale;
725 src_band_height = 4;
726 dest_band_height = 4;
727 break;
728 default:
729 /* The ratio is not acceptable now */
730 /* throw("The ratio is not acceptable for now!"); */
731 ratio_scalable = 0;
732 break;
733 }
734
735 if (ratio_scalable == 0)
736 return ratio_scalable;
737
738 horiz_line_scale(source, source_width, dest, dest_width);
739
740 /* except last band */
741 for (k = 0; k < (dest_height + dest_band_height - 1) / dest_band_height - 1; k ++) {
742 /* scale one band horizontally */
743 for (i = 1; i < src_band_height; i++) {
744 /* Trap case where we could read off the base of the source buffer */
745 line_src = source + i * source_pitch;
746
747 if (line_src < source_base)
748 line_src = source_base;
749
750 horiz_line_scale(line_src, source_width,
751 dest + i * dest_pitch, dest_width);
752 }
753
754 /* first line of next band */
755 /* Trap case where we could read off the base of the source buffer */
756 line_src = source + src_band_height * source_pitch;
757
758 if (line_src < source_base)
759 line_src = source_base;
760
761 horiz_line_scale(line_src, source_width,
762 dest + dest_band_height * dest_pitch,
763 dest_width);
764
765 /* Vertical scaling is in place */
766 vert_band_scale(dest, dest_pitch, dest_width);
767
768 /* Next band... */
769 source += src_band_height * source_pitch;
770 dest += dest_band_height * dest_pitch;
771 }
772
773 /* scale one band horizontally */
774 for (i = 1; i < src_band_height; i++) {
775 /* Trap case where we could read off the base of the source buffer */
776 line_src = source + i * source_pitch;
777
778 if (line_src < source_base)
779 line_src = source_base;
780
781 horiz_line_scale(line_src, source_width,
782 dest + i * dest_pitch,
783 dest_width);
784 }
785
786 /* Vertical scaling is in place */
787 last_vert_band_scale(dest, dest_pitch, dest_width);
788
789 return ratio_scalable;
790 }
791
792 /****************************************************************************
793 *
794 * ROUTINE : any_ratio_frame_scale
795 *
796 * INPUTS : SCALE_INSTANCE *si : Pointer to post-processor instanc e (NOT USED).
797 * unsigned char *frame_buffer : Pointer to source im age.
798 * int YOffset : Offset from start of buffer to Y samples.
799 * int UVOffset : Offset from start of buffer to UV samples.
800 *
801 * OUTPUTS : None.
802 *
803 * RETURNS : int: 1 if image scaled, 0 if image could not be scaled.
804 *
805 * FUNCTION : Scale the image with changing apect ratio.
806 *
807 * SPECIAL NOTES : None.
808 *
809 ****************************************************************************/
810 static
811 int any_ratio_frame_scale(SCALE_VARS *scale_vars, int YOffset, int UVOffset) {
812 int i;
813 int ew;
814 int eh;
815
816 /* suggested scale factors */
817 int hs = scale_vars->HScale;
818 int hr = scale_vars->HRatio;
819 int vs = scale_vars->VScale;
820 int vr = scale_vars->VRatio;
821
822 int ratio_scalable = 1;
823
824 int sw = (scale_vars->expanded_frame_width * hr + hs - 1) / hs;
825 int sh = (scale_vars->expanded_frame_height * vr + vs - 1) / vs;
826 int dw = scale_vars->expanded_frame_width;
827 int dh = scale_vars->expanded_frame_height;
828 YV12_BUFFER_CONFIG *src_yuv_config = scale_vars->src_yuv_config;
829 YV12_BUFFER_CONFIG *dst_yuv_config = scale_vars->dst_yuv_config;
830
831 if (hr == 3)
832 ew = (sw + 2) / 3 * 3 * hs / hr;
833 else
834 ew = (sw + 7) / 8 * 8 * hs / hr;
835
836 if (vr == 3)
837 eh = (sh + 2) / 3 * 3 * vs / vr;
838 else
839 eh = (sh + 7) / 8 * 8 * vs / vr;
840
841 ratio_scalable = any_ratio_2d_scale(scale_vars,
842 (const unsigned char *)src_yuv_config->y_b uffer,
843 src_yuv_config->y_stride, sw, sh,
844 (unsigned char *) dst_yuv_config->y_buffer + YOffset,
845 dst_yuv_config->y_stride, dw, dh);
846
847 for (i = 0; i < eh; i++)
848 duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_strid e + dw, 0, ew - dw);
849
850 for (i = dh; i < eh; i++)
851 duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_strid e, 0, ew);
852
853 if (ratio_scalable == 0)
854 return ratio_scalable;
855
856 sw = (sw + 1) >> 1;
857 sh = (sh + 1) >> 1;
858 dw = (dw + 1) >> 1;
859 dh = (dh + 1) >> 1;
860
861 any_ratio_2d_scale(scale_vars,
862 (const unsigned char *)src_yuv_config->u_buffer,
863 src_yuv_config->y_stride / 2, sw, sh,
864 (unsigned char *)dst_yuv_config->u_buffer + UVOffset,
865 dst_yuv_config->uv_stride, dw, dh);
866
867 any_ratio_2d_scale(scale_vars,
868 (const unsigned char *)src_yuv_config->v_buffer,
869 src_yuv_config->y_stride / 2, sw, sh,
870 (unsigned char *)dst_yuv_config->v_buffer + UVOffset,
871 dst_yuv_config->uv_stride, dw, dh);
872
873 return ratio_scalable;
874 }
875
876 /****************************************************************************
877 *
878 * ROUTINE : center_image
879 *
880 * INPUTS : SCALE_INSTANCE *si : Pointer to post-processor instanc e.
881 *
882 * OUTPUTS : None.
883 *
884 * RETURNS : void
885 *
886 * FUNCTION : Centers the image without scaling in the output buffer.
887 *
888 * SPECIAL NOTES : None.
889 *
890 ****************************************************************************/
891 static void
892 center_image(YV12_BUFFER_CONFIG *src_yuv_config, YV12_BUFFER_CONFIG *dst_yuv_con fig) {
893 int i;
894 int row_offset, col_offset;
895 unsigned char *src_data_pointer;
896 unsigned char *dst_data_pointer;
897
898 /* center values */
899 row_offset = (dst_yuv_config->y_height - src_yuv_config->y_height) / 2;
900 col_offset = (dst_yuv_config->y_width - src_yuv_config->y_width) / 2;
901
902 /* Y's */
903 src_data_pointer = src_yuv_config->y_buffer;
904 dst_data_pointer = (unsigned char *)dst_yuv_config->y_buffer + (row_offset * d st_yuv_config->y_stride) + col_offset;
905
906 for (i = 0; i < src_yuv_config->y_height; i++) {
907 duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->y_width);
908 dst_data_pointer += dst_yuv_config->y_stride;
909 src_data_pointer += src_yuv_config->y_stride;
910 }
911
912 row_offset /= 2;
913 col_offset /= 2;
914
915 /* U's */
916 src_data_pointer = src_yuv_config->u_buffer;
917 dst_data_pointer = (unsigned char *)dst_yuv_config->u_buffer + (row_offset * d st_yuv_config->uv_stride) + col_offset;
918
919 for (i = 0; i < src_yuv_config->uv_height; i++) {
920 duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
921 dst_data_pointer += dst_yuv_config->uv_stride;
922 src_data_pointer += src_yuv_config->uv_stride;
923 }
924
925 /* V's */
926 src_data_pointer = src_yuv_config->v_buffer;
927 dst_data_pointer = (unsigned char *)dst_yuv_config->v_buffer + (row_offset * d st_yuv_config->uv_stride) + col_offset;
928
929 for (i = 0; i < src_yuv_config->uv_height; i++) {
930 duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
931 dst_data_pointer += dst_yuv_config->uv_stride;
932 src_data_pointer += src_yuv_config->uv_stride;
933 }
934 }
935
936 /****************************************************************************
937 *
938 * ROUTINE : scale_or_center
939 *
940 * INPUTS : SCALE_INSTANCE *si : Pointer to post-processor instanc e.
941 *
942 *
943 *
944 * OUTPUTS : None.
945 *
946 * RETURNS : void
947 *
948 * FUNCTION : Decides to scale or center image in scale buffer for blit
949 *
950 * SPECIAL NOTES : None.
951 *
952 ****************************************************************************/
953 void
954 vp8_yv12_scale_or_center
955 (
956 YV12_BUFFER_CONFIG *src_yuv_config,
957 YV12_BUFFER_CONFIG *dst_yuv_config,
958 int expanded_frame_width,
959 int expanded_frame_height,
960 int scaling_mode,
961 int HScale,
962 int HRatio,
963 int VScale,
964 int VRatio
965 ) {
966 /*if ( ppi->post_processing_level )
967 update_umvborder ( ppi, frame_buffer );*/
968
969
970 switch (scaling_mode) {
971 case SCALE_TO_FIT:
972 case MAINTAIN_ASPECT_RATIO: {
973 SCALE_VARS scale_vars;
974 /* center values */
975 #if 1
976 int row = (dst_yuv_config->y_height - expanded_frame_height) / 2;
977 int col = (dst_yuv_config->y_width - expanded_frame_width) / 2;
978 /*int YOffset = row * dst_yuv_config->y_width + col;
979 int UVOffset = (row>>1) * dst_yuv_config->uv_width + (col>>1);*/
980 int YOffset = row * dst_yuv_config->y_stride + col;
981 int UVOffset = (row >> 1) * dst_yuv_config->uv_stride + (col >> 1);
982 #else
983 int row = (src_yuv_config->y_height - expanded_frame_height) / 2;
984 int col = (src_yuv_config->y_width - expanded_frame_width) / 2;
985 int YOffset = row * src_yuv_config->y_width + col;
986 int UVOffset = (row >> 1) * src_yuv_config->uv_width + (col >> 1);
987 #endif
988
989 scale_vars.dst_yuv_config = dst_yuv_config;
990 scale_vars.src_yuv_config = src_yuv_config;
991 scale_vars.HScale = HScale;
992 scale_vars.HRatio = HRatio;
993 scale_vars.VScale = VScale;
994 scale_vars.VRatio = VRatio;
995 scale_vars.expanded_frame_width = expanded_frame_width;
996 scale_vars.expanded_frame_height = expanded_frame_height;
997
998 /* perform center and scale */
999 any_ratio_frame_scale(&scale_vars, YOffset, UVOffset);
1000
1001 break;
1002 }
1003 case CENTER:
1004 center_image(src_yuv_config, dst_yuv_config);
1005 break;
1006
1007 default:
1008 break;
1009 }
1010 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698