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