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