• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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