1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include "config/aom_dsp_rtcd.h"
13 #include "config/av1_rtcd.h"
14
15 #include "av1/common/filter.h"
16 #include "av1/common/scale.h"
17 #include "aom_dsp/aom_filter.h"
18
19 // Note: Expect val to be in q4 precision
scaled_x(int val,const struct scale_factors * sf)20 static INLINE int scaled_x(int val, const struct scale_factors *sf) {
21 const int off =
22 (sf->x_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
23 const int64_t tval = (int64_t)val * sf->x_scale_fp + off;
24 return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
25 REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
26 }
27
28 // Note: Expect val to be in q4 precision
scaled_y(int val,const struct scale_factors * sf)29 static INLINE int scaled_y(int val, const struct scale_factors *sf) {
30 const int off =
31 (sf->y_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
32 const int64_t tval = (int64_t)val * sf->y_scale_fp + off;
33 return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
34 REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
35 }
36
37 // Note: Expect val to be in q4 precision
unscaled_value(int val,const struct scale_factors * sf)38 static int unscaled_value(int val, const struct scale_factors *sf) {
39 (void)sf;
40 return val * (1 << SCALE_EXTRA_BITS);
41 }
42
get_fixed_point_scale_factor(int other_size,int this_size)43 static int get_fixed_point_scale_factor(int other_size, int this_size) {
44 // Calculate scaling factor once for each reference frame
45 // and use fixed point scaling factors in decoding and encoding routines.
46 // Hardware implementations can calculate scale factor in device driver
47 // and use multiplication and shifting on hardware instead of division.
48 return ((other_size << REF_SCALE_SHIFT) + this_size / 2) / this_size;
49 }
50
51 // Given the fixed point scale, calculate coarse point scale.
fixed_point_scale_to_coarse_point_scale(int scale_fp)52 static int fixed_point_scale_to_coarse_point_scale(int scale_fp) {
53 return ROUND_POWER_OF_TWO(scale_fp, REF_SCALE_SHIFT - SCALE_SUBPEL_BITS);
54 }
55
56 // Note: x and y are integer precision, mvq4 is q4 precision.
av1_scale_mv(const MV * mvq4,int x,int y,const struct scale_factors * sf)57 MV32 av1_scale_mv(const MV *mvq4, int x, int y,
58 const struct scale_factors *sf) {
59 const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf);
60 const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf);
61 const MV32 res = { scaled_y((y << SUBPEL_BITS) + mvq4->row, sf) - y_off_q4,
62 scaled_x((x << SUBPEL_BITS) + mvq4->col, sf) - x_off_q4 };
63 return res;
64 }
65
av1_setup_scale_factors_for_frame(struct scale_factors * sf,int other_w,int other_h,int this_w,int this_h)66 void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
67 int other_h, int this_w, int this_h) {
68 if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) {
69 sf->x_scale_fp = REF_INVALID_SCALE;
70 sf->y_scale_fp = REF_INVALID_SCALE;
71 return;
72 }
73
74 sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
75 sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
76
77 sf->x_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->x_scale_fp);
78 sf->y_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->y_scale_fp);
79
80 if (av1_is_scaled(sf)) {
81 sf->scale_value_x = scaled_x;
82 sf->scale_value_y = scaled_y;
83 } else {
84 sf->scale_value_x = unscaled_value;
85 sf->scale_value_y = unscaled_value;
86 }
87
88 // AV1 convolve functions
89 // Special case convolve functions should produce the same result as
90 // av1_convolve_2d.
91 // subpel_x_qn == 0 && subpel_y_qn == 0
92 sf->convolve[0][0][0] = av1_convolve_2d_copy_sr;
93 // subpel_x_qn == 0
94 sf->convolve[0][1][0] = av1_convolve_y_sr;
95 // subpel_y_qn == 0
96 sf->convolve[1][0][0] = av1_convolve_x_sr;
97 // subpel_x_qn != 0 && subpel_y_qn != 0
98 sf->convolve[1][1][0] = av1_convolve_2d_sr;
99 // subpel_x_qn == 0 && subpel_y_qn == 0
100 sf->convolve[0][0][1] = av1_dist_wtd_convolve_2d_copy;
101 // subpel_x_qn == 0
102 sf->convolve[0][1][1] = av1_dist_wtd_convolve_y;
103 // subpel_y_qn == 0
104 sf->convolve[1][0][1] = av1_dist_wtd_convolve_x;
105 // subpel_x_qn != 0 && subpel_y_qn != 0
106 sf->convolve[1][1][1] = av1_dist_wtd_convolve_2d;
107 #if CONFIG_AV1_HIGHBITDEPTH
108 // AV1 High BD convolve functions
109 // Special case convolve functions should produce the same result as
110 // av1_highbd_convolve_2d.
111 // subpel_x_qn == 0 && subpel_y_qn == 0
112 sf->highbd_convolve[0][0][0] = av1_highbd_convolve_2d_copy_sr;
113 // subpel_x_qn == 0
114 sf->highbd_convolve[0][1][0] = av1_highbd_convolve_y_sr;
115 // subpel_y_qn == 0
116 sf->highbd_convolve[1][0][0] = av1_highbd_convolve_x_sr;
117 // subpel_x_qn != 0 && subpel_y_qn != 0
118 sf->highbd_convolve[1][1][0] = av1_highbd_convolve_2d_sr;
119 // subpel_x_qn == 0 && subpel_y_qn == 0
120 sf->highbd_convolve[0][0][1] = av1_highbd_dist_wtd_convolve_2d_copy;
121 // subpel_x_qn == 0
122 sf->highbd_convolve[0][1][1] = av1_highbd_dist_wtd_convolve_y;
123 // subpel_y_qn == 0
124 sf->highbd_convolve[1][0][1] = av1_highbd_dist_wtd_convolve_x;
125 // subpel_x_qn != 0 && subpel_y_qn != 0
126 sf->highbd_convolve[1][1][1] = av1_highbd_dist_wtd_convolve_2d;
127 #endif
128 }
129