LCOV - code coverage report
Current view: top level - third_party/aom/av1/common - scale.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 87 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "./aom_dsp_rtcd.h"
      13             : #include "av1/common/filter.h"
      14             : #include "av1/common/scale.h"
      15             : #include "aom_dsp/aom_filter.h"
      16             : 
      17           0 : static INLINE int scaled_x(int val, const struct scale_factors *sf) {
      18           0 :   return (int)((int64_t)val * sf->x_scale_fp >> REF_SCALE_SHIFT);
      19             : }
      20             : 
      21           0 : static INLINE int scaled_y(int val, const struct scale_factors *sf) {
      22           0 :   return (int)((int64_t)val * sf->y_scale_fp >> REF_SCALE_SHIFT);
      23             : }
      24             : 
      25           0 : static int unscaled_value(int val, const struct scale_factors *sf) {
      26             :   (void)sf;
      27           0 :   return val;
      28             : }
      29             : 
      30           0 : static int get_fixed_point_scale_factor(int other_size, int this_size) {
      31             :   // Calculate scaling factor once for each reference frame
      32             :   // and use fixed point scaling factors in decoding and encoding routines.
      33             :   // Hardware implementations can calculate scale factor in device driver
      34             :   // and use multiplication and shifting on hardware instead of division.
      35           0 :   return (other_size << REF_SCALE_SHIFT) / this_size;
      36             : }
      37             : 
      38           0 : MV32 av1_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) {
      39           0 :   const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SUBPEL_MASK;
      40           0 :   const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SUBPEL_MASK;
      41           0 :   const MV32 res = { scaled_y(mv->row, sf) + y_off_q4,
      42           0 :                      scaled_x(mv->col, sf) + x_off_q4 };
      43           0 :   return res;
      44             : }
      45             : 
      46             : #if CONFIG_HIGHBITDEPTH
      47           0 : void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
      48             :                                        int other_h, int this_w, int this_h,
      49             :                                        int use_highbd) {
      50             : #else
      51             : void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
      52             :                                        int other_h, int this_w, int this_h) {
      53             : #endif
      54           0 :   if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) {
      55           0 :     sf->x_scale_fp = REF_INVALID_SCALE;
      56           0 :     sf->y_scale_fp = REF_INVALID_SCALE;
      57           0 :     return;
      58             :   }
      59             : 
      60           0 :   sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
      61           0 :   sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
      62           0 :   sf->x_step_q4 = scaled_x(16, sf);
      63           0 :   sf->y_step_q4 = scaled_y(16, sf);
      64             : 
      65           0 :   if (av1_is_scaled(sf)) {
      66           0 :     sf->scale_value_x = scaled_x;
      67           0 :     sf->scale_value_y = scaled_y;
      68             :   } else {
      69           0 :     sf->scale_value_x = unscaled_value;
      70           0 :     sf->scale_value_y = unscaled_value;
      71             :   }
      72             : 
      73             :   // TODO(agrange): Investigate the best choice of functions to use here
      74             :   // for EIGHTTAP_SMOOTH. Since it is not interpolating, need to choose what
      75             :   // to do at full-pel offsets. The current selection, where the filter is
      76             :   // applied in one direction only, and not at all for 0,0, seems to give the
      77             :   // best quality, but it may be worth trying an additional mode that does
      78             :   // do the filtering on full-pel.
      79           0 :   if (sf->x_step_q4 == 16) {
      80           0 :     if (sf->y_step_q4 == 16) {
      81             :       // No scaling in either direction.
      82           0 :       sf->predict[0][0][0] = aom_convolve_copy;
      83           0 :       sf->predict[0][0][1] = aom_convolve_avg;
      84           0 :       sf->predict[0][1][0] = aom_convolve8_vert;
      85           0 :       sf->predict[0][1][1] = aom_convolve8_avg_vert;
      86           0 :       sf->predict[1][0][0] = aom_convolve8_horiz;
      87           0 :       sf->predict[1][0][1] = aom_convolve8_avg_horiz;
      88             :     } else {
      89             :       // No scaling in x direction. Must always scale in the y direction.
      90           0 :       sf->predict[0][0][0] = aom_convolve8_vert;
      91           0 :       sf->predict[0][0][1] = aom_convolve8_avg_vert;
      92           0 :       sf->predict[0][1][0] = aom_convolve8_vert;
      93           0 :       sf->predict[0][1][1] = aom_convolve8_avg_vert;
      94           0 :       sf->predict[1][0][0] = aom_convolve8;
      95           0 :       sf->predict[1][0][1] = aom_convolve8_avg;
      96             :     }
      97             :   } else {
      98           0 :     if (sf->y_step_q4 == 16) {
      99             :       // No scaling in the y direction. Must always scale in the x direction.
     100           0 :       sf->predict[0][0][0] = aom_convolve8_horiz;
     101           0 :       sf->predict[0][0][1] = aom_convolve8_avg_horiz;
     102           0 :       sf->predict[0][1][0] = aom_convolve8;
     103           0 :       sf->predict[0][1][1] = aom_convolve8_avg;
     104           0 :       sf->predict[1][0][0] = aom_convolve8_horiz;
     105           0 :       sf->predict[1][0][1] = aom_convolve8_avg_horiz;
     106             :     } else {
     107             :       // Must always scale in both directions.
     108           0 :       sf->predict[0][0][0] = aom_convolve8;
     109           0 :       sf->predict[0][0][1] = aom_convolve8_avg;
     110           0 :       sf->predict[0][1][0] = aom_convolve8;
     111           0 :       sf->predict[0][1][1] = aom_convolve8_avg;
     112           0 :       sf->predict[1][0][0] = aom_convolve8;
     113           0 :       sf->predict[1][0][1] = aom_convolve8_avg;
     114             :     }
     115             :   }
     116             :   // 2D subpel motion always gets filtered in both directions
     117           0 :   sf->predict[1][1][0] = aom_convolve8;
     118           0 :   sf->predict[1][1][1] = aom_convolve8_avg;
     119             : 
     120             : #if CONFIG_HIGHBITDEPTH
     121           0 :   if (use_highbd) {
     122           0 :     if (sf->x_step_q4 == 16) {
     123           0 :       if (sf->y_step_q4 == 16) {
     124             :         // No scaling in either direction.
     125           0 :         sf->highbd_predict[0][0][0] = aom_highbd_convolve_copy;
     126           0 :         sf->highbd_predict[0][0][1] = aom_highbd_convolve_avg;
     127           0 :         sf->highbd_predict[0][1][0] = aom_highbd_convolve8_vert;
     128           0 :         sf->highbd_predict[0][1][1] = aom_highbd_convolve8_avg_vert;
     129           0 :         sf->highbd_predict[1][0][0] = aom_highbd_convolve8_horiz;
     130           0 :         sf->highbd_predict[1][0][1] = aom_highbd_convolve8_avg_horiz;
     131             :       } else {
     132             :         // No scaling in x direction. Must always scale in the y direction.
     133           0 :         sf->highbd_predict[0][0][0] = aom_highbd_convolve8_vert;
     134           0 :         sf->highbd_predict[0][0][1] = aom_highbd_convolve8_avg_vert;
     135           0 :         sf->highbd_predict[0][1][0] = aom_highbd_convolve8_vert;
     136           0 :         sf->highbd_predict[0][1][1] = aom_highbd_convolve8_avg_vert;
     137           0 :         sf->highbd_predict[1][0][0] = aom_highbd_convolve8;
     138           0 :         sf->highbd_predict[1][0][1] = aom_highbd_convolve8_avg;
     139             :       }
     140             :     } else {
     141           0 :       if (sf->y_step_q4 == 16) {
     142             :         // No scaling in the y direction. Must always scale in the x direction.
     143           0 :         sf->highbd_predict[0][0][0] = aom_highbd_convolve8_horiz;
     144           0 :         sf->highbd_predict[0][0][1] = aom_highbd_convolve8_avg_horiz;
     145           0 :         sf->highbd_predict[0][1][0] = aom_highbd_convolve8;
     146           0 :         sf->highbd_predict[0][1][1] = aom_highbd_convolve8_avg;
     147           0 :         sf->highbd_predict[1][0][0] = aom_highbd_convolve8_horiz;
     148           0 :         sf->highbd_predict[1][0][1] = aom_highbd_convolve8_avg_horiz;
     149             :       } else {
     150             :         // Must always scale in both directions.
     151           0 :         sf->highbd_predict[0][0][0] = aom_highbd_convolve8;
     152           0 :         sf->highbd_predict[0][0][1] = aom_highbd_convolve8_avg;
     153           0 :         sf->highbd_predict[0][1][0] = aom_highbd_convolve8;
     154           0 :         sf->highbd_predict[0][1][1] = aom_highbd_convolve8_avg;
     155           0 :         sf->highbd_predict[1][0][0] = aom_highbd_convolve8;
     156           0 :         sf->highbd_predict[1][0][1] = aom_highbd_convolve8_avg;
     157             :       }
     158             :     }
     159             :     // 2D subpel motion always gets filtered in both directions.
     160           0 :     sf->highbd_predict[1][1][0] = aom_highbd_convolve8;
     161           0 :     sf->highbd_predict[1][1][1] = aom_highbd_convolve8_avg;
     162             :   }
     163             : #endif  // CONFIG_HIGHBITDEPTH
     164             : }

Generated by: LCOV version 1.13