Home | History | Annotate | Download | only in encoder
      1 /*
      2  *  Copyright (c) 2010 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 
     12 #include <limits.h>
     13 #include "vpx_config.h"
     14 #include "onyx_int.h"
     15 #include "mr_dissim.h"
     16 #include "vpx_dsp/vpx_dsp_common.h"
     17 #include "vpx_mem/vpx_mem.h"
     18 #include "rdopt.h"
     19 #include "vp8/common/common.h"
     20 
     21 void vp8_cal_low_res_mb_cols(VP8_COMP *cpi)
     22 {
     23     int low_res_w;
     24 
     25     /* Support arbitrary down-sampling factor */
     26     unsigned int iw = cpi->oxcf.Width*cpi->oxcf.mr_down_sampling_factor.den
     27                       + cpi->oxcf.mr_down_sampling_factor.num - 1;
     28 
     29     low_res_w = iw/cpi->oxcf.mr_down_sampling_factor.num;
     30     cpi->mr_low_res_mb_cols = ((low_res_w + 15) >> 4);
     31 }
     32 
     33 #define GET_MV(x)    \
     34 if(x->mbmi.ref_frame !=INTRA_FRAME)   \
     35 {   \
     36     mvx[cnt] = x->mbmi.mv.as_mv.row;  \
     37     mvy[cnt] = x->mbmi.mv.as_mv.col;  \
     38     cnt++;    \
     39 }
     40 
     41 #define GET_MV_SIGN(x)    \
     42 if(x->mbmi.ref_frame !=INTRA_FRAME)   \
     43 {   \
     44     mvx[cnt] = x->mbmi.mv.as_mv.row;  \
     45     mvy[cnt] = x->mbmi.mv.as_mv.col;  \
     46     if (cm->ref_frame_sign_bias[x->mbmi.ref_frame]  \
     47         != cm->ref_frame_sign_bias[tmp->mbmi.ref_frame])  \
     48     {  \
     49         mvx[cnt] *= -1;   \
     50         mvy[cnt] *= -1;   \
     51     }  \
     52     cnt++;  \
     53 }
     54 
     55 void vp8_cal_dissimilarity(VP8_COMP *cpi)
     56 {
     57     VP8_COMMON *cm = &cpi->common;
     58     int i;
     59 
     60     /* Note: The first row & first column in mip are outside the frame, which
     61      * were initialized to all 0.(ref_frame, mode, mv...)
     62      * Their ref_frame = 0 means they won't be counted in the following
     63      * calculation.
     64      */
     65     if (cpi->oxcf.mr_total_resolutions >1
     66         && cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1))
     67     {
     68         /* Store info for show/no-show frames for supporting alt_ref.
     69          * If parent frame is alt_ref, child has one too.
     70          */
     71         LOWER_RES_FRAME_INFO* store_info
     72                       = (LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info;
     73 
     74         store_info->frame_type = cm->frame_type;
     75 
     76         if(cm->frame_type != KEY_FRAME)
     77         {
     78             store_info->is_frame_dropped = 0;
     79             for (i = 1; i < MAX_REF_FRAMES; i++)
     80                 store_info->low_res_ref_frames[i] = cpi->current_ref_frames[i];
     81         }
     82 
     83         if(cm->frame_type != KEY_FRAME)
     84         {
     85             int mb_row;
     86             int mb_col;
     87             /* Point to beginning of allocated MODE_INFO arrays. */
     88             MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
     89             LOWER_RES_MB_INFO* store_mode_info = store_info->mb_info;
     90 
     91             for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
     92             {
     93                 tmp++;
     94                 for (mb_col = 0; mb_col < cm->mb_cols; mb_col ++)
     95                 {
     96                     int dissim = INT_MAX;
     97 
     98                     if(tmp->mbmi.ref_frame !=INTRA_FRAME)
     99                     {
    100                         int              mvx[8];
    101                         int              mvy[8];
    102                         int              mmvx;
    103                         int              mmvy;
    104                         int              cnt=0;
    105                         const MODE_INFO *here = tmp;
    106                         const MODE_INFO *above = here - cm->mode_info_stride;
    107                         const MODE_INFO *left = here - 1;
    108                         const MODE_INFO *aboveleft = above - 1;
    109                         const MODE_INFO *aboveright = NULL;
    110                         const MODE_INFO *right = NULL;
    111                         const MODE_INFO *belowleft = NULL;
    112                         const MODE_INFO *below = NULL;
    113                         const MODE_INFO *belowright = NULL;
    114 
    115                         /* If alternate reference frame is used, we have to
    116                          * check sign of MV. */
    117                         if(cpi->oxcf.play_alternate)
    118                         {
    119                             /* Gather mv of neighboring MBs */
    120                             GET_MV_SIGN(above)
    121                             GET_MV_SIGN(left)
    122                             GET_MV_SIGN(aboveleft)
    123 
    124                             if(mb_col < (cm->mb_cols-1))
    125                             {
    126                                 right = here + 1;
    127                                 aboveright = above + 1;
    128                                 GET_MV_SIGN(right)
    129                                 GET_MV_SIGN(aboveright)
    130                             }
    131 
    132                             if(mb_row < (cm->mb_rows-1))
    133                             {
    134                                 below = here + cm->mode_info_stride;
    135                                 belowleft = below - 1;
    136                                 GET_MV_SIGN(below)
    137                                 GET_MV_SIGN(belowleft)
    138                             }
    139 
    140                             if(mb_col < (cm->mb_cols-1)
    141                                 && mb_row < (cm->mb_rows-1))
    142                             {
    143                                 belowright = below + 1;
    144                                 GET_MV_SIGN(belowright)
    145                             }
    146                         }else
    147                         {
    148                             /* No alt_ref and gather mv of neighboring MBs */
    149                             GET_MV(above)
    150                             GET_MV(left)
    151                             GET_MV(aboveleft)
    152 
    153                             if(mb_col < (cm->mb_cols-1))
    154                             {
    155                                 right = here + 1;
    156                                 aboveright = above + 1;
    157                                 GET_MV(right)
    158                                 GET_MV(aboveright)
    159                             }
    160 
    161                             if(mb_row < (cm->mb_rows-1))
    162                             {
    163                                 below = here + cm->mode_info_stride;
    164                                 belowleft = below - 1;
    165                                 GET_MV(below)
    166                                 GET_MV(belowleft)
    167                             }
    168 
    169                             if(mb_col < (cm->mb_cols-1)
    170                                 && mb_row < (cm->mb_rows-1))
    171                             {
    172                                 belowright = below + 1;
    173                                 GET_MV(belowright)
    174                             }
    175                         }
    176 
    177                         if (cnt > 0)
    178                         {
    179                             int max_mvx = mvx[0];
    180                             int min_mvx = mvx[0];
    181                             int max_mvy = mvy[0];
    182                             int min_mvy = mvy[0];
    183                             int i;
    184 
    185                             if (cnt > 1)
    186                             {
    187                                 for (i=1; i< cnt; i++)
    188                                 {
    189                                     if (mvx[i] > max_mvx) max_mvx = mvx[i];
    190                                     else if (mvx[i] < min_mvx) min_mvx = mvx[i];
    191                                     if (mvy[i] > max_mvy) max_mvy = mvy[i];
    192                                     else if (mvy[i] < min_mvy) min_mvy = mvy[i];
    193                                 }
    194                             }
    195 
    196                             mmvx = VPXMAX(
    197                                 abs(min_mvx - here->mbmi.mv.as_mv.row),
    198                                 abs(max_mvx - here->mbmi.mv.as_mv.row));
    199                             mmvy = VPXMAX(
    200                                 abs(min_mvy - here->mbmi.mv.as_mv.col),
    201                                 abs(max_mvy - here->mbmi.mv.as_mv.col));
    202                             dissim = VPXMAX(mmvx, mmvy);
    203                         }
    204                     }
    205 
    206                     /* Store mode info for next resolution encoding */
    207                     store_mode_info->mode = tmp->mbmi.mode;
    208                     store_mode_info->ref_frame = tmp->mbmi.ref_frame;
    209                     store_mode_info->mv.as_int = tmp->mbmi.mv.as_int;
    210                     store_mode_info->dissim = dissim;
    211                     tmp++;
    212                     store_mode_info++;
    213                 }
    214             }
    215         }
    216     }
    217 }
    218 
    219 /* This function is called only when this frame is dropped at current
    220    resolution level. */
    221 void vp8_store_drop_frame_info(VP8_COMP *cpi)
    222 {
    223     /* If the frame is dropped in lower-resolution encoding, this information
    224        is passed to higher resolution level so that the encoder knows there
    225        is no mode & motion info available.
    226      */
    227     if (cpi->oxcf.mr_total_resolutions >1
    228         && cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1))
    229     {
    230         /* Store info for show/no-show frames for supporting alt_ref.
    231          * If parent frame is alt_ref, child has one too.
    232          */
    233         LOWER_RES_FRAME_INFO* store_info
    234                       = (LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info;
    235 
    236         /* Set frame_type to be INTER_FRAME since we won't drop key frame. */
    237         store_info->frame_type = INTER_FRAME;
    238         store_info->is_frame_dropped = 1;
    239     }
    240 }
    241