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