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