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