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
vp8_cal_low_res_mb_cols(VP8_COMP * cpi)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
vp8_cal_dissimilarity(VP8_COMP * cpi)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. */
vp8_store_drop_frame_info(VP8_COMP * cpi)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