vp9_scale.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
  3. *
  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
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include "./vp9_rtcd.h"
  11. #include "vp9/common/vp9_filter.h"
  12. #include "vp9/common/vp9_scale.h"
  13. static INLINE int scaled_x(int val, const struct scale_factors *sf) {
  14. return (int)((int64_t)val * sf->x_scale_fp >> REF_SCALE_SHIFT);
  15. }
  16. static INLINE int scaled_y(int val, const struct scale_factors *sf) {
  17. return (int)((int64_t)val * sf->y_scale_fp >> REF_SCALE_SHIFT);
  18. }
  19. static int unscaled_value(int val, const struct scale_factors *sf) {
  20. (void) sf;
  21. return val;
  22. }
  23. static int get_fixed_point_scale_factor(int other_size, int this_size) {
  24. // Calculate scaling factor once for each reference frame
  25. // and use fixed point scaling factors in decoding and encoding routines.
  26. // Hardware implementations can calculate scale factor in device driver
  27. // and use multiplication and shifting on hardware instead of division.
  28. return (other_size << REF_SCALE_SHIFT) / this_size;
  29. }
  30. MV32 vp9_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) {
  31. const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SUBPEL_MASK;
  32. const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SUBPEL_MASK;
  33. const MV32 res = {
  34. scaled_y(mv->row, sf) + y_off_q4,
  35. scaled_x(mv->col, sf) + x_off_q4
  36. };
  37. return res;
  38. }
  39. #if CONFIG_VP9_HIGHBITDEPTH
  40. void vp9_setup_scale_factors_for_frame(struct scale_factors *sf,
  41. int other_w, int other_h,
  42. int this_w, int this_h,
  43. int use_highbd) {
  44. #else
  45. void vp9_setup_scale_factors_for_frame(struct scale_factors *sf,
  46. int other_w, int other_h,
  47. int this_w, int this_h) {
  48. #endif
  49. if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) {
  50. sf->x_scale_fp = REF_INVALID_SCALE;
  51. sf->y_scale_fp = REF_INVALID_SCALE;
  52. return;
  53. }
  54. sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
  55. sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
  56. sf->x_step_q4 = scaled_x(16, sf);
  57. sf->y_step_q4 = scaled_y(16, sf);
  58. if (vp9_is_scaled(sf)) {
  59. sf->scale_value_x = scaled_x;
  60. sf->scale_value_y = scaled_y;
  61. } else {
  62. sf->scale_value_x = unscaled_value;
  63. sf->scale_value_y = unscaled_value;
  64. }
  65. // TODO(agrange): Investigate the best choice of functions to use here
  66. // for EIGHTTAP_SMOOTH. Since it is not interpolating, need to choose what
  67. // to do at full-pel offsets. The current selection, where the filter is
  68. // applied in one direction only, and not at all for 0,0, seems to give the
  69. // best quality, but it may be worth trying an additional mode that does
  70. // do the filtering on full-pel.
  71. if (sf->x_step_q4 == 16) {
  72. if (sf->y_step_q4 == 16) {
  73. // No scaling in either direction.
  74. sf->predict[0][0][0] = vp9_convolve_copy;
  75. sf->predict[0][0][1] = vp9_convolve_avg;
  76. sf->predict[0][1][0] = vp9_convolve8_vert;
  77. sf->predict[0][1][1] = vp9_convolve8_avg_vert;
  78. sf->predict[1][0][0] = vp9_convolve8_horiz;
  79. sf->predict[1][0][1] = vp9_convolve8_avg_horiz;
  80. } else {
  81. // No scaling in x direction. Must always scale in the y direction.
  82. sf->predict[0][0][0] = vp9_convolve8_vert;
  83. sf->predict[0][0][1] = vp9_convolve8_avg_vert;
  84. sf->predict[0][1][0] = vp9_convolve8_vert;
  85. sf->predict[0][1][1] = vp9_convolve8_avg_vert;
  86. sf->predict[1][0][0] = vp9_convolve8;
  87. sf->predict[1][0][1] = vp9_convolve8_avg;
  88. }
  89. } else {
  90. if (sf->y_step_q4 == 16) {
  91. // No scaling in the y direction. Must always scale in the x direction.
  92. sf->predict[0][0][0] = vp9_convolve8_horiz;
  93. sf->predict[0][0][1] = vp9_convolve8_avg_horiz;
  94. sf->predict[0][1][0] = vp9_convolve8;
  95. sf->predict[0][1][1] = vp9_convolve8_avg;
  96. sf->predict[1][0][0] = vp9_convolve8_horiz;
  97. sf->predict[1][0][1] = vp9_convolve8_avg_horiz;
  98. } else {
  99. // Must always scale in both directions.
  100. sf->predict[0][0][0] = vp9_convolve8;
  101. sf->predict[0][0][1] = vp9_convolve8_avg;
  102. sf->predict[0][1][0] = vp9_convolve8;
  103. sf->predict[0][1][1] = vp9_convolve8_avg;
  104. sf->predict[1][0][0] = vp9_convolve8;
  105. sf->predict[1][0][1] = vp9_convolve8_avg;
  106. }
  107. }
  108. // 2D subpel motion always gets filtered in both directions
  109. sf->predict[1][1][0] = vp9_convolve8;
  110. sf->predict[1][1][1] = vp9_convolve8_avg;
  111. #if CONFIG_VP9_HIGHBITDEPTH
  112. if (use_highbd) {
  113. if (sf->x_step_q4 == 16) {
  114. if (sf->y_step_q4 == 16) {
  115. // No scaling in either direction.
  116. sf->highbd_predict[0][0][0] = vp9_highbd_convolve_copy;
  117. sf->highbd_predict[0][0][1] = vp9_highbd_convolve_avg;
  118. sf->highbd_predict[0][1][0] = vp9_highbd_convolve8_vert;
  119. sf->highbd_predict[0][1][1] = vp9_highbd_convolve8_avg_vert;
  120. sf->highbd_predict[1][0][0] = vp9_highbd_convolve8_horiz;
  121. sf->highbd_predict[1][0][1] = vp9_highbd_convolve8_avg_horiz;
  122. } else {
  123. // No scaling in x direction. Must always scale in the y direction.
  124. sf->highbd_predict[0][0][0] = vp9_highbd_convolve8_vert;
  125. sf->highbd_predict[0][0][1] = vp9_highbd_convolve8_avg_vert;
  126. sf->highbd_predict[0][1][0] = vp9_highbd_convolve8_vert;
  127. sf->highbd_predict[0][1][1] = vp9_highbd_convolve8_avg_vert;
  128. sf->highbd_predict[1][0][0] = vp9_highbd_convolve8;
  129. sf->highbd_predict[1][0][1] = vp9_highbd_convolve8_avg;
  130. }
  131. } else {
  132. if (sf->y_step_q4 == 16) {
  133. // No scaling in the y direction. Must always scale in the x direction.
  134. sf->highbd_predict[0][0][0] = vp9_highbd_convolve8_horiz;
  135. sf->highbd_predict[0][0][1] = vp9_highbd_convolve8_avg_horiz;
  136. sf->highbd_predict[0][1][0] = vp9_highbd_convolve8;
  137. sf->highbd_predict[0][1][1] = vp9_highbd_convolve8_avg;
  138. sf->highbd_predict[1][0][0] = vp9_highbd_convolve8_horiz;
  139. sf->highbd_predict[1][0][1] = vp9_highbd_convolve8_avg_horiz;
  140. } else {
  141. // Must always scale in both directions.
  142. sf->highbd_predict[0][0][0] = vp9_highbd_convolve8;
  143. sf->highbd_predict[0][0][1] = vp9_highbd_convolve8_avg;
  144. sf->highbd_predict[0][1][0] = vp9_highbd_convolve8;
  145. sf->highbd_predict[0][1][1] = vp9_highbd_convolve8_avg;
  146. sf->highbd_predict[1][0][0] = vp9_highbd_convolve8;
  147. sf->highbd_predict[1][0][1] = vp9_highbd_convolve8_avg;
  148. }
  149. }
  150. // 2D subpel motion always gets filtered in both directions.
  151. sf->highbd_predict[1][1][0] = vp9_highbd_convolve8;
  152. sf->highbd_predict[1][1][1] = vp9_highbd_convolve8_avg;
  153. }
  154. #endif
  155. }