Fix multi-resolution threaded encoding
[profile/ivi/libvpx.git] / vp8 / encoder / mr_dissim.c
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
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
53 void vp8_cal_dissimilarity(VP8_COMP *cpi)
54 {
55     VP8_COMMON *cm = &cpi->common;
56
57     /* Note: The first row & first column in mip are outside the frame, which
58      * were initialized to all 0.(ref_frame, mode, mv...)
59      * Their ref_frame = 0 means they won't be counted in the following
60      * calculation.
61      */
62     if (cpi->oxcf.mr_total_resolutions >1
63         && cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1))
64     {
65         /* Store info for show/no-show frames for supporting alt_ref.
66          * If parent frame is alt_ref, child has one too.
67          */
68         if(cm->frame_type != KEY_FRAME)
69         {
70             int mb_row;
71             int mb_col;
72             /* Point to beginning of allocated MODE_INFO arrays. */
73             MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
74             LOWER_RES_INFO* store_mode_info
75                             = (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info;
76
77             for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
78             {
79                 tmp++;
80                 for (mb_col = 0; mb_col < cm->mb_cols; mb_col ++)
81                 {
82                     int dissim = INT_MAX;
83
84                     if(tmp->mbmi.ref_frame !=INTRA_FRAME)
85                     {
86                         int              mvx[8];
87                         int              mvy[8];
88                         int              mmvx;
89                         int              mmvy;
90                         int              cnt=0;
91                         const MODE_INFO *here = tmp;
92                         const MODE_INFO *above = here - cm->mode_info_stride;
93                         const MODE_INFO *left = here - 1;
94                         const MODE_INFO *aboveleft = above - 1;
95                         const MODE_INFO *aboveright = NULL;
96                         const MODE_INFO *right = NULL;
97                         const MODE_INFO *belowleft = NULL;
98                         const MODE_INFO *below = NULL;
99                         const MODE_INFO *belowright = NULL;
100
101                         /* If alternate reference frame is used, we have to
102                          * check sign of MV. */
103                         if(cpi->oxcf.play_alternate)
104                         {
105                             /* Gather mv of neighboring MBs */
106                             GET_MV_SIGN(above)
107                             GET_MV_SIGN(left)
108                             GET_MV_SIGN(aboveleft)
109
110                             if(mb_col < (cm->mb_cols-1))
111                             {
112                                 right = here + 1;
113                                 aboveright = above + 1;
114                                 GET_MV_SIGN(right)
115                                 GET_MV_SIGN(aboveright)
116                             }
117
118                             if(mb_row < (cm->mb_rows-1))
119                             {
120                                 below = here + cm->mode_info_stride;
121                                 belowleft = below - 1;
122                                 GET_MV_SIGN(below)
123                                 GET_MV_SIGN(belowleft)
124                             }
125
126                             if(mb_col < (cm->mb_cols-1)
127                                 && mb_row < (cm->mb_rows-1))
128                             {
129                                 belowright = below + 1;
130                                 GET_MV_SIGN(belowright)
131                             }
132                         }else
133                         {
134                             /* No alt_ref and gather mv of neighboring MBs */
135                             GET_MV(above)
136                             GET_MV(left)
137                             GET_MV(aboveleft)
138
139                             if(mb_col < (cm->mb_cols-1))
140                             {
141                                 right = here + 1;
142                                 aboveright = above + 1;
143                                 GET_MV(right)
144                                 GET_MV(aboveright)
145                             }
146
147                             if(mb_row < (cm->mb_rows-1))
148                             {
149                                 below = here + cm->mode_info_stride;
150                                 belowleft = below - 1;
151                                 GET_MV(below)
152                                 GET_MV(belowleft)
153                             }
154
155                             if(mb_col < (cm->mb_cols-1)
156                                 && mb_row < (cm->mb_rows-1))
157                             {
158                                 belowright = below + 1;
159                                 GET_MV(belowright)
160                             }
161                         }
162
163                         if (cnt > 0)
164                         {
165                             int max_mvx = mvx[0];
166                             int min_mvx = mvx[0];
167                             int max_mvy = mvy[0];
168                             int min_mvy = mvy[0];
169                             int i;
170
171                             if (cnt > 1)
172                             {
173                                 for (i=1; i< cnt; i++)
174                                 {
175                                     if (mvx[i] > max_mvx) max_mvx = mvx[i];
176                                     else if (mvx[i] < min_mvx) min_mvx = mvx[i];
177                                     if (mvy[i] > max_mvy) max_mvy = mvy[i];
178                                     else if (mvy[i] < min_mvy) min_mvy = mvy[i];
179                                 }
180                             }
181
182                             mmvx = MAX(abs(min_mvx - here->mbmi.mv.as_mv.row),
183                                        abs(max_mvx - here->mbmi.mv.as_mv.row));
184                             mmvy = MAX(abs(min_mvy - here->mbmi.mv.as_mv.col),
185                                        abs(max_mvy - here->mbmi.mv.as_mv.col));
186                             dissim = MAX(mmvx, mmvy);
187                         }
188                     }
189
190                     /* Store mode info for next resolution encoding */
191                     store_mode_info->mode = tmp->mbmi.mode;
192                     store_mode_info->ref_frame = tmp->mbmi.ref_frame;
193                     store_mode_info->mv.as_int = tmp->mbmi.mv.as_int;
194                     store_mode_info->dissim = dissim;
195                     tmp++;
196                     store_mode_info++;
197                 }
198             }
199         }
200     }
201 }