LCOV - code coverage report
Current view: top level - media/libvpx/libvpx/vp9/common - vp9_scale.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 60 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) 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             : 
      11             : #include "./vpx_dsp_rtcd.h"
      12             : #include "vp9/common/vp9_filter.h"
      13             : #include "vp9/common/vp9_scale.h"
      14             : #include "vpx_dsp/vpx_filter.h"
      15             : 
      16           0 : static INLINE int scaled_x(int val, const struct scale_factors *sf) {
      17           0 :   return (int)((int64_t)val * sf->x_scale_fp >> REF_SCALE_SHIFT);
      18             : }
      19             : 
      20           0 : static INLINE int scaled_y(int val, const struct scale_factors *sf) {
      21           0 :   return (int)((int64_t)val * sf->y_scale_fp >> REF_SCALE_SHIFT);
      22             : }
      23             : 
      24           0 : static int unscaled_value(int val, const struct scale_factors *sf) {
      25             :   (void)sf;
      26           0 :   return val;
      27             : }
      28             : 
      29           0 : static int get_fixed_point_scale_factor(int other_size, int this_size) {
      30             :   // Calculate scaling factor once for each reference frame
      31             :   // and use fixed point scaling factors in decoding and encoding routines.
      32             :   // Hardware implementations can calculate scale factor in device driver
      33             :   // and use multiplication and shifting on hardware instead of division.
      34           0 :   return (other_size << REF_SCALE_SHIFT) / this_size;
      35             : }
      36             : 
      37           0 : MV32 vp9_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) {
      38           0 :   const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SUBPEL_MASK;
      39           0 :   const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SUBPEL_MASK;
      40           0 :   const MV32 res = { scaled_y(mv->row, sf) + y_off_q4,
      41           0 :                      scaled_x(mv->col, sf) + x_off_q4 };
      42           0 :   return res;
      43             : }
      44             : 
      45             : #if CONFIG_VP9_HIGHBITDEPTH
      46             : void vp9_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
      47             :                                        int other_h, int this_w, int this_h,
      48             :                                        int use_highbd) {
      49             : #else
      50           0 : void vp9_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
      51             :                                        int other_h, int this_w, int this_h) {
      52             : #endif
      53           0 :   if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) {
      54           0 :     sf->x_scale_fp = REF_INVALID_SCALE;
      55           0 :     sf->y_scale_fp = REF_INVALID_SCALE;
      56           0 :     return;
      57             :   }
      58             : 
      59           0 :   sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
      60           0 :   sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
      61           0 :   sf->x_step_q4 = scaled_x(16, sf);
      62           0 :   sf->y_step_q4 = scaled_y(16, sf);
      63             : 
      64           0 :   if (vp9_is_scaled(sf)) {
      65           0 :     sf->scale_value_x = scaled_x;
      66           0 :     sf->scale_value_y = scaled_y;
      67             :   } else {
      68           0 :     sf->scale_value_x = unscaled_value;
      69           0 :     sf->scale_value_y = unscaled_value;
      70             :   }
      71             : 
      72             :   // TODO(agrange): Investigate the best choice of functions to use here
      73             :   // for EIGHTTAP_SMOOTH. Since it is not interpolating, need to choose what
      74             :   // to do at full-pel offsets. The current selection, where the filter is
      75             :   // applied in one direction only, and not at all for 0,0, seems to give the
      76             :   // best quality, but it may be worth trying an additional mode that does
      77             :   // do the filtering on full-pel.
      78             : 
      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] = vpx_convolve_copy;
      83           0 :       sf->predict[0][0][1] = vpx_convolve_avg;
      84           0 :       sf->predict[0][1][0] = vpx_convolve8_vert;
      85           0 :       sf->predict[0][1][1] = vpx_convolve8_avg_vert;
      86           0 :       sf->predict[1][0][0] = vpx_convolve8_horiz;
      87           0 :       sf->predict[1][0][1] = vpx_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] = vpx_scaled_vert;
      91           0 :       sf->predict[0][0][1] = vpx_scaled_avg_vert;
      92           0 :       sf->predict[0][1][0] = vpx_scaled_vert;
      93           0 :       sf->predict[0][1][1] = vpx_scaled_avg_vert;
      94           0 :       sf->predict[1][0][0] = vpx_scaled_2d;
      95           0 :       sf->predict[1][0][1] = vpx_scaled_avg_2d;
      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] = vpx_scaled_horiz;
     101           0 :       sf->predict[0][0][1] = vpx_scaled_avg_horiz;
     102           0 :       sf->predict[0][1][0] = vpx_scaled_2d;
     103           0 :       sf->predict[0][1][1] = vpx_scaled_avg_2d;
     104           0 :       sf->predict[1][0][0] = vpx_scaled_horiz;
     105           0 :       sf->predict[1][0][1] = vpx_scaled_avg_horiz;
     106             :     } else {
     107             :       // Must always scale in both directions.
     108           0 :       sf->predict[0][0][0] = vpx_scaled_2d;
     109           0 :       sf->predict[0][0][1] = vpx_scaled_avg_2d;
     110           0 :       sf->predict[0][1][0] = vpx_scaled_2d;
     111           0 :       sf->predict[0][1][1] = vpx_scaled_avg_2d;
     112           0 :       sf->predict[1][0][0] = vpx_scaled_2d;
     113           0 :       sf->predict[1][0][1] = vpx_scaled_avg_2d;
     114             :     }
     115             :   }
     116             : 
     117             :   // 2D subpel motion always gets filtered in both directions
     118             : 
     119           0 :   if ((sf->x_step_q4 != 16) || (sf->y_step_q4 != 16)) {
     120           0 :     sf->predict[1][1][0] = vpx_scaled_2d;
     121           0 :     sf->predict[1][1][1] = vpx_scaled_avg_2d;
     122             :   } else {
     123           0 :     sf->predict[1][1][0] = vpx_convolve8;
     124           0 :     sf->predict[1][1][1] = vpx_convolve8_avg;
     125             :   }
     126             : 
     127             : #if CONFIG_VP9_HIGHBITDEPTH
     128             :   if (use_highbd) {
     129             :     if (sf->x_step_q4 == 16) {
     130             :       if (sf->y_step_q4 == 16) {
     131             :         // No scaling in either direction.
     132             :         sf->highbd_predict[0][0][0] = vpx_highbd_convolve_copy;
     133             :         sf->highbd_predict[0][0][1] = vpx_highbd_convolve_avg;
     134             :         sf->highbd_predict[0][1][0] = vpx_highbd_convolve8_vert;
     135             :         sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg_vert;
     136             :         sf->highbd_predict[1][0][0] = vpx_highbd_convolve8_horiz;
     137             :         sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg_horiz;
     138             :       } else {
     139             :         // No scaling in x direction. Must always scale in the y direction.
     140             :         sf->highbd_predict[0][0][0] = vpx_highbd_convolve8_vert;
     141             :         sf->highbd_predict[0][0][1] = vpx_highbd_convolve8_avg_vert;
     142             :         sf->highbd_predict[0][1][0] = vpx_highbd_convolve8_vert;
     143             :         sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg_vert;
     144             :         sf->highbd_predict[1][0][0] = vpx_highbd_convolve8;
     145             :         sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg;
     146             :       }
     147             :     } else {
     148             :       if (sf->y_step_q4 == 16) {
     149             :         // No scaling in the y direction. Must always scale in the x direction.
     150             :         sf->highbd_predict[0][0][0] = vpx_highbd_convolve8_horiz;
     151             :         sf->highbd_predict[0][0][1] = vpx_highbd_convolve8_avg_horiz;
     152             :         sf->highbd_predict[0][1][0] = vpx_highbd_convolve8;
     153             :         sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg;
     154             :         sf->highbd_predict[1][0][0] = vpx_highbd_convolve8_horiz;
     155             :         sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg_horiz;
     156             :       } else {
     157             :         // Must always scale in both directions.
     158             :         sf->highbd_predict[0][0][0] = vpx_highbd_convolve8;
     159             :         sf->highbd_predict[0][0][1] = vpx_highbd_convolve8_avg;
     160             :         sf->highbd_predict[0][1][0] = vpx_highbd_convolve8;
     161             :         sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg;
     162             :         sf->highbd_predict[1][0][0] = vpx_highbd_convolve8;
     163             :         sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg;
     164             :       }
     165             :     }
     166             :     // 2D subpel motion always gets filtered in both directions.
     167             :     sf->highbd_predict[1][1][0] = vpx_highbd_convolve8;
     168             :     sf->highbd_predict[1][1][1] = vpx_highbd_convolve8_avg;
     169             :   }
     170             : #endif
     171             : }

Generated by: LCOV version 1.13