Line data Source code
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 0 : void vp8_cal_low_res_mb_cols(VP8_COMP *cpi) {
21 : int low_res_w;
22 :
23 : /* Support arbitrary down-sampling factor */
24 0 : unsigned int iw = cpi->oxcf.Width * cpi->oxcf.mr_down_sampling_factor.den +
25 0 : cpi->oxcf.mr_down_sampling_factor.num - 1;
26 :
27 0 : low_res_w = iw / cpi->oxcf.mr_down_sampling_factor.num;
28 0 : cpi->mr_low_res_mb_cols = ((low_res_w + 15) >> 4);
29 0 : }
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 0 : void vp8_cal_dissimilarity(VP8_COMP *cpi) {
51 0 : 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 0 : if (cpi->oxcf.mr_total_resolutions > 1 &&
60 0 : 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 0 : LOWER_RES_FRAME_INFO *store_info =
65 : (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info;
66 :
67 0 : store_info->frame_type = cm->frame_type;
68 :
69 0 : if (cm->frame_type != KEY_FRAME) {
70 0 : store_info->is_frame_dropped = 0;
71 0 : for (i = 1; i < MAX_REF_FRAMES; ++i)
72 0 : store_info->low_res_ref_frames[i] = cpi->current_ref_frames[i];
73 : }
74 :
75 0 : if (cm->frame_type != KEY_FRAME) {
76 : int mb_row;
77 : int mb_col;
78 : /* Point to beginning of allocated MODE_INFO arrays. */
79 0 : MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
80 0 : LOWER_RES_MB_INFO *store_mode_info = store_info->mb_info;
81 :
82 0 : for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
83 0 : tmp++;
84 0 : for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
85 0 : int dissim = INT_MAX;
86 :
87 0 : if (tmp->mbmi.ref_frame != INTRA_FRAME) {
88 : int mvx[8];
89 : int mvy[8];
90 : int mmvx;
91 : int mmvy;
92 0 : int cnt = 0;
93 0 : const MODE_INFO *here = tmp;
94 0 : const MODE_INFO *above = here - cm->mode_info_stride;
95 0 : const MODE_INFO *left = here - 1;
96 0 : const MODE_INFO *aboveleft = above - 1;
97 0 : const MODE_INFO *aboveright = NULL;
98 0 : const MODE_INFO *right = NULL;
99 0 : const MODE_INFO *belowleft = NULL;
100 0 : const MODE_INFO *below = NULL;
101 0 : const MODE_INFO *belowright = NULL;
102 :
103 : /* If alternate reference frame is used, we have to
104 : * check sign of MV. */
105 0 : if (cpi->oxcf.play_alternate) {
106 : /* Gather mv of neighboring MBs */
107 0 : GET_MV_SIGN(above)
108 0 : GET_MV_SIGN(left)
109 0 : GET_MV_SIGN(aboveleft)
110 :
111 0 : if (mb_col < (cm->mb_cols - 1)) {
112 0 : right = here + 1;
113 0 : aboveright = above + 1;
114 0 : GET_MV_SIGN(right)
115 0 : GET_MV_SIGN(aboveright)
116 : }
117 :
118 0 : if (mb_row < (cm->mb_rows - 1)) {
119 0 : below = here + cm->mode_info_stride;
120 0 : belowleft = below - 1;
121 0 : GET_MV_SIGN(below)
122 0 : GET_MV_SIGN(belowleft)
123 : }
124 :
125 0 : if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) {
126 0 : belowright = below + 1;
127 0 : GET_MV_SIGN(belowright)
128 : }
129 : } else {
130 : /* No alt_ref and gather mv of neighboring MBs */
131 0 : GET_MV(above)
132 0 : GET_MV(left)
133 0 : GET_MV(aboveleft)
134 :
135 0 : if (mb_col < (cm->mb_cols - 1)) {
136 0 : right = here + 1;
137 0 : aboveright = above + 1;
138 0 : GET_MV(right)
139 0 : GET_MV(aboveright)
140 : }
141 :
142 0 : if (mb_row < (cm->mb_rows - 1)) {
143 0 : below = here + cm->mode_info_stride;
144 0 : belowleft = below - 1;
145 0 : GET_MV(below)
146 0 : GET_MV(belowleft)
147 : }
148 :
149 0 : if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) {
150 0 : belowright = below + 1;
151 0 : GET_MV(belowright)
152 : }
153 : }
154 :
155 0 : if (cnt > 0) {
156 0 : int max_mvx = mvx[0];
157 0 : int min_mvx = mvx[0];
158 0 : int max_mvy = mvy[0];
159 0 : int min_mvy = mvy[0];
160 : int i;
161 :
162 0 : if (cnt > 1) {
163 0 : for (i = 1; i < cnt; ++i) {
164 0 : if (mvx[i] > max_mvx)
165 0 : max_mvx = mvx[i];
166 0 : else if (mvx[i] < min_mvx)
167 0 : min_mvx = mvx[i];
168 0 : if (mvy[i] > max_mvy)
169 0 : max_mvy = mvy[i];
170 0 : else if (mvy[i] < min_mvy)
171 0 : min_mvy = mvy[i];
172 : }
173 : }
174 :
175 0 : mmvx = VPXMAX(abs(min_mvx - here->mbmi.mv.as_mv.row),
176 : abs(max_mvx - here->mbmi.mv.as_mv.row));
177 0 : mmvy = VPXMAX(abs(min_mvy - here->mbmi.mv.as_mv.col),
178 : abs(max_mvy - here->mbmi.mv.as_mv.col));
179 0 : dissim = VPXMAX(mmvx, mmvy);
180 : }
181 : }
182 :
183 : /* Store mode info for next resolution encoding */
184 0 : store_mode_info->mode = tmp->mbmi.mode;
185 0 : store_mode_info->ref_frame = tmp->mbmi.ref_frame;
186 0 : store_mode_info->mv.as_int = tmp->mbmi.mv.as_int;
187 0 : store_mode_info->dissim = dissim;
188 0 : tmp++;
189 0 : store_mode_info++;
190 : }
191 : }
192 : }
193 : }
194 0 : }
195 :
196 : /* This function is called only when this frame is dropped at current
197 : resolution level. */
198 0 : 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 0 : if (cpi->oxcf.mr_total_resolutions > 1 &&
204 0 : 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 0 : 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 0 : store_info->frame_type = INTER_FRAME;
213 0 : store_info->is_frame_dropped = 1;
214 : }
215 0 : }
|