1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp8/encoder/mr_dissim.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,236 @@ 1.4 +/* 1.5 + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 + 1.15 +#include <limits.h> 1.16 +#include "vpx_config.h" 1.17 +#include "onyx_int.h" 1.18 +#include "mr_dissim.h" 1.19 +#include "vpx_mem/vpx_mem.h" 1.20 +#include "rdopt.h" 1.21 + 1.22 +void vp8_cal_low_res_mb_cols(VP8_COMP *cpi) 1.23 +{ 1.24 + int low_res_w; 1.25 + 1.26 + /* Support arbitrary down-sampling factor */ 1.27 + unsigned int iw = cpi->oxcf.Width*cpi->oxcf.mr_down_sampling_factor.den 1.28 + + cpi->oxcf.mr_down_sampling_factor.num - 1; 1.29 + 1.30 + low_res_w = iw/cpi->oxcf.mr_down_sampling_factor.num; 1.31 + cpi->mr_low_res_mb_cols = ((low_res_w + 15) >> 4); 1.32 +} 1.33 + 1.34 +#define GET_MV(x) \ 1.35 +if(x->mbmi.ref_frame !=INTRA_FRAME) \ 1.36 +{ \ 1.37 + mvx[cnt] = x->mbmi.mv.as_mv.row; \ 1.38 + mvy[cnt] = x->mbmi.mv.as_mv.col; \ 1.39 + cnt++; \ 1.40 +} 1.41 + 1.42 +#define GET_MV_SIGN(x) \ 1.43 +if(x->mbmi.ref_frame !=INTRA_FRAME) \ 1.44 +{ \ 1.45 + mvx[cnt] = x->mbmi.mv.as_mv.row; \ 1.46 + mvy[cnt] = x->mbmi.mv.as_mv.col; \ 1.47 + if (cm->ref_frame_sign_bias[x->mbmi.ref_frame] \ 1.48 + != cm->ref_frame_sign_bias[tmp->mbmi.ref_frame]) \ 1.49 + { \ 1.50 + mvx[cnt] *= -1; \ 1.51 + mvy[cnt] *= -1; \ 1.52 + } \ 1.53 + cnt++; \ 1.54 +} 1.55 + 1.56 +void vp8_cal_dissimilarity(VP8_COMP *cpi) 1.57 +{ 1.58 + VP8_COMMON *cm = &cpi->common; 1.59 + int i; 1.60 + 1.61 + /* Note: The first row & first column in mip are outside the frame, which 1.62 + * were initialized to all 0.(ref_frame, mode, mv...) 1.63 + * Their ref_frame = 0 means they won't be counted in the following 1.64 + * calculation. 1.65 + */ 1.66 + if (cpi->oxcf.mr_total_resolutions >1 1.67 + && cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) 1.68 + { 1.69 + /* Store info for show/no-show frames for supporting alt_ref. 1.70 + * If parent frame is alt_ref, child has one too. 1.71 + */ 1.72 + LOWER_RES_FRAME_INFO* store_info 1.73 + = (LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info; 1.74 + 1.75 + store_info->frame_type = cm->frame_type; 1.76 + 1.77 + if(cm->frame_type != KEY_FRAME) 1.78 + { 1.79 + store_info->is_frame_dropped = 0; 1.80 + for (i = 1; i < MAX_REF_FRAMES; i++) 1.81 + store_info->low_res_ref_frames[i] = cpi->current_ref_frames[i]; 1.82 + } 1.83 + 1.84 + if(cm->frame_type != KEY_FRAME) 1.85 + { 1.86 + int mb_row; 1.87 + int mb_col; 1.88 + /* Point to beginning of allocated MODE_INFO arrays. */ 1.89 + MODE_INFO *tmp = cm->mip + cm->mode_info_stride; 1.90 + LOWER_RES_MB_INFO* store_mode_info = store_info->mb_info; 1.91 + 1.92 + for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++) 1.93 + { 1.94 + tmp++; 1.95 + for (mb_col = 0; mb_col < cm->mb_cols; mb_col ++) 1.96 + { 1.97 + int dissim = INT_MAX; 1.98 + 1.99 + if(tmp->mbmi.ref_frame !=INTRA_FRAME) 1.100 + { 1.101 + int mvx[8]; 1.102 + int mvy[8]; 1.103 + int mmvx; 1.104 + int mmvy; 1.105 + int cnt=0; 1.106 + const MODE_INFO *here = tmp; 1.107 + const MODE_INFO *above = here - cm->mode_info_stride; 1.108 + const MODE_INFO *left = here - 1; 1.109 + const MODE_INFO *aboveleft = above - 1; 1.110 + const MODE_INFO *aboveright = NULL; 1.111 + const MODE_INFO *right = NULL; 1.112 + const MODE_INFO *belowleft = NULL; 1.113 + const MODE_INFO *below = NULL; 1.114 + const MODE_INFO *belowright = NULL; 1.115 + 1.116 + /* If alternate reference frame is used, we have to 1.117 + * check sign of MV. */ 1.118 + if(cpi->oxcf.play_alternate) 1.119 + { 1.120 + /* Gather mv of neighboring MBs */ 1.121 + GET_MV_SIGN(above) 1.122 + GET_MV_SIGN(left) 1.123 + GET_MV_SIGN(aboveleft) 1.124 + 1.125 + if(mb_col < (cm->mb_cols-1)) 1.126 + { 1.127 + right = here + 1; 1.128 + aboveright = above + 1; 1.129 + GET_MV_SIGN(right) 1.130 + GET_MV_SIGN(aboveright) 1.131 + } 1.132 + 1.133 + if(mb_row < (cm->mb_rows-1)) 1.134 + { 1.135 + below = here + cm->mode_info_stride; 1.136 + belowleft = below - 1; 1.137 + GET_MV_SIGN(below) 1.138 + GET_MV_SIGN(belowleft) 1.139 + } 1.140 + 1.141 + if(mb_col < (cm->mb_cols-1) 1.142 + && mb_row < (cm->mb_rows-1)) 1.143 + { 1.144 + belowright = below + 1; 1.145 + GET_MV_SIGN(belowright) 1.146 + } 1.147 + }else 1.148 + { 1.149 + /* No alt_ref and gather mv of neighboring MBs */ 1.150 + GET_MV(above) 1.151 + GET_MV(left) 1.152 + GET_MV(aboveleft) 1.153 + 1.154 + if(mb_col < (cm->mb_cols-1)) 1.155 + { 1.156 + right = here + 1; 1.157 + aboveright = above + 1; 1.158 + GET_MV(right) 1.159 + GET_MV(aboveright) 1.160 + } 1.161 + 1.162 + if(mb_row < (cm->mb_rows-1)) 1.163 + { 1.164 + below = here + cm->mode_info_stride; 1.165 + belowleft = below - 1; 1.166 + GET_MV(below) 1.167 + GET_MV(belowleft) 1.168 + } 1.169 + 1.170 + if(mb_col < (cm->mb_cols-1) 1.171 + && mb_row < (cm->mb_rows-1)) 1.172 + { 1.173 + belowright = below + 1; 1.174 + GET_MV(belowright) 1.175 + } 1.176 + } 1.177 + 1.178 + if (cnt > 0) 1.179 + { 1.180 + int max_mvx = mvx[0]; 1.181 + int min_mvx = mvx[0]; 1.182 + int max_mvy = mvy[0]; 1.183 + int min_mvy = mvy[0]; 1.184 + int i; 1.185 + 1.186 + if (cnt > 1) 1.187 + { 1.188 + for (i=1; i< cnt; i++) 1.189 + { 1.190 + if (mvx[i] > max_mvx) max_mvx = mvx[i]; 1.191 + else if (mvx[i] < min_mvx) min_mvx = mvx[i]; 1.192 + if (mvy[i] > max_mvy) max_mvy = mvy[i]; 1.193 + else if (mvy[i] < min_mvy) min_mvy = mvy[i]; 1.194 + } 1.195 + } 1.196 + 1.197 + mmvx = MAX(abs(min_mvx - here->mbmi.mv.as_mv.row), 1.198 + abs(max_mvx - here->mbmi.mv.as_mv.row)); 1.199 + mmvy = MAX(abs(min_mvy - here->mbmi.mv.as_mv.col), 1.200 + abs(max_mvy - here->mbmi.mv.as_mv.col)); 1.201 + dissim = MAX(mmvx, mmvy); 1.202 + } 1.203 + } 1.204 + 1.205 + /* Store mode info for next resolution encoding */ 1.206 + store_mode_info->mode = tmp->mbmi.mode; 1.207 + store_mode_info->ref_frame = tmp->mbmi.ref_frame; 1.208 + store_mode_info->mv.as_int = tmp->mbmi.mv.as_int; 1.209 + store_mode_info->dissim = dissim; 1.210 + tmp++; 1.211 + store_mode_info++; 1.212 + } 1.213 + } 1.214 + } 1.215 + } 1.216 +} 1.217 + 1.218 +/* This function is called only when this frame is dropped at current 1.219 + resolution level. */ 1.220 +void vp8_store_drop_frame_info(VP8_COMP *cpi) 1.221 +{ 1.222 + /* If the frame is dropped in lower-resolution encoding, this information 1.223 + is passed to higher resolution level so that the encoder knows there 1.224 + is no mode & motion info available. 1.225 + */ 1.226 + if (cpi->oxcf.mr_total_resolutions >1 1.227 + && cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) 1.228 + { 1.229 + /* Store info for show/no-show frames for supporting alt_ref. 1.230 + * If parent frame is alt_ref, child has one too. 1.231 + */ 1.232 + LOWER_RES_FRAME_INFO* store_info 1.233 + = (LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info; 1.234 + 1.235 + /* Set frame_type to be INTER_FRAME since we won't drop key frame. */ 1.236 + store_info->frame_type = INTER_FRAME; 1.237 + store_info->is_frame_dropped = 1; 1.238 + } 1.239 +}