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