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 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 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 38 static int unscaled_value(int val, const struct scale_factors *sf) { 39 (void)sf; 40 return val << SCALE_EXTRA_BITS; 41 } 42 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. 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. 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 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_q4 == 0 && subpel_y_q4 == 0 92 sf->convolve[0][0][0] = av1_convolve_2d_copy_sr; 93 // subpel_x_q4 == 0 94 sf->convolve[0][1][0] = av1_convolve_y_sr; 95 // subpel_y_q4 == 0 96 sf->convolve[1][0][0] = av1_convolve_x_sr; 97 // subpel_x_q4 != 0 && subpel_y_q4 != 0 98 sf->convolve[1][1][0] = av1_convolve_2d_sr; 99 // subpel_x_q4 == 0 && subpel_y_q4 == 0 100 sf->convolve[0][0][1] = av1_dist_wtd_convolve_2d_copy; 101 // subpel_x_q4 == 0 102 sf->convolve[0][1][1] = av1_dist_wtd_convolve_y; 103 // subpel_y_q4 == 0 104 sf->convolve[1][0][1] = av1_dist_wtd_convolve_x; 105 // subpel_x_q4 != 0 && subpel_y_q4 != 0 106 sf->convolve[1][1][1] = av1_dist_wtd_convolve_2d; 107 // AV1 High BD convolve functions 108 // Special case convolve functions should produce the same result as 109 // av1_highbd_convolve_2d. 110 // subpel_x_q4 == 0 && subpel_y_q4 == 0 111 sf->highbd_convolve[0][0][0] = av1_highbd_convolve_2d_copy_sr; 112 // subpel_x_q4 == 0 113 sf->highbd_convolve[0][1][0] = av1_highbd_convolve_y_sr; 114 // subpel_y_q4 == 0 115 sf->highbd_convolve[1][0][0] = av1_highbd_convolve_x_sr; 116 // subpel_x_q4 != 0 && subpel_y_q4 != 0 117 sf->highbd_convolve[1][1][0] = av1_highbd_convolve_2d_sr; 118 // subpel_x_q4 == 0 && subpel_y_q4 == 0 119 sf->highbd_convolve[0][0][1] = av1_highbd_dist_wtd_convolve_2d_copy; 120 // subpel_x_q4 == 0 121 sf->highbd_convolve[0][1][1] = av1_highbd_dist_wtd_convolve_y; 122 // subpel_y_q4 == 0 123 sf->highbd_convolve[1][0][1] = av1_highbd_dist_wtd_convolve_x; 124 // subpel_x_q4 != 0 && subpel_y_q4 != 0 125 sf->highbd_convolve[1][1][1] = av1_highbd_dist_wtd_convolve_2d; 126 } 127