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 if (!motion_field_info->motion_field_array) return STATUS_FAILED;
182 for (frame_idx = 0; frame_idx < frame_num; ++frame_idx) {
183 for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
184 for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES;
185 ++square_block_idx) {
186 BLOCK_SIZE bsize = square_block_idx_to_bsize(square_block_idx);
187 const int mi_height = num_8x8_blocks_high_lookup[bsize];
188 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
189 const int block_rows = mi_size_to_block_size(mi_height, mi_rows);
190 const int block_cols = mi_size_to_block_size(mi_width, mi_cols);
191 MotionField *motion_field =
192 &motion_field_info
193 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
194 Status status =
195 vp9_alloc_motion_field(motion_field, bsize, block_rows, block_cols);
196 if (status == STATUS_FAILED) {
197 return STATUS_FAILED;
198 }
199 }
200 }
201 }
202 motion_field_info->allocated = 1;
203 return STATUS_OK;
204 }
205
vp9_alloc_motion_field(MotionField * motion_field,BLOCK_SIZE bsize,int block_rows,int block_cols)206 Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize,
207 int block_rows, int block_cols) {
208 Status status = STATUS_OK;
209 motion_field->ready = 0;
210 motion_field->bsize = bsize;
211 motion_field->block_rows = block_rows;
212 motion_field->block_cols = block_cols;
213 motion_field->block_num = block_rows * block_cols;
214 motion_field->mf =
215 vpx_calloc(motion_field->block_num, sizeof(*motion_field->mf));
216 if (motion_field->mf == NULL) {
217 status = STATUS_FAILED;
218 }
219 motion_field->set_mv =
220 vpx_calloc(motion_field->block_num, sizeof(*motion_field->set_mv));
221 if (motion_field->set_mv == NULL) {
222 vpx_free(motion_field->mf);
223 motion_field->mf = NULL;
224 status = STATUS_FAILED;
225 }
226 motion_field->local_structure = vpx_calloc(
227 motion_field->block_num, sizeof(*motion_field->local_structure));
228 if (motion_field->local_structure == NULL) {
229 vpx_free(motion_field->mf);
230 motion_field->mf = NULL;
231 vpx_free(motion_field->set_mv);
232 motion_field->set_mv = NULL;
233 status = STATUS_FAILED;
234 }
235 return status;
236 }
237
vp9_free_motion_field(MotionField * motion_field)238 void vp9_free_motion_field(MotionField *motion_field) {
239 vpx_free(motion_field->mf);
240 vpx_free(motion_field->set_mv);
241 vpx_free(motion_field->local_structure);
242 vp9_zero(*motion_field);
243 }
244
vp9_free_motion_field_info(MotionFieldInfo * motion_field_info)245 void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info) {
246 if (motion_field_info->allocated) {
247 int frame_idx, rf_idx, square_block_idx;
248 for (frame_idx = 0; frame_idx < motion_field_info->frame_num; ++frame_idx) {
249 for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) {
250 for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES;
251 ++square_block_idx) {
252 MotionField *motion_field =
253 &motion_field_info
254 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
255 vp9_free_motion_field(motion_field);
256 }
257 }
258 }
259 vpx_free(motion_field_info->motion_field_array);
260 motion_field_info->motion_field_array = NULL;
261 motion_field_info->frame_num = 0;
262 motion_field_info->allocated = 0;
263 }
264 }
265
vp9_motion_field_info_get_motion_field(MotionFieldInfo * motion_field_info,int frame_idx,int rf_idx,BLOCK_SIZE bsize)266 MotionField *vp9_motion_field_info_get_motion_field(
267 MotionFieldInfo *motion_field_info, int frame_idx, int rf_idx,
268 BLOCK_SIZE bsize) {
269 int square_block_idx = get_square_block_idx(bsize);
270 assert(frame_idx < motion_field_info->frame_num);
271 assert(motion_field_info->allocated == 1);
272 return &motion_field_info
273 ->motion_field_array[frame_idx][rf_idx][square_block_idx];
274 }
275
vp9_motion_field_is_mv_set(const MotionField * motion_field,int brow,int bcol)276 int vp9_motion_field_is_mv_set(const MotionField *motion_field, int brow,
277 int bcol) {
278 assert(brow >= 0 && brow < motion_field->block_rows);
279 assert(bcol >= 0 && bcol < motion_field->block_cols);
280 return motion_field->set_mv[brow * motion_field->block_cols + bcol];
281 }
282
vp9_motion_field_get_mv(const MotionField * motion_field,int brow,int bcol)283 int_mv vp9_motion_field_get_mv(const MotionField *motion_field, int brow,
284 int bcol) {
285 assert(brow >= 0 && brow < motion_field->block_rows);
286 assert(bcol >= 0 && bcol < motion_field->block_cols);
287 return motion_field->mf[brow * motion_field->block_cols + bcol];
288 }
289
vp9_motion_field_mi_get_mv(const MotionField * motion_field,int mi_row,int mi_col)290 int_mv vp9_motion_field_mi_get_mv(const MotionField *motion_field, int mi_row,
291 int mi_col) {
292 const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize];
293 const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize];
294 const int brow = mi_row / mi_height;
295 const int bcol = mi_col / mi_width;
296 assert(mi_row % mi_height == 0);
297 assert(mi_col % mi_width == 0);
298 return vp9_motion_field_get_mv(motion_field, brow, bcol);
299 }
300
vp9_motion_field_mi_set_mv(MotionField * motion_field,int mi_row,int mi_col,int_mv mv)301 void vp9_motion_field_mi_set_mv(MotionField *motion_field, int mi_row,
302 int mi_col, int_mv mv) {
303 const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize];
304 const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize];
305 const int brow = mi_row / mi_height;
306 const int bcol = mi_col / mi_width;
307 assert(mi_row % mi_height == 0);
308 assert(mi_col % mi_width == 0);
309 assert(brow >= 0 && brow < motion_field->block_rows);
310 assert(bcol >= 0 && bcol < motion_field->block_cols);
311 motion_field->mf[brow * motion_field->block_cols + bcol] = mv;
312 motion_field->set_mv[brow * motion_field->block_cols + bcol] = 1;
313 }
314
vp9_motion_field_reset_mvs(MotionField * motion_field)315 void vp9_motion_field_reset_mvs(MotionField *motion_field) {
316 memset(motion_field->set_mv, 0,
317 motion_field->block_num * sizeof(*motion_field->set_mv));
318 }
319
log2_approximation(int64_t v)320 static int64_t log2_approximation(int64_t v) {
321 assert(v > 0);
322 if (v < LOG2_TABLE_SIZE) {
323 return log2_table[v];
324 } else {
325 // use linear approximation when v >= 2^10
326 const int slope =
327 1477; // slope = 1 / (log(2) * 1024) * (1 << LOG2_PRECISION)
328 assert(LOG2_TABLE_SIZE == 1 << 10);
329
330 return slope * (v - LOG2_TABLE_SIZE) + (10 << LOG2_PRECISION);
331 }
332 }
333
vp9_nb_mvs_inconsistency(const MV * mv,const int_mv * nb_full_mvs,int mv_num)334 int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs,
335 int mv_num) {
336 // The behavior of this function is to compute log2 of mv difference,
337 // i.e. min log2(1 + row_diff * row_diff + col_diff * col_diff)
338 // against available neighbor mvs.
339 // Since the log2 is monotonically increasing, we can compute
340 // min row_diff * row_diff + col_diff * col_diff first
341 // then apply log2 in the end.
342 int i;
343 int64_t min_abs_diff = INT64_MAX;
344 int cnt = 0;
345 assert(mv_num <= NB_MVS_NUM);
346 for (i = 0; i < mv_num; ++i) {
347 MV nb_mv = nb_full_mvs[i].as_mv;
348 const int64_t row_diff = abs(mv->row - nb_mv.row);
349 const int64_t col_diff = abs(mv->col - nb_mv.col);
350 const int64_t abs_diff = row_diff * row_diff + col_diff * col_diff;
351 assert(nb_full_mvs[i].as_int != INVALID_MV);
352 min_abs_diff = VPXMIN(abs_diff, min_abs_diff);
353 ++cnt;
354 }
355 if (cnt) {
356 return log2_approximation(1 + min_abs_diff);
357 }
358 return 0;
359 }
360
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)361 static FloatMV get_smooth_motion_vector(const FloatMV scaled_search_mv,
362 const FloatMV *tmp_mf,
363 const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
364 int rows, int cols, int row, int col,
365 float alpha) {
366 const FloatMV tmp_mv = tmp_mf[row * cols + col];
367 int idx_row, idx_col;
368 FloatMV avg_nb_mv = { 0.0f, 0.0f };
369 FloatMV mv = { 0.0f, 0.0f };
370 float filter[3][3] = { { 1.0f / 12.0f, 1.0f / 6.0f, 1.0f / 12.0f },
371 { 1.0f / 6.0f, 0.0f, 1.0f / 6.0f },
372 { 1.0f / 12.0f, 1.0f / 6.0f, 1.0f / 12.0f } };
373 for (idx_row = 0; idx_row < 3; ++idx_row) {
374 int nb_row = row + idx_row - 1;
375 for (idx_col = 0; idx_col < 3; ++idx_col) {
376 int nb_col = col + idx_col - 1;
377 if (nb_row < 0 || nb_col < 0 || nb_row >= rows || nb_col >= cols) {
378 avg_nb_mv.row += (tmp_mv.row) * filter[idx_row][idx_col];
379 avg_nb_mv.col += (tmp_mv.col) * filter[idx_row][idx_col];
380 } else {
381 const FloatMV nb_mv = tmp_mf[nb_row * cols + nb_col];
382 avg_nb_mv.row += (nb_mv.row) * filter[idx_row][idx_col];
383 avg_nb_mv.col += (nb_mv.col) * filter[idx_row][idx_col];
384 }
385 }
386 }
387 {
388 // M is the local variance of reference frame
389 float M00 = M[row * cols + col][0];
390 float M01 = M[row * cols + col][1];
391 float M10 = M[row * cols + col][2];
392 float M11 = M[row * cols + col][3];
393
394 float det = (M00 + alpha) * (M11 + alpha) - M01 * M10;
395
396 float inv_M00 = (M11 + alpha) / det;
397 float inv_M01 = -M01 / det;
398 float inv_M10 = -M10 / det;
399 float inv_M11 = (M00 + alpha) / det;
400
401 float inv_MM00 = inv_M00 * M00 + inv_M01 * M10;
402 float inv_MM01 = inv_M00 * M01 + inv_M01 * M11;
403 float inv_MM10 = inv_M10 * M00 + inv_M11 * M10;
404 float inv_MM11 = inv_M10 * M01 + inv_M11 * M11;
405
406 mv.row = inv_M00 * avg_nb_mv.row * alpha + inv_M01 * avg_nb_mv.col * alpha +
407 inv_MM00 * scaled_search_mv.row + inv_MM01 * scaled_search_mv.col;
408 mv.col = inv_M10 * avg_nb_mv.row * alpha + inv_M11 * avg_nb_mv.col * alpha +
409 inv_MM10 * scaled_search_mv.row + inv_MM11 * scaled_search_mv.col;
410 }
411 return mv;
412 }
413
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)414 void vp9_get_smooth_motion_field(const MV *search_mf,
415 const int (*M)[MF_LOCAL_STRUCTURE_SIZE],
416 int rows, int cols, BLOCK_SIZE bsize,
417 float alpha, int num_iters, MV *smooth_mf) {
418 // M is the local variation of reference frame
419 // build two buffers
420 FloatMV *input = (FloatMV *)malloc(rows * cols * sizeof(FloatMV));
421 FloatMV *output = (FloatMV *)malloc(rows * cols * sizeof(FloatMV));
422 int idx;
423 int row, col;
424 int bw = 4 << b_width_log2_lookup[bsize];
425 int bh = 4 << b_height_log2_lookup[bsize];
426 if (!(input && output)) goto fail;
427 // copy search results to input buffer
428 for (idx = 0; idx < rows * cols; ++idx) {
429 input[idx].row = (float)search_mf[idx].row / bh;
430 input[idx].col = (float)search_mf[idx].col / bw;
431 }
432 for (idx = 0; idx < num_iters; ++idx) {
433 FloatMV *tmp;
434 for (row = 0; row < rows; ++row) {
435 for (col = 0; col < cols; ++col) {
436 // note: the scaled_search_mf and smooth_mf are all scaled by macroblock
437 // size
438 const MV search_mv = search_mf[row * cols + col];
439 FloatMV scaled_search_mv = { (float)search_mv.row / bh,
440 (float)search_mv.col / bw };
441 output[row * cols + col] = get_smooth_motion_vector(
442 scaled_search_mv, input, M, rows, cols, row, col, alpha);
443 }
444 }
445 // swap buffers
446 tmp = input;
447 input = output;
448 output = tmp;
449 }
450 // copy smoothed results to output
451 for (idx = 0; idx < rows * cols; ++idx) {
452 smooth_mf[idx].row = (int)(input[idx].row * bh);
453 smooth_mf[idx].col = (int)(input[idx].col * bw);
454 }
455 fail:
456 free(input);
457 free(output);
458 }
459
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])460 void vp9_get_local_structure(const YV12_BUFFER_CONFIG *cur_frame,
461 const YV12_BUFFER_CONFIG *ref_frame,
462 const MV *search_mf,
463 const vp9_variance_fn_ptr_t *fn_ptr, int rows,
464 int cols, BLOCK_SIZE bsize,
465 int (*M)[MF_LOCAL_STRUCTURE_SIZE]) {
466 const int bw = 4 << b_width_log2_lookup[bsize];
467 const int bh = 4 << b_height_log2_lookup[bsize];
468 const int cur_stride = cur_frame->y_stride;
469 const int ref_stride = ref_frame->y_stride;
470 const int width = ref_frame->y_width;
471 const int height = ref_frame->y_height;
472 int row, col;
473 for (row = 0; row < rows; ++row) {
474 for (col = 0; col < cols; ++col) {
475 int cur_offset = row * bh * cur_stride + col * bw;
476 uint8_t *center = cur_frame->y_buffer + cur_offset;
477 int ref_h = row * bh + search_mf[row * cols + col].row;
478 int ref_w = col * bw + search_mf[row * cols + col].col;
479 int ref_offset;
480 uint8_t *target;
481 uint8_t *nb;
482 int search_dist;
483 int nb_dist;
484 int I_row = 0, I_col = 0;
485 // TODO(Dan): handle the case that when reference frame block beyond the
486 // boundary
487 ref_h = ref_h < 0 ? 0 : (ref_h >= height - bh ? height - bh - 1 : ref_h);
488 ref_w = ref_w < 0 ? 0 : (ref_w >= width - bw ? width - bw - 1 : ref_w);
489 // compute search results distortion
490 // TODO(Dan): maybe need to use vp9 function to find the reference block,
491 // to compare with the results of my python code, I first use my way to
492 // compute the reference block
493 ref_offset = ref_h * ref_stride + ref_w;
494 target = ref_frame->y_buffer + ref_offset;
495 search_dist = fn_ptr->sdf(center, cur_stride, target, ref_stride);
496 // compute target's neighbors' distortions
497 // TODO(Dan): if using padding, the boundary condition may vary
498 // up
499 if (ref_h - bh >= 0) {
500 nb = target - ref_stride * bh;
501 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
502 I_row += nb_dist - search_dist;
503 }
504 // down
505 if (ref_h + bh < height - bh) {
506 nb = target + ref_stride * bh;
507 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
508 I_row += nb_dist - search_dist;
509 }
510 if (ref_h - bh >= 0 && ref_h + bh < height - bh) {
511 I_row /= 2;
512 }
513 I_row /= (bw * bh);
514 // left
515 if (ref_w - bw >= 0) {
516 nb = target - bw;
517 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
518 I_col += nb_dist - search_dist;
519 }
520 // down
521 if (ref_w + bw < width - bw) {
522 nb = target + bw;
523 nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride);
524 I_col += nb_dist - search_dist;
525 }
526 if (ref_w - bw >= 0 && ref_w + bw < width - bw) {
527 I_col /= 2;
528 }
529 I_col /= (bw * bh);
530 M[row * cols + col][0] = I_row * I_row;
531 M[row * cols + col][1] = I_row * I_col;
532 M[row * cols + col][2] = I_col * I_row;
533 M[row * cols + col][3] = I_col * I_col;
534 }
535 }
536 }
537