1 /*
2 * Copyright (c) 2019 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 "vp9/common/vp9_mv.h"
12 #include "vp9/encoder/vp9_non_greedy_mv.h"
13 // TODO(angiebird): move non_greedy_mv related functions to this file
14
15 #define LOG2_TABLE_SIZE 1024
16 static const int log2_table[LOG2_TABLE_SIZE] = {
17 0, // This is a dummy value
18 0, 1048576, 1661954, 2097152, 2434718, 2710530, 2943725,
19 3145728, 3323907, 3483294, 3627477, 3759106, 3880192, 3992301,
20 4096672, 4194304, 4286015, 4372483, 4454275, 4531870, 4605679,
21 4676053, 4743299, 4807682, 4869436, 4928768, 4985861, 5040877,
22 5093962, 5145248, 5194851, 5242880, 5289431, 5334591, 5378443,
23 5421059, 5462508, 5502851, 5542146, 5580446, 5617800, 5654255,
24 5689851, 5724629, 5758625, 5791875, 5824409, 5856258, 5887450,
25 5918012, 5947969, 5977344, 6006160, 6034437, 6062195, 6089453,
26 6116228, 6142538, 6168398, 6193824, 6218829, 6243427, 6267632,
27 6291456, 6314910, 6338007, 6360756, 6383167, 6405252, 6427019,
28 6448477, 6469635, 6490501, 6511084, 6531390, 6551427, 6571202,
29 6590722, 6609993, 6629022, 6647815, 6666376, 6684713, 6702831,
30 6720734, 6738427, 6755916, 6773205, 6790299, 6807201, 6823917,
31 6840451, 6856805, 6872985, 6888993, 6904834, 6920510, 6936026,
32 6951384, 6966588, 6981641, 6996545, 7011304, 7025920, 7040397,
33 7054736, 7068940, 7083013, 7096956, 7110771, 7124461, 7138029,
34 7151476, 7164804, 7178017, 7191114, 7204100, 7216974, 7229740,
35 7242400, 7254954, 7267405, 7279754, 7292003, 7304154, 7316208,
36 7328167, 7340032, 7351805, 7363486, 7375079, 7386583, 7398000,
37 7409332, 7420579, 7431743, 7442826, 7453828, 7464751, 7475595,
38 7486362, 7497053, 7507669, 7518211, 7528680, 7539077, 7549404,
39 7559660, 7569847, 7579966, 7590017, 7600003, 7609923, 7619778,
40 7629569, 7639298, 7648964, 7658569, 7668114, 7677598, 7687023,
41 7696391, 7705700, 7714952, 7724149, 7733289, 7742375, 7751407,
42 7760385, 7769310, 7778182, 7787003, 7795773, 7804492, 7813161,
43 7821781, 7830352, 7838875, 7847350, 7855777, 7864158, 7872493,
44 7880782, 7889027, 7897226, 7905381, 7913492, 7921561, 7929586,
45 7937569, 7945510, 7953410, 7961268, 7969086, 7976864, 7984602,
46 7992301, 7999960, 8007581, 8015164, 8022709, 8030217, 8037687,
47 8045121, 8052519, 8059880, 8067206, 8074496, 8081752, 8088973,
48 8096159, 8103312, 8110431, 8117516, 8124569, 8131589, 8138576,
49 8145532, 8152455, 8159347, 8166208, 8173037, 8179836, 8186605,
50 8193343, 8200052, 8206731, 8213380, 8220001, 8226593, 8233156,
51 8239690, 8246197, 8252676, 8259127, 8265550, 8271947, 8278316,
52 8284659, 8290976, 8297266, 8303530, 8309768, 8315981, 8322168,
53 8328330, 8334467, 8340579, 8346667, 8352730, 8358769, 8364784,
54 8370775, 8376743, 8382687, 8388608, 8394506, 8400381, 8406233,
55 8412062, 8417870, 8423655, 8429418, 8435159, 8440878, 8446576,
56 8452252, 8457908, 8463542, 8469155, 8474748, 8480319, 8485871,
57 8491402, 8496913, 8502404, 8507875, 8513327, 8518759, 8524171,
58 8529564, 8534938, 8540293, 8545629, 8550947, 8556245, 8561525,
59 8566787, 8572031, 8577256, 8582464, 8587653, 8592825, 8597980,
60 8603116, 8608236, 8613338, 8618423, 8623491, 8628542, 8633576,
61 8638593, 8643594, 8648579, 8653547, 8658499, 8663434, 8668354,
62 8673258, 8678145, 8683017, 8687874, 8692715, 8697540, 8702350,
63 8707145, 8711925, 8716690, 8721439, 8726174, 8730894, 8735599,
64 8740290, 8744967, 8749628, 8754276, 8758909, 8763528, 8768134,
65 8772725, 8777302, 8781865, 8786415, 8790951, 8795474, 8799983,
66 8804478, 8808961, 8813430, 8817886, 8822328, 8826758, 8831175,
67 8835579, 8839970, 8844349, 8848715, 8853068, 8857409, 8861737,
68 8866053, 8870357, 8874649, 8878928, 8883195, 8887451, 8891694,
69 8895926, 8900145, 8904353, 8908550, 8912734, 8916908, 8921069,
70 8925220, 8929358, 8933486, 8937603, 8941708, 8945802, 8949885,
71 8953957, 8958018, 8962068, 8966108, 8970137, 8974155, 8978162,
72 8982159, 8986145, 8990121, 8994086, 8998041, 9001986, 9005920,
73 9009844, 9013758, 9017662, 9021556, 9025440, 9029314, 9033178,
74 9037032, 9040877, 9044711, 9048536, 9052352, 9056157, 9059953,
75 9063740, 9067517, 9071285, 9075044, 9078793, 9082533, 9086263,
76 9089985, 9093697, 9097400, 9101095, 9104780, 9108456, 9112123,
77 9115782, 9119431, 9123072, 9126704, 9130328, 9133943, 9137549,
78 9141146, 9144735, 9148316, 9151888, 9155452, 9159007, 9162554,
79 9166092, 9169623, 9173145, 9176659, 9180165, 9183663, 9187152,
80 9190634, 9194108, 9197573, 9201031, 9204481, 9207923, 9211357,
81 9214784, 9218202, 9221613, 9225017, 9228412, 9231800, 9235181,
82 9238554, 9241919, 9245277, 9248628, 9251971, 9255307, 9258635,
83 9261956, 9265270, 9268577, 9271876, 9275169, 9278454, 9281732,
84 9285002, 9288266, 9291523, 9294773, 9298016, 9301252, 9304481,
85 9307703, 9310918, 9314126, 9317328, 9320523, 9323711, 9326892,
86 9330067, 9333235, 9336397, 9339552, 9342700, 9345842, 9348977,
87 9352106, 9355228, 9358344, 9361454, 9364557, 9367654, 9370744,
88 9373828, 9376906, 9379978, 9383043, 9386102, 9389155, 9392202,
89 9395243, 9398278, 9401306, 9404329, 9407345, 9410356, 9413360,
90 9416359, 9419351, 9422338, 9425319, 9428294, 9431263, 9434226,
91 9437184, 9440136, 9443082, 9446022, 9448957, 9451886, 9454809,
92 9457726, 9460638, 9463545, 9466446, 9469341, 9472231, 9475115,
93 9477994, 9480867, 9483735, 9486597, 9489454, 9492306, 9495152,
94 9497993, 9500828, 9503659, 9506484, 9509303, 9512118, 9514927,
95 9517731, 9520530, 9523324, 9526112, 9528895, 9531674, 9534447,
96 9537215, 9539978, 9542736, 9545489, 9548237, 9550980, 9553718,
97 9556451, 9559179, 9561903, 9564621, 9567335, 9570043, 9572747,
98 9575446, 9578140, 9580830, 9583514, 9586194, 9588869, 9591540,
99 9594205, 9596866, 9599523, 9602174, 9604821, 9607464, 9610101,
100 9612735, 9615363, 9617987, 9620607, 9623222, 9625832, 9628438,
101 9631040, 9633637, 9636229, 9638818, 9641401, 9643981, 9646556,
102 9649126, 9651692, 9654254, 9656812, 9659365, 9661914, 9664459,
103 9666999, 9669535, 9672067, 9674594, 9677118, 9679637, 9682152,
104 9684663, 9687169, 9689672, 9692170, 9694665, 9697155, 9699641,
105 9702123, 9704601, 9707075, 9709545, 9712010, 9714472, 9716930,
106 9719384, 9721834, 9724279, 9726721, 9729159, 9731593, 9734024,
107 9736450, 9738872, 9741291, 9743705, 9746116, 9748523, 9750926,
108 9753326, 9755721, 9758113, 9760501, 9762885, 9765266, 9767642,
109 9770015, 9772385, 9774750, 9777112, 9779470, 9781825, 9784175,
110 9786523, 9788866, 9791206, 9793543, 9795875, 9798204, 9800530,
111 9802852, 9805170, 9807485, 9809797, 9812104, 9814409, 9816710,
112 9819007, 9821301, 9823591, 9825878, 9828161, 9830441, 9832718,
113 9834991, 9837261, 9839527, 9841790, 9844050, 9846306, 9848559,
114 9850808, 9853054, 9855297, 9857537, 9859773, 9862006, 9864235,
115 9866462, 9868685, 9870904, 9873121, 9875334, 9877544, 9879751,
116 9881955, 9884155, 9886352, 9888546, 9890737, 9892925, 9895109,
117 9897291, 9899469, 9901644, 9903816, 9905985, 9908150, 9910313,
118 9912473, 9914629, 9916783, 9918933, 9921080, 9923225, 9925366,
119 9927504, 9929639, 9931771, 9933900, 9936027, 9938150, 9940270,
120 9942387, 9944502, 9946613, 9948721, 9950827, 9952929, 9955029,
121 9957126, 9959219, 9961310, 9963398, 9965484, 9967566, 9969645,
122 9971722, 9973796, 9975866, 9977934, 9980000, 9982062, 9984122,
123 9986179, 9988233, 9990284, 9992332, 9994378, 9996421, 9998461,
124 10000498, 10002533, 10004565, 10006594, 10008621, 10010644, 10012665,
125 10014684, 10016700, 10018713, 10020723, 10022731, 10024736, 10026738,
126 10028738, 10030735, 10032729, 10034721, 10036710, 10038697, 10040681,
127 10042662, 10044641, 10046617, 10048591, 10050562, 10052530, 10054496,
128 10056459, 10058420, 10060379, 10062334, 10064287, 10066238, 10068186,
129 10070132, 10072075, 10074016, 10075954, 10077890, 10079823, 10081754,
130 10083682, 10085608, 10087532, 10089453, 10091371, 10093287, 10095201,
131 10097112, 10099021, 10100928, 10102832, 10104733, 10106633, 10108529,
132 10110424, 10112316, 10114206, 10116093, 10117978, 10119861, 10121742,
133 10123620, 10125495, 10127369, 10129240, 10131109, 10132975, 10134839,
134 10136701, 10138561, 10140418, 10142273, 10144126, 10145976, 10147825,
135 10149671, 10151514, 10153356, 10155195, 10157032, 10158867, 10160699,
136 10162530, 10164358, 10166184, 10168007, 10169829, 10171648, 10173465,
137 10175280, 10177093, 10178904, 10180712, 10182519, 10184323, 10186125,
138 10187925, 10189722, 10191518, 10193311, 10195103, 10196892, 10198679,
139 10200464, 10202247, 10204028, 10205806, 10207583, 10209357, 10211130,
140 10212900, 10214668, 10216435, 10218199, 10219961, 10221721, 10223479,
141 10225235, 10226989, 10228741, 10230491, 10232239, 10233985, 10235728,
142 10237470, 10239210, 10240948, 10242684, 10244417, 10246149, 10247879,
143 10249607, 10251333, 10253057, 10254779, 10256499, 10258217, 10259933,
144 10261647, 10263360, 10265070, 10266778, 10268485, 10270189, 10271892,
145 10273593, 10275292, 10276988, 10278683, 10280376, 10282068, 10283757,
146 10285444, 10287130, 10288814, 10290495, 10292175, 10293853, 10295530,
147 10297204, 10298876, 10300547, 10302216, 10303883, 10305548, 10307211,
148 10308873, 10310532, 10312190, 10313846, 10315501, 10317153, 10318804,
149 10320452, 10322099, 10323745, 10325388, 10327030, 10328670, 10330308,
150 10331944, 10333578, 10335211, 10336842, 10338472, 10340099, 10341725,
151 10343349, 10344971, 10346592, 10348210, 10349828, 10351443, 10353057,
152 10354668, 10356279, 10357887, 10359494, 10361099, 10362702, 10364304,
153 10365904, 10367502, 10369099, 10370694, 10372287, 10373879, 10375468,
154 10377057, 10378643, 10380228, 10381811, 10383393, 10384973, 10386551,
155 10388128, 10389703, 10391276, 10392848, 10394418, 10395986, 10397553,
156 10399118, 10400682, 10402244, 10403804, 10405363, 10406920, 10408476,
157 10410030, 10411582, 10413133, 10414682, 10416230, 10417776, 10419320,
158 10420863, 10422404, 10423944, 10425482, 10427019, 10428554, 10430087,
159 10431619, 10433149, 10434678, 10436206, 10437731, 10439256, 10440778,
160 10442299, 10443819, 10445337, 10446854, 10448369, 10449882, 10451394,
161 10452905, 10454414, 10455921, 10457427, 10458932, 10460435, 10461936,
162 10463436, 10464935, 10466432, 10467927, 10469422, 10470914, 10472405,
163 10473895, 10475383, 10476870, 10478355, 10479839, 10481322, 10482802,
164 10484282,
165 };
166
mi_size_to_block_size(int mi_bsize,int mi_num)167 static int mi_size_to_block_size(int mi_bsize, int mi_num) {
168 return (mi_num % mi_bsize) ? mi_num / mi_bsize + 1 : mi_num / mi_bsize;
169 }
170
vp9_alloc_motion_field_info(MotionFieldInfo * motion_field_info,int frame_num,int mi_rows,int mi_cols)171 Status vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info,
172 int frame_num, int mi_rows, int mi_cols) {
173 int frame_idx, rf_idx, square_block_idx;
174 if (motion_field_info->allocated) {
175 // TODO(angiebird): Avoid re-allocate buffer if possible
176 vp9_free_motion_field_info(motion_field_info);
177 }
178 motion_field_info->frame_num = frame_num;
179 motion_field_info->motion_field_array =
180 vpx_calloc(frame_num, sizeof(*motion_field_info->motion_field_array));
181 for (frame_idx = 0; frame_idx < frame_num; ++frame_idx) {
182 for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
183 for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES;
184 ++square_block_idx) {
185 BLOCK_SIZE bsize = square_block_idx_to_bsize(square_block_idx);
186 const int mi_height = num_8x8_blocks_high_lookup[bsize];
187 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
188 const int block_rows = mi_size_to_block_size(mi_height, mi_rows);
189 const int block_cols = mi_size_to_block_size(mi_width, mi_cols);
190 MotionField *motion_field =
191 &motion_field_info
192 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
193 Status status =
194 vp9_alloc_motion_field(motion_field, bsize, block_rows, block_cols);
195 if (status == STATUS_FAILED) {
196 return STATUS_FAILED;
197 }
198 }
199 }
200 }
201 motion_field_info->allocated = 1;
202 return STATUS_OK;
203 }
204
vp9_alloc_motion_field(MotionField * motion_field,BLOCK_SIZE bsize,int block_rows,int block_cols)205 Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
206 int block_rows, int block_cols) {
207 Status status = STATUS_OK;
208 motion_field->ready = 0;
209 motion_field->bsize = bsize;
210 motion_field->block_rows = block_rows;
211 motion_field->block_cols = block_cols;
212 motion_field->block_num = block_rows * block_cols;
213 motion_field->mf =
214 vpx_calloc(motion_field->block_num, sizeof(*motion_field->mf));
215 if (motion_field->mf == NULL) {
216 status = STATUS_FAILED;
217 }
218 motion_field->set_mv =
219 vpx_calloc(motion_field->block_num, sizeof(*motion_field->set_mv));
220 if (motion_field->set_mv == NULL) {
221 vpx_free(motion_field->mf);
222 motion_field->mf = NULL;
223 status = STATUS_FAILED;
224 }
225 motion_field->local_structure = vpx_calloc(
226 motion_field->block_num, sizeof(*motion_field->local_structure));
227 if (motion_field->local_structure == NULL) {
228 vpx_free(motion_field->mf);
229 motion_field->mf = NULL;
230 vpx_free(motion_field->set_mv);
231 motion_field->set_mv = NULL;
232 status = STATUS_FAILED;
233 }
234 return status;
235 }
236
vp9_free_motion_field(MotionField * motion_field)237 void vp9_free_motion_field(MotionField *motion_field) {
238 vpx_free(motion_field->mf);
239 vpx_free(motion_field->set_mv);
240 vpx_free(motion_field->local_structure);
241 vp9_zero(*motion_field);
242 }
243
vp9_free_motion_field_info(MotionFieldInfo * motion_field_info)244 void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info) {
245 if (motion_field_info->allocated) {
246 int frame_idx, rf_idx, square_block_idx;
247 for (frame_idx = 0; frame_idx < motion_field_info->frame_num; ++frame_idx) {
248 for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
249 for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES;
250 ++square_block_idx) {
251 MotionField *motion_field =
252 &motion_field_info
253 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
254 vp9_free_motion_field(motion_field);
255 }
256 }
257 }
258 vpx_free(motion_field_info->motion_field_array);
259 motion_field_info->motion_field_array = NULL;
260 motion_field_info->frame_num = 0;
261 motion_field_info->allocated = 0;
262 }
263 }
264
vp9_motion_field_info_get_motion_field(MotionFieldInfo * motion_field_info,int frame_idx,int rf_idx,BLOCK_SIZE bsize)265 MotionField *vp9_motion_field_info_get_motion_field(
266 MotionFieldInfo *motion_field_info, int frame_idx, int rf_idx,
267 BLOCK_SIZE bsize) {
268 int square_block_idx = get_square_block_idx(bsize);
269 assert(frame_idx < motion_field_info->frame_num);
270 assert(motion_field_info->allocated == 1);
271 return &motion_field_info
272 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
273 }
274
vp9_motion_field_is_mv_set(const MotionField * motion_field,int brow,int bcol)275 int vp9_motion_field_is_mv_set(const MotionField *motion_field, int brow,
276 int bcol) {
277 assert(brow >= 0 && brow < motion_field->block_rows);
278 assert(bcol >= 0 && bcol < motion_field->block_cols);
279 return motion_field->set_mv[brow * motion_field->block_cols + bcol];
280 }
281
vp9_motion_field_get_mv(const MotionField * motion_field,int brow,int bcol)282 int_mv vp9_motion_field_get_mv(const MotionField *motion_field, int brow,
283 int bcol) {
284 assert(brow >= 0 && brow < motion_field->block_rows);
285 assert(bcol >= 0 && bcol < motion_field->block_cols);
286 return motion_field->mf[brow * motion_field->block_cols + bcol];
287 }
288
vp9_motion_field_mi_get_mv(const MotionField * motion_field,int mi_row,int mi_col)289 int_mv vp9_motion_field_mi_get_mv(const MotionField *motion_field, int mi_row,
290 int mi_col) {
291 const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize];
292 const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize];
293 const int brow = mi_row / mi_height;
294 const int bcol = mi_col / mi_width;
295 assert(mi_row % mi_height == 0);
296 assert(mi_col % mi_width == 0);
297 return vp9_motion_field_get_mv(motion_field, brow, bcol);
298 }
299
vp9_motion_field_mi_set_mv(MotionField * motion_field,int mi_row,int mi_col,int_mv mv)300 void vp9_motion_field_mi_set_mv(MotionField *motion_field, int mi_row,
301 int mi_col, int_mv mv) {
302 const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize];
303 const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize];
304 const int brow = mi_row / mi_height;
305 const int bcol = mi_col / mi_width;
306 assert(mi_row % mi_height == 0);
307 assert(mi_col % mi_width == 0);
308 assert(brow >= 0 && brow < motion_field->block_rows);
309 assert(bcol >= 0 && bcol < motion_field->block_cols);
310 motion_field->mf[brow * motion_field->block_cols + bcol] = mv;
311 motion_field->set_mv[brow * motion_field->block_cols + bcol] = 1;
312 }
313
vp9_motion_field_reset_mvs(MotionField * motion_field)314 void vp9_motion_field_reset_mvs(MotionField *motion_field) {
315 memset(motion_field->set_mv, 0,
316 motion_field->block_num * sizeof(*motion_field->set_mv));
317 }
318
log2_approximation(int64_t v)319 static int64_t log2_approximation(int64_t v) {
320 assert(v > 0);
321 if (v < LOG2_TABLE_SIZE) {
322 return log2_table[v];
323 } else {
324 // use linear approximation when v >= 2^10
325 const int slope =
326 1477; // slope = 1 / (log(2) * 1024) * (1 << LOG2_PRECISION)
327 assert(LOG2_TABLE_SIZE == 1 << 10);
328
329 return slope * (v - LOG2_TABLE_SIZE) + (10 << LOG2_PRECISION);
330 }
331 }
332
vp9_nb_mvs_inconsistency(const MV * mv,const int_mv * nb_full_mvs,int mv_num)333 int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs,
334 int mv_num) {
335 // The behavior of this function is to compute log2 of mv difference,
336 // i.e. min log2(1 + row_diff * row_diff + col_diff * col_diff)
337 // against available neighbor mvs.
338 // Since the log2 is monotonically increasing, we can compute
339 // min row_diff * row_diff + col_diff * col_diff first
340 // then apply log2 in the end.
341 int i;
342 int64_t min_abs_diff = INT64_MAX;
343 int cnt = 0;
344 assert(mv_num <= NB_MVS_NUM);
345 for (i = 0; i < mv_num; ++i) {
346 MV nb_mv = nb_full_mvs[i].as_mv;
347 const int64_t row_diff = abs(mv->row - nb_mv.row);
348 const int64_t col_diff = abs(mv->col - nb_mv.col);
349 const int64_t abs_diff = row_diff * row_diff + col_diff * col_diff;
350 assert(nb_full_mvs[i].as_int != INVALID_MV);
351 min_abs_diff = VPXMIN(abs_diff, min_abs_diff);
352 ++cnt;
353 }
354 if (cnt) {
355 return log2_approximation(1 + min_abs_diff);
356 }
357 return 0;
358 }
359
get_smooth_motion_vector(const FloatMV scaled_search_mv,const FloatMV * tmp_mf,const int (* M)[MF_LOCAL_STRUCTURE_SIZE],int rows,int cols,int row,int col,float alpha)360 static FloatMV get_smooth_motion_vector(const FloatMV scaled_search_mv,
361 const FloatMV *tmp_mf,
362 const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
363 int rows, int cols, int row, int col,
364 float alpha) {
365 const FloatMV tmp_mv = tmp_mf[row * cols + col];
366 int idx_row, idx_col;
367 FloatMV avg_nb_mv = { 0.0f, 0.0f };
368 FloatMV mv = { 0.0f, 0.0f };
369 float filter[3][3] = { { 1.0f / 12.0f, 1.0f / 6.0f, 1.0f / 12.0f },
370 { 1.0f / 6.0f, 0.0f, 1.0f / 6.0f },
371 { 1.0f / 12.0f, 1.0f / 6.0f, 1.0f / 12.0f } };
372 for (idx_row = 0; idx_row < 3; ++idx_row) {
373 int nb_row = row + idx_row - 1;
374 for (idx_col = 0; idx_col < 3; ++idx_col) {
375 int nb_col = col + idx_col - 1;
376 if (nb_row < 0 || nb_col < 0 || nb_row >= rows || nb_col >= cols) {
377 avg_nb_mv.row += (tmp_mv.row) * filter[idx_row][idx_col];
378 avg_nb_mv.col += (tmp_mv.col) * filter[idx_row][idx_col];
379 } else {
380 const FloatMV nb_mv = tmp_mf[nb_row * cols + nb_col];
381 avg_nb_mv.row += (nb_mv.row) * filter[idx_row][idx_col];
382 avg_nb_mv.col += (nb_mv.col) * filter[idx_row][idx_col];
383 }
384 }
385 }
386 {
387 // M is the local variance of reference frame
388 float M00 = M[row * cols + col][0];
389 float M01 = M[row * cols + col][1];
390 float M10 = M[row * cols + col][2];
391 float M11 = M[row * cols + col][3];
392
393 float det = (M00 + alpha) * (M11 + alpha) - M01 * M10;
394
395 float inv_M00 = (M11 + alpha) / det;
396 float inv_M01 = -M01 / det;
397 float inv_M10 = -M10 / det;
398 float inv_M11 = (M00 + alpha) / det;
399
400 float inv_MM00 = inv_M00 * M00 + inv_M01 * M10;
401 float inv_MM01 = inv_M00 * M01 + inv_M01 * M11;
402 float inv_MM10 = inv_M10 * M00 + inv_M11 * M10;
403 float inv_MM11 = inv_M10 * M01 + inv_M11 * M11;
404
405 mv.row = inv_M00 * avg_nb_mv.row * alpha + inv_M01 * avg_nb_mv.col * alpha +
406 inv_MM00 * scaled_search_mv.row + inv_MM01 * scaled_search_mv.col;
407 mv.col = inv_M10 * avg_nb_mv.row * alpha + inv_M11 * avg_nb_mv.col * alpha +
408 inv_MM10 * scaled_search_mv.row + inv_MM11 * scaled_search_mv.col;
409 }
410 return mv;
411 }
412
vp9_get_smooth_motion_field(const MV * search_mf,const int (* M)[MF_LOCAL_STRUCTURE_SIZE],int rows,int cols,BLOCK_SIZE bsize,float alpha,int num_iters,MV * smooth_mf)413 void vp9_get_smooth_motion_field(const MV *search_mf,
414 const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
415 int rows, int cols, BLOCK_SIZE bsize,
416 float alpha, int num_iters, MV *smooth_mf) {
417 // M is the local variation of reference frame
418 // build two buffers
419 FloatMV *input = (FloatMV *)malloc(rows * cols * sizeof(FloatMV));
420 FloatMV *output = (FloatMV *)malloc(rows * cols * sizeof(FloatMV));
421 int idx;
422 int row, col;
423 int bw = 4 << b_width_log2_lookup[bsize];
424 int bh = 4 << b_height_log2_lookup[bsize];
425 // copy search results to input buffer
426 for (idx = 0; idx < rows * cols; ++idx) {
427 input[idx].row = (float)search_mf[idx].row / bh;
428 input[idx].col = (float)search_mf[idx].col / bw;
429 }
430 for (idx = 0; idx < num_iters; ++idx) {
431 FloatMV *tmp;
432 for (row = 0; row < rows; ++row) {
433 for (col = 0; col < cols; ++col) {
434 // note: the scaled_search_mf and smooth_mf are all scaled by macroblock
435 // size
436 const MV search_mv = search_mf[row * cols + col];
437 FloatMV scaled_search_mv = { (float)search_mv.row / bh,
438 (float)search_mv.col / bw };
439 output[row * cols + col] = get_smooth_motion_vector(
440 scaled_search_mv, input, M, rows, cols, row, col, alpha);
441 }
442 }
443 // swap buffers
444 tmp = input;
445 input = output;
446 output = tmp;
447 }
448 // copy smoothed results to output
449 for (idx = 0; idx < rows * cols; ++idx) {
450 smooth_mf[idx].row = (int)(input[idx].row * bh);
451 smooth_mf[idx].col = (int)(input[idx].col * bw);
452 }
453 free(input);
454 free(output);
455 }
456
vp9_get_local_structure(const YV12_BUFFER_CONFIG * cur_frame,const YV12_BUFFER_CONFIG * ref_frame,const MV * search_mf,const vp9_variance_fn_ptr_t * fn_ptr,int rows,int cols,BLOCK_SIZE bsize,int (* M)[MF_LOCAL_STRUCTURE_SIZE])457 void vp9_get_local_structure(const YV12_BUFFER_CONFIG *cur_frame,
458 const YV12_BUFFER_CONFIG *ref_frame,
459 const MV *search_mf,
460 const vp9_variance_fn_ptr_t *fn_ptr, int rows,
461 int cols, BLOCK_SIZE bsize,
462 int (*M)[MF_LOCAL_STRUCTURE_SIZE]) {
463 const int bw = 4 << b_width_log2_lookup[bsize];
464 const int bh = 4 << b_height_log2_lookup[bsize];
465 const int cur_stride = cur_frame->y_stride;
466 const int ref_stride = ref_frame->y_stride;
467 const int width = ref_frame->y_width;
468 const int height = ref_frame->y_height;
469 int row, col;
470 for (row = 0; row < rows; ++row) {
471 for (col = 0; col < cols; ++col) {
472 int cur_offset = row * bh * cur_stride + col * bw;
473 uint8_t *center = cur_frame->y_buffer + cur_offset;
474 int ref_h = row * bh + search_mf[row * cols + col].row;
475 int ref_w = col * bw + search_mf[row * cols + col].col;
476 int ref_offset;
477 uint8_t *target;
478 uint8_t *nb;
479 int search_dist;
480 int nb_dist;
481 int I_row = 0, I_col = 0;
482 // TODO(Dan): handle the case that when reference frame block beyond the
483 // boundary
484 ref_h = ref_h < 0 ? 0 : (ref_h >= height - bh ? height - bh - 1 : ref_h);
485 ref_w = ref_w < 0 ? 0 : (ref_w >= width - bw ? width - bw - 1 : ref_w);
486 // compute search results distortion
487 // TODO(Dan): maybe need to use vp9 function to find the reference block,
488 // to compare with the results of my python code, I first use my way to
489 // compute the reference block
490 ref_offset = ref_h * ref_stride + ref_w;
491 target = ref_frame->y_buffer + ref_offset;
492 search_dist = fn_ptr->sdf(center, cur_stride, target, ref_stride);
493 // compute target's neighbors' distortions
494 // TODO(Dan): if using padding, the boundary condition may vary
495 // up
496 if (ref_h - bh >= 0) {
497 nb = target - ref_stride * bh;
498 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
499 I_row += nb_dist - search_dist;
500 }
501 // down
502 if (ref_h + bh < height - bh) {
503 nb = target + ref_stride * bh;
504 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
505 I_row += nb_dist - search_dist;
506 }
507 if (ref_h - bh >= 0 && ref_h + bh < height - bh) {
508 I_row /= 2;
509 }
510 I_row /= (bw * bh);
511 // left
512 if (ref_w - bw >= 0) {
513 nb = target - bw;
514 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
515 I_col += nb_dist - search_dist;
516 }
517 // down
518 if (ref_w + bw < width - bw) {
519 nb = target + bw;
520 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
521 I_col += nb_dist - search_dist;
522 }
523 if (ref_w - bw >= 0 && ref_w + bw < width - bw) {
524 I_col /= 2;
525 }
526 I_col /= (bw * bh);
527 M[row * cols + col][0] = I_row * I_row;
528 M[row * cols + col][1] = I_row * I_col;
529 M[row * cols + col][2] = I_col * I_row;
530 M[row * cols + col][3] = I_col * I_col;
531 }
532 }
533 }
534