• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2022 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 /**
21  *******************************************************************************
22  * @file
23  *  isvcd_mode_mv_resamp.c
24  *
25  * @brief
26  *  Contains routines that resample for SVC resampling
27  *
28  * @author
29  *  Kishore
30  *
31  * @par List of Functions:
32  *  - isvcd_ref_lyr_part_idc()
33  *  - isvcd_check_motion()
34  *  - isvcd_get_min_positive()
35  *  - isvcd_motion_scale_crop_wdw_change()
36  *  - isvcd_interlyr_motion_scale()
37  *  - isvcd_store_motion_map()
38  *  - isvcd_check_mv_diff()
39  *  - isvcd_interlyr_motion_submbmode_pred()
40  *  - isvcd_interlyr_mbmode_pred_bmb()
41  *  - isvcd_populate_ref_idx()
42  *  - isvcd_interlyr_mbmode_pred()
43  *  - isvcd_compute_interlyr_motion_mode()
44  *  - isvcd_interlyr_motion_mode_pred_dyadic()
45  *  - isvcd_compute_scaled_offsets()
46  *  - isvcd_comp_mode_mv_res_init()
47  *
48  * @remarks
49  *  None
50  *
51  *******************************************************************************
52  */
53 
54 #include <assert.h>
55 #include <string.h>
56 #include "ih264_typedefs.h"
57 #include "ih264_macros.h"
58 #include "ih264_platform_macros.h"
59 #include "ih264_defs.h"
60 #include "ih264d_bitstrm.h"
61 #include "ih264d_defs.h"
62 #include "ih264d_debug.h"
63 #include "isvcd_structs.h"
64 #include "ih264d_defs.h"
65 #include "ih264d_parse_cavlc.h"
66 #include "ih264d_mb_utils.h"
67 #include "ih264d_deblocking.h"
68 #include "ih264d_dpb_manager.h"
69 #include "ih264d_mvpred.h"
70 #include "ih264d_inter_pred.h"
71 #include "ih264d_process_pslice.h"
72 #include "ih264d_error_handler.h"
73 #include "ih264d_cabac.h"
74 #include "ih264d_debug.h"
75 #include "ih264d_tables.h"
76 #include "ih264d_parse_slice.h"
77 #include "ih264d_utils.h"
78 #include "ih264d_parse_islice.h"
79 #include "ih264d_process_bslice.h"
80 #include "ih264d_process_intra_mb.h"
81 #include "isvcd_mode_mv_resamp.h"
82 #include "ih264_debug.h"
83 
84 const WORD32 g_i4_dpb_size[16] = {
85     396,  396,   900,   2376,  2376,  2376,  4752,   8100,
86     8100, 18000, 20480, 32768, 32768, 34816, 110400, 184320,
87 };
88 
89 /*****************************************************************************/
90 /* total_coeff and trailing 1's decode table                                 */
91 /*****************************************************************************/
92 
93 /*-----------------------------------------------------------------------*/
94 /* This table consists of info about the NNZ and t1 table                */
95 /*-----------------------------------------------------------------------*/
96 
97 const UWORD16 g_au2_nnz_tbl_offsets[9] = {0, 0, 120, 120, 224, 224, 224, 224, 224};
98 
99 /*-----------------------------------------------------------------------*/
100 /* For given bits in the bitstream, this table consists of 3 parts       */
101 /* | tcoeff(4) | t1s(2) | suffix(2)|                                     */
102 /*-----------------------------------------------------------------------*/
103 
104 const UWORD8 g_au1_codegx_avc[312] = {
105     0,   0,   0,   0,   0,   0,   0,   0,   4,   4,   4,   4,   4,   4,   4,   4,   24,  24,
106     24,  24,  24,  24,  24,  24,  22,  22,  2,   2,   45,  45,  45,  45,  78,  78,  42,  42,
107     61,  61,  61,  61,  94,  94,  58,  58,  38,  38,  18,  18,  110, 110, 74,  74,  54,  54,
108     34,  34,  126, 126, 90,  90,  70,  70,  50,  50,  142, 142, 106, 106, 86,  86,  66,  66,
109     115, 139, 119, 99,  159, 123, 103, 83,  191, 171, 151, 147, 175, 155, 135, 131, 223, 203,
110     183, 179, 207, 187, 167, 163, 255, 235, 231, 211, 239, 219, 215, 195, 242, 242, 250, 250,
111     246, 246, 226, 226, 196, 196, 196, 196, 196, 196, 196, 196,
112 
113     5,   5,   5,   5,   1,   1,   1,   1,   62,  62,  46,  46,  25,  25,  25,  25,  95,  43,
114     39,  3,   78,  78,  22,  22,  110, 110, 58,  58,  54,  54,  18,  18,  126, 126, 74,  74,
115     70,  70,  34,  34,  66,  66,  90,  90,  86,  86,  50,  50,  142, 142, 106, 106, 102, 102,
116     82,  82,  175, 139, 135, 115, 159, 123, 119, 99,  163, 171, 167, 147, 191, 155, 151, 131,
117     223, 203, 199, 195, 207, 187, 183, 179, 231, 227, 235, 215, 218, 218, 210, 210, 254, 254,
118     250, 250, 246, 246, 242, 242, 236, 236, 236, 236, 236, 236, 236, 236,
119 
120     111, 95,  79,  63,  47,  27,  7,   0,   71,  75,  55,  59,  39,  127, 43,  23,  35,  107,
121     103, 19,  143, 91,  87,  3,   99,  83,  139, 67,  159, 123, 119, 51,  191, 171, 151, 131,
122     175, 155, 135, 115, 179, 203, 183, 163, 207, 187, 167, 147, 231, 211, 223, 219, 215, 195,
123     198, 198, 246, 246, 226, 226, 238, 238, 234, 234, 253, 253, 253, 253, 249, 249, 249, 249,
124     240, 240, 240, 240, 240, 240, 240, 240};
125 
126 /*-----------------------------------------------------------------------*/
127 /* For given bits in the bitstream the decoded codeword consists of 2    */
128 /* fields:                                                               */
129 /* | targetcoefftokenidx(6) | suffix(2) |                                */
130 /*-----------------------------------------------------------------------*/
131 
132 const UWORD8 g_au1_codegx_svc[312] = {
133     16,  16,  16,  16,  16,  16,  16,  16,  4,   4,   4,   4,   4,   4,   4,   4,   8,   8,   8,
134     8,   8,   8,   8,   8,   22,  22,  18,  18,  13,  13,  13,  13,  34,  34,  30,  30,  25,  25,
135     25,  25,  50,  50,  46,  46,  42,  42,  38,  38,  66,  66,  62,  62,  58,  58,  54,  54,  82,
136     82,  78,  78,  74,  74,  70,  70,  98,  98,  94,  94,  90,  90,  86,  86,  131, 127, 123, 119,
137     115, 111, 107, 103, 163, 159, 155, 151, 147, 143, 139, 135, 195, 191, 187, 183, 179, 175, 171,
138     167, 231, 227, 223, 219, 215, 211, 207, 203, 246, 246, 242, 242, 238, 238, 234, 234, 196, 196,
139     196, 196, 196, 196, 196, 196, 5,   5,   5,   5,   29,  29,  29,  29,  18,  18,  14,  14,  9,
140     9,   9,   9,   43,  39,  35,  31,  26,  26,  22,  22,  58,  58,  54,  54,  50,  50,  46,  46,
141     74,  74,  70,  70,  66,  66,  62,  62,  90,  90,  86,  86,  82,  82,  78,  78,  106, 106, 102,
142     102, 98,  98,  94,  94,  139, 135, 131, 127, 123, 119, 115, 111, 171, 167, 163, 159, 155, 151,
143     147, 143, 203, 199, 195, 191, 187, 183, 179, 175, 227, 223, 231, 219, 210, 210, 206, 206, 234,
144     234, 246, 246, 242, 242, 238, 238, 212, 212, 212, 212, 212, 212, 212, 212, 31,  27,  23,  19,
145     15,  11,  7,   64,  63,  59,  55,  51,  47,  43,  39,  35,  95,  91,  87,  83,  79,  75,  71,
146     67,  127, 123, 119, 115, 111, 107, 103, 99,  159, 155, 151, 147, 143, 139, 135, 131, 191, 187,
147     183, 179, 175, 171, 167, 163, 219, 215, 211, 207, 203, 199, 194, 194, 234, 234, 230, 230, 226,
148     226, 222, 222, 241, 241, 241, 241, 237, 237, 237, 237, 244, 244, 244, 244, 244, 244, 244, 244,
149     64,  64,  64,  64,  64,  64,  64,  64
150 
151 };
152 
153 /*---------------------------------------------------------------------------*/
154 /* A lookup table, when nC>=8, to get the targetcoefftokenidx                */
155 /*---------------------------------------------------------------------------*/
156 
157 const UWORD8 g_au1_target_coeff_token_idx[68] = {
158     0,  0,  0,  0,  16, 1,  1,  1,  20, 8,  2,  2,  23, 11, 9,  3,  24, 13, 12, 4,  28, 15, 14,
159     5,  30, 17, 18, 6,  31, 21, 22, 7,  32, 25, 26, 10, 36, 33, 29, 19, 40, 37, 34, 27, 44, 41,
160     38, 35, 47, 45, 42, 39, 49, 48, 46, 43, 53, 50, 51, 52, 57, 54, 55, 56, 61, 58, 59, 60};
161 
162 /*---------------------------------------------------------------------------*/
163 /* A lookup table for invTotalCoeff( coeffTokenIdx) and                      */
164 /*  invTrailingOnes( coeffTokenIdx )                                         */
165 /*---------------------------------------------------------------------------*/
166 
167 const UWORD8 g_au1_inv_tcoeff_t1[186] = {
168     0,  5,  10, 15, 4,  9,  19, 14, 23, 8,  13, 18, 27, 12, 17, 22, 31, 16, 21, 26, 35,
169     20, 25, 30, 39, 24, 29, 34, 43, 28, 33, 38, 32, 36, 37, 42, 47, 40, 41, 46, 51, 44,
170     45, 50, 55, 48, 49, 54, 59, 53, 52, 57, 58, 63, 56, 61, 62, 67, 60, 65, 66, 64,
171 
172     0,  5,  10, 15, 19, 9,  23, 4,  13, 14, 27, 8,  17, 18, 31, 12, 21, 22, 35, 16, 25,
173     26, 20, 24, 29, 30, 39, 28, 33, 34, 43, 32, 37, 38, 47, 36, 41, 42, 51, 40, 45, 46,
174     44, 48, 49, 50, 55, 52, 53, 54, 59, 56, 58, 63, 57, 60, 61, 62, 67, 64, 65, 66,
175 
176     0,  5,  10, 15, 19, 23, 27, 31, 9,  14, 35, 13, 18, 17, 22, 21, 4,  25, 26, 39, 8,
177     29, 30, 12, 16, 33, 34, 43, 20, 38, 24, 28, 32, 37, 42, 47, 36, 41, 46, 51, 40, 45,
178     50, 55, 44, 49, 54, 48, 53, 52, 57, 58, 59, 56, 61, 62, 63, 60, 65, 66, 67, 64};
179 
180 /*---------------------------------------------------------------------------*/
181 /* A lookup table for decoding the chroma nnz's and trailing 1's             */
182 /*---------------------------------------------------------------------------*/
183 
184 const UWORD8 g_au1_chroma_dc_nnz_t1[28] = {4,  4, 4,  4,  0,  0,  0,  0,  24, 24, 24, 24, 18, 46,
185                                            22, 2, 49, 49, 33, 33, 41, 41, 37, 37, 57, 57, 53, 53};
186 
187 /*****************************************************************************/
188 /* Total zeroes table                                                        */
189 /*****************************************************************************/
190 
191 /*-----------------------------------------------------------------------*/
192 /* Contains information about tz table. Each entry consists of 3 fields  */
193 /* | table offset (8) | max zeroes(4) | bit offset(2) |                  */
194 /*-----------------------------------------------------------------------*/
195 
196 const UWORD16 g_au2_tz_tbl_offsets[27] = {0,     37,    1178,  2778,  4374,  5718,  7066,
197                                           8666,  10265, 11097, 11925, 12625, 13200, 13516,
198                                           13768, 13956, 14092, 14344, 14532, 14677, 15374,
199                                           16206, 17034, 17609, 17928, 18116, 18240};
200 
201 /*-----------------------------------------------------------------------*/
202 /* Total zero table                                                      */
203 /*-----------------------------------------------------------------------*/
204 
205 const UWORD8 g_au1_tz_tbl[285] = {
206     0,  0,  9,  5,  17, 13, 25, 21, 33, 29, 41, 37, 49, 45, 57, 53, 60, 60,
207 
208     14, 10, 6,  2,  26, 22, 17, 17, 33, 33, 29, 29, 41, 41, 37, 37, 49, 49, 45, 45, 52, 52, 52,
209     52, 56, 26, 14, 10, 6,  18, 2,  29, 29, 33, 33, 21, 21, 41, 41, 37, 37, 48, 48, 48, 48, 44,
210     44, 44, 44, 52, 26, 22, 18, 6,  14, 10, 33, 33, 37, 37, 29, 29, 41, 41, 1,  1,  44, 44, 44,
211     44, 48, 26, 22, 18, 14, 6,  2,  29, 29, 33, 33, 9,  9,  40, 40, 40, 40, 36, 36, 36, 36, 44,
212     22, 18, 14, 10, 29, 29, 25, 25, 36, 36, 36, 36, 32, 32, 32, 32, 4,  4,  4,  4,  0,  0,  0,
213     0,  40, 14, 10, 21, 21, 25, 25, 17, 17, 32, 32, 32, 32, 28, 28, 28, 28, 4,  4,  4,  4,  0,
214     0,  0,  0,  36, 21, 17, 25, 13, 28, 28, 4,  4,  8,  8,  0,  0,  32,
215 
216     17, 13, 24, 24, 20, 20, 8,  8,  28, 28, 0,  0,  4,
217 
218     17, 13, 20, 20, 8,  8,  24, 24, 0,  0,  4,
219 
220     16, 16, 13, 21, 8,  8,  4,  4,  0,
221 
222     12, 8,  16, 4,  0,
223 
224     8,  12, 4,  0,
225 
226     8,  4,  0,
227 
228     4,  0,
229 
230     0,  4,  8,  12,
231 
232     0,  4,  8,
233 
234     0,  4,
235 
236     0,  0,  5,  9,  13, 17, 20, 20, 24, 24, 28,        /*11*/
237 
238     14, 18, 22, 26, 4,  4,  4,  4,  8,  8,  8,  8,  0, /*13*/
239 
240     13, 13, 18, 22, 8,  8,  8,  8,  4,  4,  4,  4,  0, /*13*/
241 
242     13, 13, 2,  18, 8,  8,  8,  8,  4,                 /*9*/
243 
244     9,  13, 4,  4,  0,                                 /*5*/
245 
246     8,  4,  0,                                         /*3*/
247 
248     4,  0                                              /*2*/
249 };
250 
251 /*****************************************************************************/
252 /* Run before table                                                          */
253 /*****************************************************************************/
254 
255 const UWORD8 g_au1_run_bef_tbl[64] = {0,  0,  0,  0,  0,  0,  0, 0, 5,  5,  5,  5,  1,  1,  1, 1,
256                                       10, 10, 6,  6,  1,  1,  1, 1, 14, 14, 10, 10, 6,  6,  2, 2,
257                                       19, 15, 10, 10, 6,  6,  2, 2, 23, 19, 15, 11, 6,  6,  2, 2,
258                                       7,  11, 19, 15, 27, 23, 2, 2, 27, 27, 23, 19, 15, 11, 7, 3};
259 
260 /*****************************************************************************/
261 /* CBP table                                                                 */
262 /*****************************************************************************/
263 
264 /*-----------------------------------------------------------------------*/
265 /* Contains both inter and intra tables                                  */
266 /*-----------------------------------------------------------------------*/
267 
268 const UWORD8 g_au1_intra_cbp[48] = {47, 31, 15, 0,  23, 27, 29, 30, 7,  11, 13, 14, 39, 43, 45, 46,
269                                     16, 3,  5,  10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1,  2,  4,
270                                     8,  17, 18, 20, 24, 6,  9,  22, 25, 32, 33, 34, 36, 40, 38, 41};
271 
272 const UWORD8 g_au1_inter_cbp[48] = {0,  16, 1,  2,  4,  8,  32, 3,  5,  10, 12, 15, 47, 7,  11, 13,
273                                     14, 6,  9,  31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
274                                     17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41};
275 
276 /*---------------------------------------------------------------------------*/
277 /* Contains the cbp table for intra16x16 mb type                             */
278 /*---------------------------------------------------------------------------*/
279 
280 const UWORD8 g_au1_intra16x16_cbp[6] = {0, 16, 32, 15, 31, 47};
281 
282 /*****************************************************************************/
283 /* Inverse scan table                                                        */
284 /*****************************************************************************/
285 
286 /*-----------------------------------------------------------------------*/
287 /* Regular inverse scan tables                                           */
288 /*-----------------------------------------------------------------------*/
289 
290 const UWORD8 g_au1_regular_inv_scan[16] = {0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15};
291 
292 const UWORD8 g_au1_regular_inv_scan_field[16] = {0, 4, 1,  8,  12, 5, 9,  13,
293                                                  2, 6, 10, 14, 3,  7, 11, 15};
294 
295 const UWORD8 g_au1_regular_inv_scan8x8[64] = {
296     0,  1,  8,  16, 9,  2,  3,  10, 17, 24, 32, 25, 18, 11, 4,  5,  12, 19, 26, 33, 40, 48,
297     41, 34, 27, 20, 13, 6,  7,  14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23,
298     30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
299 
300 UWORD8 const g_au1_subblk_8x8_offsets[16] = {0,   0,   0,   0,   64,  64,  64,  64,
301                                              128, 128, 128, 128, 192, 192, 192, 192};
302 
303 /*---------------------------------------------------------------------------*/
304 /* 8x8 inverse scan tables                                               */
305 /*---------------------------------------------------------------------------*/
306 
307 const UWORD8 g_au1_prog_deinter_inv_scan[4][16] = {
308     {0, 9, 17, 18, 12, 40, 27, 7, 35, 57, 29, 30, 58, 38, 53, 47},  /* for First subblock  */
309     {1, 2, 24, 11, 19, 48, 20, 14, 42, 50, 22, 37, 59, 31, 60, 55}, /* for second subblock */
310     {8, 3, 32, 4, 26, 41, 13, 21, 49, 43, 15, 44, 52, 39, 61, 62},  /* for third subblock  */
311     {16, 10, 25, 5, 33, 34, 6, 28, 56, 36, 23, 51, 45, 46, 54, 63}  /* for fourth subblock */
312 };
313 
314 const UWORD8 g_au1_prog_8x8_inv_scan[64] = {
315     0,  1,  8,  16, 9,  2,  3,  10, 17, 24, 32, 25, 18, 11, 4,  5,  12, 19, 26, 33, 40, 48,
316     41, 34, 27, 20, 13, 6,  7,  14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23,
317     30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
318 
319 /*****************************************************************************/
320 /* SUBMB partition tables                                                    */
321 /*****************************************************************************/
322 
323 /*---------------------------------------------------------------------------*/
324 /* Number of sub Mb's in 8x8 partition mode                              */
325 /*---------------------------------------------------------------------------*/
326 
327 const UWORD8 g_au1_num_sub_mb_part[4] = {1, 2, 2, 4};
328 
329 /*---------------------------------------------------------------------------*/
330 /* Width and height of submb's in terms of 4x4 (for 8x8 partition mode)  */
331 /*---------------------------------------------------------------------------*/
332 
333 const UWORD8 g_au1_sub_mb_part_wd[4] = {2, 2, 1, 1};
334 
335 const UWORD8 g_au1_sub_mb_part_ht[4] = {2, 1, 2, 1};
336 
337 /*---------------------------------------------------------------------------*/
338 /* SubMB mc mode table                                                   */
339 /*---------------------------------------------------------------------------*/
340 
341 const UWORD8 g_au1_sub_mb_mc_mode[20] = {SUBMB_8x8, SUBMB_8x4, SUBMB_4x8, SUBMB_4x4, SUBMB_8x8,
342                                          SUBMB_8x8, SUBMB_8x8, SUBMB_8x8, SUBMB_8x4, SUBMB_4x8,
343                                          SUBMB_8x4, SUBMB_4x8, SUBMB_8x4, SUBMB_4x8, SUBMB_4x4,
344                                          SUBMB_4x4, SUBMB_4x4,
345                                          /* Self defined modes B DIRECT8x8 */
346                                          SUBMB_4x4, SUBMB_4x4, SUBMB_4x4};
347 
348 /*---------------------------------------------------------------------------*/
349 /* SubMb prediciton mode table                                           */
350 /*---------------------------------------------------------------------------*/
351 
352 const UWORD8 g_au1_sub_mb_pred_mode[20] = {
353     PRED_L0,
354     PRED_L0,
355     PRED_L0,
356     PRED_L0,
357     B_DIRECT,
358     PRED_L0,
359     PRED_L1,
360     BI_PRED,
361     PRED_L0,
362     PRED_L0,
363     PRED_L1,
364     PRED_L1,
365     BI_PRED,
366     BI_PRED,
367     PRED_L0,
368     PRED_L1,
369     BI_PRED,
370     /* Self defined modes for B DIRECT8x8 */
371     BI_PRED,
372     PRED_L0,
373     PRED_L1,
374 };
375 
376 /*****************************************************************************/
377 /* MB partition tables                                                       */
378 /*****************************************************************************/
379 
380 /*---------------------------------------------------------------------------*/
381 /* Number of MB partitions                                               */
382 /*---------------------------------------------------------------------------*/
383 
384 const UWORD8 g_au1_num_mb_part[5] = {1, 2, 2, 4, 4};
385 
386 /*---------------------------------------------------------------------------*/
387 /* MB partitions width and height in terms of submbs                     */
388 /*---------------------------------------------------------------------------*/
389 
390 const UWORD8 g_au1_mb_part_wd[5] = {4, 4, 2, 2, 2};
391 
392 const UWORD8 g_au1_mb_part_ht[5] = {4, 2, 4, 2, 2};
393 
394 /*---------------------------------------------------------------------------*/
395 /* MB MC mode of mb partitions                                               */
396 /*---------------------------------------------------------------------------*/
397 
398 const UWORD8 g_au1_mb_mc_mode[31] = {
399     PRED_16x16, PRED_16x8, PRED_8x16, PRED_8x8, PRED_8x8R0, PRED_16x16, PRED_16x16, PRED_16x16,
400     PRED_16x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8,
401     PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8,
402     PRED_8x16, PRED_16x8, PRED_8x16, PRED_8x8,
403     /* Self defined modes for B_SKIP and DIRECT16x16 */
404     PRED_8x8, PRED_8x8, PRED_8x8};
405 
406 /*---------------------------------------------------------------------------*/
407 /* MB prediciton mode table                                                  */
408 /*---------------------------------------------------------------------------*/
409 
410 const WORD8 g_au1_mb_pred_mode[2][32] = {
411     {
412         PRED_L0,
413         PRED_L0,
414         PRED_L0,
415         PRED_INVALID,
416         PRED_INVALID,
417         B_DIRECT,
418         PRED_L0,
419         PRED_L1,
420         BI_PRED,
421         PRED_L0,
422         PRED_L0,
423         PRED_L1,
424         PRED_L1,
425         PRED_L0,
426         PRED_L0,
427         PRED_L1,
428         PRED_L1,
429         PRED_L0,
430         PRED_L0,
431         PRED_L1,
432         PRED_L1,
433         BI_PRED,
434         BI_PRED,
435         BI_PRED,
436         BI_PRED,
437         BI_PRED,
438         BI_PRED,
439         PRED_INVALID,
440         /* Self defined modes for B_SKIP and DIRECT16x16 */
441         BI_PRED,
442         PRED_L0,
443         PRED_L1,
444     },
445     {PRED_INVALID, PRED_L0, PRED_L0, PRED_INVALID, PRED_INVALID, PRED_INVALID, PRED_INVALID,
446      PRED_INVALID, PRED_INVALID, PRED_L0, PRED_L0, PRED_L1, PRED_L1, PRED_L1, PRED_L1, PRED_L0,
447      PRED_L0, BI_PRED, BI_PRED, BI_PRED, BI_PRED, PRED_L0, PRED_L0, PRED_L1, PRED_L1, BI_PRED,
448      BI_PRED, PRED_INVALID,
449      /* Self defined modes for B_SKIP and DIRECT16x16 */
450      PRED_INVALID, PRED_INVALID, PRED_INVALID}};
451 
452 /*---------------------------------------------------------------------------*/
453 /* Neighbour partition address offsets table                                 */
454 /*---------------------------------------------------------------------------*/
455 
456 const UWORD8 g_au1_neighbors_addr_offset[2][16 * 4] = {
457     /* Each row has current, left, top, top right */
458     /* Each row corresponds to sub_mb_num */
459 
460     /* Partition width 4 */
461     {
462         0,  0,  0, 1, 1,  0, 1, 2, 2,  1,  2, 3, 3,  2,  3,  5,  4,  1,  0,  1,  5, 4,
463         1,  0,  6, 5, 2,  3, 7, 6, 3,  2,  8, 2, 4,  5,  9,  8,  5,  6,  10, 9,  6, 7,
464         11, 10, 7, 6, 12, 3, 8, 9, 13, 12, 9, 8, 14, 13, 10, 11, 15, 14, 11, 10,
465     },
466     /* Partition width 8 */
467     {/* Only alternate rows are valid */
468      0, 0, 0, 2, 0,  0, 0, 0,  2, 1, 2, 4, 0,  0,  0,  0, 4, 1, 0,  2, 0, 0,
469      0, 0, 6, 5, 2,  1, 0, 0,  0, 0, 8, 2, 4,  6,  0,  0, 0, 0, 10, 9, 6, 5,
470      0, 0, 0, 0, 12, 3, 8, 10, 0, 0, 0, 0, 14, 13, 10, 9, 0, 0, 0,  0}};
471 
472 /*---------------------------------------------------------------------------*/
473 /* Reference index comparison map table                                      */
474 /*---------------------------------------------------------------------------*/
475 const UWORD8 g_au1_ref_idx_comp_map[16 * 2 * 16] = {
476     /* SUB MB NUMBER 0 */
477     0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 4, 5, 6, 7, /* Partition width 4 */
478     0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
479 
480     /* SUB MB NUMBER 1 */
481     1, 1, 7, 7, 5, 5, 7, 7, 1, 1, 3, 3, 1, 1, 7, 7, /* Partition width 4 */
482     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
483 
484     /* SUB MB NUMBER 2 */
485     0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, /* Partition width 4 */
486     0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
487 
488     /* SUB MB NUMBER 3 */
489     1, 1, 7, 7, 1, 1, 7, 7, 1, 1, 3, 3, 5, 5, 7, 7, /* Partition width 4 */
490     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
491 
492     /* SUB MB NUMBER 4 */
493     6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
494     2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
495 
496     /* SUB MB NUMBER 5 */
497     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
498     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
499 
500     /* SUB MB NUMBER 6 */
501     6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
502     2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
503 
504     /* SUB MB NUMBER 7 */
505     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
506     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
507 
508     /* SUB MB NUMBER 8 */
509     0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, /* Partition width 4 */
510     0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
511 
512     /* SUB MB NUMBER 9 */
513     1, 1, 3, 3, 5, 5, 7, 7, 1, 1, 3, 3, 5, 5, 7, 7, /* Partition width 4 */
514     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
515 
516     /* SUB MB NUMBER 10 */
517     0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, /* Partition width 4 */
518     0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
519 
520     /* SUB MB NUMBER 11 */
521     1, 1, 7, 7, 1, 1, 7, 7, 1, 1, 7, 7, 1, 1, 7, 7, /* Partition width 4 */
522     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
523 
524     /* SUB MB NUMBER 12 */
525     6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
526     2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
527 
528     /* SUB MB NUMBER 13 */
529     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
530     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
531 
532     /* SUB MB NUMBER 14 */
533     6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
534     2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
535 
536     /* SUB MB NUMBER 15 */
537     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
538     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* Partition width 8 */
539 
540 };
541 
542 /*-----------------------------------------------------------------------*/
543 /* SUB MB index                                                          */
544 /*-----------------------------------------------------------------------*/
545 
546 const UWORD8 g_au1_sub_mb_idx_mod[16] = {
547     0, 0,      /* 16x16 */
548     0, 8,      /* 16x8 */
549     0, 2,      /* 8x16 */
550     0, 0,      /* 8x8 */
551     0, 4,      /* 8x4 */
552     0, 1,      /* 4x8 */
553     0, 1, 3, 1 /* 4x4 */
554 };
555 
556 /*****************************************************************************/
557 /* Raster scan offset table                                                  */
558 /*****************************************************************************/
559 
560 const UWORD8 g_au1_sub_blk_rast_scan_offsets[16] = {0, 1, 4,  5,  2,  3,  6,  7,
561                                                     8, 9, 12, 13, 10, 11, 14, 15};
562 
563 /*****************************************************************************/
564 /*Motion and mode computation tables                                         */
565 /*****************************************************************************/
566 
567 /* B MB TYPES */
568 const UWORD8 g_au1_eb_mb_type[36] = {
569     B_L0_16x16,   B_L0_16x16,   B_L0_16x16,   B_L1_16x16,   B_L1_16x16,   B_L1_16x16,
570     B_BI_16x16,   B_BI_16x16,   B_BI_16x16,   B_L0_L0_16x8, B_L0_L1_16x8, B_L0_BI_16x8,
571     B_L1_L0_16x8, B_L1_L1_16x8, B_L1_BI_16x8, B_BI_L0_16x8, B_BI_L1_16x8, B_BI_BI_16x8,
572     B_L0_L0_8x16, B_L0_L1_8x16, B_L0_BI_8x16, B_L1_L0_8x16, B_L1_L1_8x16, B_L1_BI_8x16,
573     B_BI_L0_8x16, B_BI_L1_8x16, B_BI_BI_8x16, B_8x8,        B_8x8,        B_8x8,
574     B_8x8,        B_8x8,        B_8x8,        B_8x8,        B_8x8,        B_8x8};
575 
576 /* P MB TYPES */
577 const UWORD8 g_au1_ep_mb_type[4] = {P_L0_16x16, P_L0_L0_16x8, P_L0_L0_8x16, P_8x8};
578 
579 /* P SUB MB TYPES */
580 const UWORD8 g_au1_ep_submb_type[4] = {P_L0_8x8, P_L0_8x4, P_L0_4x8, P_L0_4x4};
581 
582 /* B SUB MB TYPES */
583 const UWORD8 g_au1_eb_submb_type[12] = {B_L0_8x8, B_L1_8x8, B_BI_8x8, B_L0_8x4, B_L1_8x4, B_BI_8x4,
584                                         B_L0_4x8, B_L1_4x8, B_BI_4x8, B_L0_4x4, B_L1_4x4, B_BI_4x4};
585 
586 /*****************************************************************************/
587 /* Deblocking related tables                                                 */
588 /*****************************************************************************/
589 
590 /* chroma QP values luma Qp is used to index to this table */
591 const UWORD8 g_au1_qp_scale_chroma[52] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
592                                           13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
593                                           26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34, 35,
594                                           35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39};
595 
596 /* alpha table used in deblocking */
597 const UWORD8 g_au1_alpha_table[52] = {0,  0,  0,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
598                                       0,  0,  0,  4,   4,   5,   6,   7,   8,   9,   10,  12,  13,
599                                       15, 17, 20, 22,  25,  28,  32,  36,  40,  45,  50,  56,  63,
600                                       71, 80, 90, 101, 113, 127, 144, 162, 182, 203, 226, 255, 255};
601 
602 /* clip table used in deblcoking */
603 const UWORD8 g_au1_clip_table_deblk[75] = {
604     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,
605     8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
606     27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
607     46, 47, 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51};
608 
609 /* Beta table used in deblocking*/
610 const UWORD8 g_au1_beta_table[52] = {
611     0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  2,  3,  3,  3,  3,  4,  4,  4,
612     6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18};
613 
614 /* clip table used baed on index BS and other vakues */
615 const UWORD8 g_au1_clip_table[52][4] = {
616     {0, 0, 0, 0},    {0, 0, 0, 0},   {0, 0, 0, 0},   {0, 0, 0, 0},   {0, 0, 0, 0},
617     {0, 0, 0, 0},    {0, 0, 0, 0},   {0, 0, 0, 0},   {0, 0, 0, 0},   {0, 0, 0, 0},
618     {0, 0, 0, 0},    {0, 0, 0, 0},   {0, 0, 0, 0},   {0, 0, 0, 0},   {0, 0, 0, 0},
619     {0, 0, 0, 0},    {0, 0, 0, 0},   {0, 0, 0, 1},   {0, 0, 0, 1},   {0, 0, 0, 1},
620     {0, 0, 0, 1},    {0, 0, 1, 1},   {0, 0, 1, 1},   {0, 1, 1, 1},   {0, 1, 1, 1},
621     {0, 1, 1, 1},    {0, 1, 1, 1},   {0, 1, 1, 2},   {0, 1, 1, 2},   {0, 1, 1, 2},
622     {0, 1, 1, 2},    {0, 1, 2, 3},   {0, 1, 2, 3},   {0, 2, 2, 3},   {0, 2, 2, 4},
623     {0, 2, 3, 4},    {0, 2, 3, 4},   {0, 3, 3, 5},   {0, 3, 4, 6},   {0, 3, 4, 6},
624     {0, 4, 5, 7},    {0, 4, 5, 8},   {0, 4, 6, 9},   {0, 5, 7, 10},  {0, 6, 8, 11},
625     {0, 6, 8, 13},   {0, 7, 10, 14}, {0, 8, 11, 16}, {0, 9, 12, 18}, {0, 10, 13, 20},
626     {0, 11, 15, 23}, {0, 13, 17, 25}};
627 
628 /*****************************************************************************/
629 /* QUANTIZATION TABLES                                                       */
630 /*****************************************************************************/
631 
632 const UWORD8 g_au1_luma_to_chroma_qp_map[52] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
633                                                 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
634                                                 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34, 35,
635                                                 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39};
636 
637 const UWORD8 g_au1_scale_factor_table[6] = {8, 9, 10, 11, 13, 14};
638 
639 /*****************************************************************************/
640 /* SCALING MATRICIES TABLE                                                   */
641 /*****************************************************************************/
642 
643 /* Default table used for INTRA 4x4 blocks */
644 const WORD16 g_ai2_default_intra4x4[16] = {6,  13, 13, 20, 20, 20, 28, 28,
645                                            28, 28, 32, 32, 32, 37, 37, 42};
646 
647 /* Default table used for INTER 4x4 blocks */
648 const WORD16 g_ai2_default_inter4x4[16] = {10, 14, 14, 20, 20, 20, 24, 24,
649                                            24, 24, 27, 27, 27, 30, 30, 34};
650 
651 /* Flat table used for 4x4 blocks */
652 const WORD16 g_ai2_flat_4x4[16] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
653 
654 /* Flat table used for 4x4 blocks */
655 const WORD16 g_ai2_flat_8x8[64] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
656                                    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
657                                    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
658                                    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
659 
660 /* Default table used for INTRA 8x8 blocks */
661 const WORD16 g_ai2_default_intra8x8[64] = {
662     6,  10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25,
663     25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31,
664     31, 31, 31, 31, 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42};
665 
666 /* Default table used for INTER 8x8 blocks */
667 const WORD16 g_ai2_default_inter8x8[64] = {
668     9,  13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22,
669     22, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27,
670     27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35};
671 
672 /* V(qp%6) table */
673 const WORD8 g_ai1_scale_quant_matrix[6][16] = {
674     {10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16},
675     {11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18},
676     {13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20},
677     {14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23},
678     {16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25},
679     {18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29}};
680 
681 /* V(qp%6) table for 8x8 */
682 const UWORD8 g_ai1_8x8_scale_quant_matrix[6][64] = {
683     {20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25,
684      18, 25, 18, 25, 18, 25, 19, 24, 24, 19, 19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24,
685      24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18},
686     {22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28,
687      19, 28, 19, 28, 19, 28, 21, 26, 26, 21, 21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26,
688      26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19},
689     {26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33,
690      23, 33, 23, 33, 23, 33, 24, 31, 31, 24, 24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31,
691      31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23},
692     {28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35,
693      25, 35, 25, 35, 25, 35, 26, 33, 33, 26, 26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33,
694      33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25},
695     {32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40,
696      28, 40, 28, 40, 28, 40, 30, 38, 38, 30, 30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38,
697      38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28},
698     {36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46,
699      32, 46, 32, 46, 32, 46, 34, 43, 43, 34, 34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43,
700      43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32}
701 
702 };
703 
704 /*****************************************************************************/
705 /* CABAC engine tables                                                       */
706 /*****************************************************************************/
707 
708 const UWORD8 g_au1_sig_coeff_ctxt_inc[64] = {
709     0, 1, 2, 3,  4,  5,  5,  4, 4, 3,  3,  4, 4,  4,  5,  5,  4,  4,  4,  4,  3,  3,
710     6, 7, 7, 7,  8,  9,  10, 9, 8, 7,  7,  6, 11, 12, 13, 11, 6,  7,  8,  9,  14, 10,
711     9, 8, 6, 11, 12, 13, 11, 6, 9, 14, 10, 9, 11, 12, 13, 11, 14, 10, 12, 255};
712 
713 const UWORD8 g_au1_last_coeff_ctxt_inc[64] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
714                                               2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
715                                               3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
716                                               5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 255};
717 
718 /*-----------------------------------------------------------------------*/
719 /* Range table                                                           */
720 /*-----------------------------------------------------------------------*/
721 
722 const UWORD8 g_au1_cabac_rtab[64][4] = {
723     {128, 176, 208, 240}, {128, 167, 197, 227}, {128, 158, 187, 216}, {123, 150, 178, 205},
724     {116, 142, 169, 195}, {111, 135, 160, 185}, {105, 128, 152, 175}, {100, 122, 144, 166},
725     {95, 116, 137, 158},  {90, 110, 130, 150},  {85, 104, 123, 142},  {81, 99, 117, 135},
726     {77, 94, 111, 128},   {73, 89, 105, 122},   {69, 85, 100, 116},   {66, 80, 95, 110},
727     {62, 76, 90, 104},    {59, 72, 86, 99},     {56, 69, 81, 94},     {53, 65, 77, 89},
728     {51, 62, 73, 85},     {48, 59, 69, 80},     {46, 56, 66, 76},     {43, 53, 63, 72},
729     {41, 50, 59, 69},     {39, 48, 56, 65},     {37, 45, 54, 62},     {35, 43, 51, 59},
730     {33, 41, 48, 56},     {32, 39, 46, 53},     {30, 37, 43, 50},     {29, 35, 41, 48},
731     {27, 33, 39, 45},     {26, 31, 37, 43},     {24, 30, 35, 41},     {23, 28, 33, 39},
732     {22, 27, 32, 37},     {21, 26, 30, 35},     {20, 24, 29, 33},     {19, 23, 27, 31},
733     {18, 22, 26, 30},     {17, 21, 25, 28},     {16, 20, 23, 27},     {15, 19, 22, 25},
734     {14, 18, 21, 24},     {14, 17, 20, 23},     {13, 16, 19, 22},     {12, 15, 18, 21},
735     {12, 14, 17, 20},     {11, 14, 16, 19},     {11, 13, 15, 18},     {10, 12, 15, 17},
736     {10, 12, 14, 16},     {9, 11, 13, 15},      {9, 11, 12, 14},      {8, 10, 12, 14},
737     {8, 9, 11, 13},       {7, 9, 11, 12},       {7, 9, 10, 12},       {7, 8, 10, 11},
738     {6, 8, 9, 11},        {6, 7, 9, 10},        {6, 7, 8, 9},         {2, 2, 2, 2}};
739 
740 /*-----------------------------------------------------------------------*/
741 /* Next state MPS_LPS table                                                  */
742 /*-----------------------------------------------------------------------*/
743 
744 const UWORD16 g_au2_cabac_next_state_mps_lps[64] = {
745     0x100,  0x200,  0x301,  0x402,  0x502,  0x604,  0x704,  0x805,  0x906,  0xa07,  0xb08,
746     0xc09,  0xd09,  0xe0b,  0xf0b,  0x100c, 0x110d, 0x120d, 0x130f, 0x140f, 0x1510, 0x1610,
747     0x1712, 0x1812, 0x1913, 0x1a13, 0x1b15, 0x1c15, 0x1d16, 0x1e16, 0x1f17, 0x2018, 0x2118,
748     0x2219, 0x231a, 0x241a, 0x251b, 0x261b, 0x271c, 0x281d, 0x291d, 0x2a1e, 0x2b1e, 0x2c1e,
749     0x2d1f, 0x2e20, 0x2f20, 0x3021, 0x3121, 0x3221, 0x3322, 0x3422, 0x3523, 0x3623, 0x3723,
750     0x3824, 0x3924, 0x3a24, 0x3b25, 0x3c25, 0x3d25, 0x3e26, 0x3e26, 0x3f3f};
751 
752 /*****************************************************************************/
753 /*                                                                           */
754 /*  Function Name :  isvcd_ref_lyr_part_idc                                   */
755 /*                                                                           */
756 /*  Description   : this function computes the reference layer partition map */
757 /*                  for all the 4x4 partitions of the current MB             */
758 /*                                                                           */
759 /*  Inputs        : pv_comp_mode_mv_ctxt : mode motion handle                */
760 /*                  ai4_ref_part_idc : pointer to reference layer partition  */
761 /*                    indentification                                        */
762 /*                  pi4_intra_flag  : pointer to store the intra flag        */
763 /*                  i4_mb_addr      : current MB address                     */
764 /*  Globals       : none                                                     */
765 /*  Processing    : it projects the each 4x4 block onto the refernce layer   */
766 /*                  and gets the co-located location. it checks the  MB mode */
767 /*                  of the reference layer MB for INTRA and performs actions */
768 /*                  appropriately. it modifies the intra declared partitions */
769 /*                  for non-dydaic cases                                     */
770 /*  Outputs       : packed offset x and offset y in the refernce layer array */
771 /*  Returns       : none                                                     */
772 /*                                                                           */
773 /*  Issues        : none                                                     */
774 /*                                                                           */
775 /*  Revision History:                                                        */
776 /*                                                                           */
777 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
778 /*         06 09 2021   vijayakumar          creation                        */
779 /*                                                                           */
780 /*****************************************************************************/
isvcd_ref_lyr_part_idc(void * pv_comp_mode_mv_ctxt,WORD32 ai4_ref_part_idc[4][4],WORD32 * pi4_intra_flag,void * pv_mb_params)781 void isvcd_ref_lyr_part_idc(void *pv_comp_mode_mv_ctxt, WORD32 ai4_ref_part_idc[4][4],
782                             WORD32 *pi4_intra_flag, void *pv_mb_params)
783 {
784     /*! Flow of the module is as follows                                   */
785     /*! 1. runs loops over the 16 4x4 blocks and gets teh reference layer
786     patition information by projecting the 1,1 locations of
787     each block                                                      */
788     /*! 2. if the projected partition is in INTRA MB then its stores -1
789     to the partition idc array                                      */
790     /*! 3. if projected partition is in INTER MB then it packs and stores
791     the offsets form the starting pointer in the part_idc array     */
792     /*! 4. IN non dyaydic cases. the part idc having -1 are replaced by
793     neighbours if the current MB projected is not INTRA             */
794     /*! 5. the -1 values are replaced first on a 4x4 inside an 8x8 basis   */
795     /*! 6. in second iteration -1 are replaced at an 8x8 basis             */
796     /*! 7. stores the intra MB status in the location given                */
797 
798     mode_motion_ctxt_t *ps_ctxt;
799     mode_motion_lyr_ctxt *ps_lyr_mem;
800     inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
801     WORD32 i4_blk_y, i4_blk_x;
802     WORD32 i4_mb_x, i4_mb_y;
803     WORD32 i4_intra_mb_flag;
804     WORD32 i4_inter_lyr_mb_prms_stride;
805     dec_mb_info_t *ps_mb_params;
806 
807     ps_mb_params = (dec_mb_info_t *) pv_mb_params;
808     ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
809 
810     /* get the current layer ctxt */
811     ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
812 
813     /* ref layer mb mode */
814     ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) ps_lyr_mem->s_ref_mb_mode.pv_buffer;
815     i4_inter_lyr_mb_prms_stride = ps_lyr_mem->s_ref_mb_mode.i4_num_element_stride;
816 
817     /* derive the MB_X and MB_Y for the current MB */
818     i4_mb_x = ps_mb_params->u2_mbx;
819     i4_mb_y = ps_mb_params->u2_mby;
820 
821     /* set the intra MB flag to default TRUE */
822     i4_intra_mb_flag = SVCD_TRUE;
823 
824     /*-----------------------------------------------------------------------*/
825     /* derive the reference layer part idc for all 16 partitions             */
826     /*-----------------------------------------------------------------------*/
827     for(i4_blk_y = 0; i4_blk_y < NUM_SUB_MB_PARTS; i4_blk_y++)
828     {
829         for(i4_blk_x = 0; i4_blk_x < NUM_SUB_MB_PARTS; i4_blk_x++)
830         {
831             WORD32 i4_curr_x, i4_curr_y;
832             WORD32 i4_ref_x, i4_ref_y;
833             WORD32 i4_ref_mb_x, i4_ref_mb_y;
834             WORD8 i1_ref_mb_mode;
835             inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms_temp;
836 
837             i4_curr_x = (i4_mb_x << 4) + (i4_blk_x << 2) + 1;
838             i4_curr_y = (i4_mb_y << 4) + (i4_blk_y << 2) + 1;
839 
840             /* get the colocated position in the refernce layer */
841             i4_ref_x = ps_lyr_mem->pi2_ref_loc_x[i4_curr_x];
842             i4_ref_y = ps_lyr_mem->pi2_ref_loc_y[i4_curr_y];
843 
844             i4_ref_x = CLIP3(0, ((ps_lyr_mem->i4_ref_width) - 1), i4_ref_x);
845 
846             i4_ref_y = CLIP3(0, ((ps_lyr_mem->i4_ref_height) - 1), i4_ref_y);
847 
848             /* get the reference mb x and y */
849             i4_ref_mb_x = (i4_ref_x >> 4);
850             i4_ref_mb_y = (i4_ref_y >> 4);
851 
852             /* get the appropriate mb params in reference layer */
853             ps_inter_lyr_mb_prms_temp = ps_inter_lyr_mb_prms + i4_ref_mb_x;
854             ps_inter_lyr_mb_prms_temp += i4_ref_mb_y * i4_inter_lyr_mb_prms_stride;
855 
856             i1_ref_mb_mode = ps_inter_lyr_mb_prms_temp->i1_mb_mode;
857 
858             /* check if the MB mode of the refernce MB is Intra*/
859             if(i1_ref_mb_mode > SVC_INTER_MB)
860             {
861                 /* store the -1 value */
862                 ai4_ref_part_idc[i4_blk_y][i4_blk_x] = -1;
863             }
864             else
865             {
866                 /* pack and store the reference x and y */
867                 ai4_ref_part_idc[i4_blk_y][i4_blk_x] = (i4_ref_y << 16) + i4_ref_x;
868                 i4_intra_mb_flag = SVCD_FALSE;
869             }
870 
871         } /* end of block x loop */
872 
873     }     /* end of block y loop */
874 
875     /*************************************************************************/
876     /* if the restricted spatial resolution change flag is 0                 */
877     /* modify the part_idc for all the partitions                            */
878     /*************************************************************************/
879     if(SVCD_FALSE == (ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag) &&
880        (SVCD_FALSE == i4_intra_mb_flag))
881     {
882         /* replace values of "-1" on a 4x4 block basis */
883         WORD32 i4_xp, i4_yp;
884         WORD32 i4_indx_x, i4_indx_y;
885         WORD32 ai4_flag_8x8[2][2] = {SVCD_FALSE};
886 
887         /* loop over (4) 8x8 partitions */
888         for(i4_yp = 0; i4_yp < 2; i4_yp++)
889         {
890             for(i4_xp = 0; i4_xp < 2; i4_xp++)
891             {
892                 WORD32 i4_xs, i4_ys;
893                 WORD32 ai4_flag_4x4[2][2] = {SVCD_FALSE};
894 
895                 /* loop over (4) 4x4 partitions */
896                 for(i4_ys = 0; i4_ys < 2; i4_ys++)
897                 {
898                     for(i4_xs = 0; i4_xs < 2; i4_xs++)
899                     {
900                         /* index to the exact 4x4 block */
901                         i4_indx_y = (i4_yp << 1) + i4_ys;
902                         i4_indx_x = (i4_xp << 1) + i4_xs;
903 
904                         /* check if the current part idc is -1*/
905                         if(ai4_ref_part_idc[i4_indx_y][i4_indx_x] == -1)
906                         {
907                             WORD32 i4_temp_x = 1 - i4_xs;
908                             WORD32 i4_temp_y = 1 - i4_ys;
909                             WORD32 i4_temp_part_y = (i4_yp << 1) + i4_temp_y;
910 
911                             WORD32 i4_temp_part_x = (i4_xp << 1) + i4_temp_x;
912 
913                             ai4_flag_4x4[i4_ys][i4_xs] = SVCD_TRUE;
914 
915                             /* replace with appropriate values */
916                             if((SVCD_FALSE == ai4_flag_4x4[i4_ys][i4_temp_x]) &&
917                                (ai4_ref_part_idc[i4_indx_y][i4_temp_part_x] != -1))
918                             {
919                                 ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
920                                     ai4_ref_part_idc[i4_indx_y][i4_temp_part_x];
921                             }
922                             else if((SVCD_FALSE == ai4_flag_4x4[i4_temp_y][i4_xs]) &&
923                                     (ai4_ref_part_idc[i4_temp_part_y][i4_indx_x] != -1))
924                             {
925                                 ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
926                                     ai4_ref_part_idc[i4_temp_part_y][i4_indx_x];
927                             }
928                             else if((SVCD_FALSE == ai4_flag_4x4[i4_temp_y][i4_temp_x]) &&
929                                     (ai4_ref_part_idc[i4_temp_part_y][i4_temp_part_x] != -1))
930                             {
931                                 ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
932                                     ai4_ref_part_idc[i4_temp_part_y][i4_temp_part_x];
933                             }
934                         } /* end of part idc equal to -1 check */
935 
936                     }     /* end of sub partition xs loop */
937 
938                 }         /* end of sub partition ys loop */
939 
940             }             /* end of partition xp loop */
941 
942         }                 /* end of partition yp loop */
943 
944         /* replace values of "-1" on an 8x8 block basis */
945 
946         /* loop over (4) 8x8 partitions */
947         for(i4_yp = 0; i4_yp < 2; i4_yp++)
948         {
949             for(i4_xp = 0; i4_xp < 2; i4_xp++)
950             {
951                 WORD32 i4_yp_inv = 1 - i4_yp;
952                 WORD32 i4_xp_inv = 1 - i4_xp;
953                 WORD32 i4_xo_inv = (2 - i4_xp);
954                 WORD32 i4_yo_inv = (2 - i4_yp);
955                 i4_indx_x = (i4_xp << 1);
956                 i4_indx_y = (i4_yp << 1);
957 
958                 /* check if the current part idc is -1*/
959                 if(ai4_ref_part_idc[i4_indx_y][i4_indx_x] == -1)
960                 {
961                     ai4_flag_8x8[i4_yp][i4_xp] = SVCD_TRUE;
962 
963                     /* replace the -1 with appropriate values */
964                     if(SVCD_FALSE == ai4_flag_8x8[i4_yp][i4_xp_inv] &&
965                        ai4_ref_part_idc[i4_indx_y][i4_xo_inv] != -1)
966                     {
967                         ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
968                             ai4_ref_part_idc[i4_indx_y][i4_xo_inv];
969 
970                         ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x] =
971                             ai4_ref_part_idc[i4_indx_y + 1][i4_xo_inv];
972 
973                         ai4_ref_part_idc[i4_indx_y][i4_indx_x + 1] =
974                             ai4_ref_part_idc[i4_indx_y][i4_xo_inv];
975 
976                         ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x + 1] =
977                             ai4_ref_part_idc[i4_indx_y + 1][i4_xo_inv];
978                     }
979                     else if(SVCD_FALSE == ai4_flag_8x8[i4_yp_inv][i4_xp] &&
980                             ai4_ref_part_idc[i4_yo_inv][i4_indx_x] != -1)
981                     {
982                         ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
983                             ai4_ref_part_idc[i4_yo_inv][i4_indx_x];
984 
985                         ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x] =
986                             ai4_ref_part_idc[i4_yo_inv][i4_indx_x];
987 
988                         ai4_ref_part_idc[i4_indx_y][i4_indx_x + 1] =
989                             ai4_ref_part_idc[i4_yo_inv][i4_indx_x + 1];
990 
991                         ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x + 1] =
992                             ai4_ref_part_idc[i4_yo_inv][i4_indx_x + 1];
993                     }
994                     else if(SVCD_FALSE == ai4_flag_8x8[i4_yp_inv][i4_xp_inv] &&
995                             ai4_ref_part_idc[i4_yo_inv][i4_xo_inv] != -1)
996                     {
997                         ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
998                             ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
999 
1000                         ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x] =
1001                             ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
1002 
1003                         ai4_ref_part_idc[i4_indx_y][i4_indx_x + 1] =
1004                             ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
1005 
1006                         ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x + 1] =
1007                             ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
1008                     }
1009                 } /* end of part idc equal to -1 check */
1010 
1011             }     /* end of partition xp loop */
1012 
1013         }         /* end of partition yp loop */
1014 
1015     }             /* end of refinement of part idc for non dyadic case*/
1016 
1017     /* store the intra flag in the location provided */
1018     *pi4_intra_flag = i4_intra_mb_flag;
1019 
1020     return;
1021 }
1022 /*****************************************************************************/
1023 /*                                                                           */
1024 /*  Function Name : isvcd_check_motion                                        */
1025 /*                                                                           */
1026 /*  Description   :this function calculates the MV diff b/w to motion vectors*/
1027 /*                 and returns 1 if it is under threshold equal to 0         */
1028 /*                                                                           */
1029 /*  Inputs        : pv_motion_prm_mb_part_a : pointer to motion struct part A*/
1030 /*                  pv_motion_prm_mb_part_b : pointer to motion struct part B*/
1031 /*                  i4_listx        : lists to be checked                    */
1032 /*  Globals       : none                                                     */
1033 /*  Processing    : it compares reference indcies fo given number of lists   */
1034 /*                  it calculates the mv diff and compares it with 0         */
1035 /*                  it does the above for given number of lists              */
1036 /*  Outputs       : none                                                     */
1037 /*  Returns       : 1 if matching 0 if not matching                          */
1038 /*                                                                           */
1039 /*  Issues        : none                                                     */
1040 /*                                                                           */
1041 /*  Revision History:                                                        */
1042 /*                                                                           */
1043 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1044 /*         06 09 2021   vijayakumar          creation                        */
1045 /*                                                                           */
1046 /*****************************************************************************/
isvcd_check_motion(void * pv_motion_prm_mb_part_a,void * pv_motion_prm_mb_part_b,WORD32 i4_listx)1047 WORD32 isvcd_check_motion(void *pv_motion_prm_mb_part_a, void *pv_motion_prm_mb_part_b,
1048                           WORD32 i4_listx)
1049 {
1050     mv_pred_t *ps_part_a;
1051     mv_pred_t *ps_part_b;
1052     WORD32 i4_cntr;
1053     WORD32 i4_mv_treshold;
1054     WORD32 i4_flag = 0;
1055 
1056     ps_part_a = (mv_pred_t *) pv_motion_prm_mb_part_a;
1057     ps_part_b = (mv_pred_t *) pv_motion_prm_mb_part_b;
1058 
1059     for(i4_cntr = 0; i4_cntr < i4_listx; i4_cntr++)
1060     {
1061         /* calculate the absolute diff of both components */
1062         i4_mv_treshold = ABS((ps_part_a->i2_mv[2 * i4_cntr]) - (ps_part_b->i2_mv[2 * i4_cntr]));
1063         i4_mv_treshold +=
1064             ABS((ps_part_a->i2_mv[1 + 2 * i4_cntr]) - (ps_part_b->i2_mv[1 + 2 * i4_cntr]));
1065 
1066         if((0 == i4_mv_treshold) &&
1067            (ps_part_a->i1_ref_frame[i4_cntr] == ps_part_b->i1_ref_frame[i4_cntr]))
1068         {
1069             i4_flag = 1;
1070         }
1071         else
1072         {
1073             i4_flag = 0;
1074             return (i4_flag);
1075         }
1076 
1077     } /* end of loop over lists */
1078 
1079     return (i4_flag);
1080 }
1081 /*****************************************************************************/
1082 /*                                                                           */
1083 /*  Function Name : isvcd_get_min_positive                                    */
1084 /*                                                                           */
1085 /*  Description   : this utility return the minimum positive b/w the given   */
1086 /*                  inputs                                                   */
1087 /*                                                                           */
1088 /*  Inputs        :  i4_input_1: value A , i4_input_2: value B               */
1089 /*  Globals       :  none                                                    */
1090 /*  Processing    :  if A & B are greater than -1 thenit returns MIN(A<B)    */
1091 /*                   otherwise return MAX(A<B)                               */
1092 /*  Outputs       :  none                                                    */
1093 /*  Returns       :  minimum positive of the two inputs                      */
1094 /*                                                                           */
1095 /*  Issues        :  none                                                    */
1096 /*                                                                           */
1097 /*  Revision History:                                                        */
1098 /*                                                                           */
1099 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1100 /*         06 09 2021   vijayakumar          creation                        */
1101 /*                                                                           */
1102 /*****************************************************************************/
isvcd_get_min_positive(WORD32 i4_input_1,WORD32 i4_input_2)1103 WORD32 isvcd_get_min_positive(WORD32 i4_input_1, WORD32 i4_input_2)
1104 {
1105     UWORD32 u4_x, u4_y;
1106     WORD32 i4_min_positive;
1107 
1108     /* get positive values */
1109     u4_x = (UWORD32) i4_input_1;
1110     u4_y = (UWORD32) i4_input_2;
1111 
1112     /* logic and desired output
1113 
1114     u4_x     magnitude compare    u4_y           o/p
1115     +              >              +             u4_y
1116     +              <              +             u4_x
1117     +              =              +             u4_x
1118     -              >              -             u4_y
1119     -              <              -             u4_x
1120     -              =              -             u4_x
1121     0              =              0             u4_x
1122     -              n/a            +             u4_y
1123     +              n/a            -             u4_x
1124 
1125     */
1126 
1127     if((u4_y < u4_x) && (0 <= i4_input_2))
1128     {
1129         i4_min_positive = i4_input_2;
1130     }
1131     else
1132     {
1133         i4_min_positive = i4_input_1;
1134     }
1135     return (i4_min_positive);
1136 }
1137 /*****************************************************************************/
1138 /*                                                                           */
1139 /*  Function Name :  isvcd_motion_scale_crop_wdw_change                       */
1140 /*                                                                           */
1141 /*  Description   : This function does the up scaling of motion vectors and  */
1142 /*                  for crop window change cases                             */
1143 /*  Inputs        : pv_comp_mode_mv_ctxt : mode motion handle                */
1144 /*                  ps_lyr_mem   : pointer current layer memory              */
1145 /*                  ps_mb_params : pointer to mb params structure            */
1146 /*                  ps_ref_mv    : pointer to reference MVs                  */
1147 /*                  ps_motion_pred : pointer to current 4x4 part mv pred     */
1148 /*                  i4_listx : lists to be processed                         */
1149 /*                  i4_part_frm_x: horz location in the picture of the       */
1150 /*                                 current sub partition                     */
1151 /*                  i4_part_frm_y: vertical location in the picture of the   */
1152 /*                                 current sub partition                     */
1153 /*  Globals       :                                                          */
1154 /*  Processing    : it takes care of cropping                                */
1155 /*                  change flag                                              */
1156 /*  Outputs       : it stores the interlayer MV pred in the structure        */
1157 /*  Returns       : none                                                     */
1158 /*                                                                           */
1159 /*  Issues        : none                                                     */
1160 /*                                                                           */
1161 /*  Revision History:                                                        */
1162 /*                                                                           */
1163 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1164 /*         06 09 2021   vijayakumar          creation                        */
1165 /*                                                                           */
1166 /*****************************************************************************/
isvcd_motion_scale_crop_wdw_change(mode_motion_ctxt_t * ps_ctxt,mode_motion_lyr_ctxt * ps_lyr_mem,dec_mb_info_t * ps_mb_params,mv_pred_t * ps_ref_mv,mv_pred_t * ps_motion_pred,WORD32 i4_lists,WORD32 i4_part_frm_x,WORD32 i4_part_frm_y,void ** ppv_map_ref_idx_to_poc,UWORD8 u1_list_x)1167 void isvcd_motion_scale_crop_wdw_change(mode_motion_ctxt_t *ps_ctxt,
1168                                         mode_motion_lyr_ctxt *ps_lyr_mem,
1169                                         dec_mb_info_t *ps_mb_params, mv_pred_t *ps_ref_mv,
1170                                         mv_pred_t *ps_motion_pred, WORD32 i4_lists,
1171                                         WORD32 i4_part_frm_x, WORD32 i4_part_frm_y,
1172                                         void **ppv_map_ref_idx_to_poc, UWORD8 u1_list_x)
1173 {
1174     ref_lyr_scaled_offset_t *ps_curr_lyr_offset;
1175     ref_lyr_scaled_offset_t *ps_ref_pic_lyr_offset;
1176     WORD32 i4_ref_lyr_width, i4_ref_lyr_height;
1177     WORD32 i4_curr_lyr_width, i4_curr_lyr_height;
1178     WORD32 i4_ref_indx;
1179     WORD32 i4_mv_x, i4_mv_y;
1180     WORD32 i4_x, i4_y;
1181     WORD32 i4_dox, i4_doy, i4_dsw, i4_dsh;
1182     WORD32 i4_scale_x, i4_scale_y;
1183     WORD8 *pi1_ref_idx_map;
1184 
1185     UNUSED(ps_ctxt);
1186     UNUSED(ps_mb_params);
1187 
1188     /* get the reference index */
1189     i4_ref_indx = ps_motion_pred->i1_ref_frame[u1_list_x];
1190 
1191     i4_mv_x = (WORD32) ps_ref_mv->i2_mv[2 * u1_list_x];
1192     i4_mv_y = (WORD32) ps_ref_mv->i2_mv[1 + 2 * u1_list_x];
1193 
1194     /* get the Map buffer pointer */
1195     if(0 == i4_lists)
1196     {
1197         pi1_ref_idx_map = (WORD8 *) ppv_map_ref_idx_to_poc;
1198     }
1199     else
1200     {
1201         pi1_ref_idx_map = (WORD8 *) (ppv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF);
1202     }
1203 
1204     /* get the Ref layer width and height */
1205     i4_ref_lyr_width = ps_lyr_mem->i4_ref_width;
1206     i4_ref_lyr_height = ps_lyr_mem->i4_ref_height;
1207 
1208     /* get the Scaled ref layer width and height */
1209     i4_curr_lyr_width = ps_lyr_mem->ps_curr_lyr_res_prms->u2_scaled_ref_width;
1210     i4_curr_lyr_height = ps_lyr_mem->ps_curr_lyr_res_prms->u2_scaled_ref_height;
1211 
1212     /* get the offset stucture pointer */
1213     ps_curr_lyr_offset = &ps_lyr_mem->ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset;
1214 
1215     /* get the reference offset structure pointer */
1216     ps_ref_pic_lyr_offset = ps_lyr_mem->ps_ref_pic_lyr_offsets + pi1_ref_idx_map[i4_ref_indx];
1217 
1218     /* calculate the correction variables */
1219     i4_dox = ps_curr_lyr_offset->i2_left - ps_ref_pic_lyr_offset->i2_left;
1220     i4_doy = ps_curr_lyr_offset->i2_top - ps_ref_pic_lyr_offset->i2_top;
1221     i4_dsw = ps_curr_lyr_offset->i2_rt - ps_ref_pic_lyr_offset->i2_rt + i4_dox;
1222     i4_dsh = ps_curr_lyr_offset->i2_bot - ps_ref_pic_lyr_offset->i2_bot + i4_doy;
1223 
1224     i4_scale_x =
1225         (((i4_curr_lyr_width + i4_dsw) << 16) + (i4_ref_lyr_width >> 1)) / i4_ref_lyr_width;
1226 
1227     i4_scale_y =
1228         (((i4_curr_lyr_height + i4_dsh) << 16) + (i4_ref_lyr_height >> 1)) / i4_ref_lyr_height;
1229 
1230     /* scale the motion vectors */
1231     i4_mv_x = (i4_mv_x * i4_scale_x + 32768) >> 16;
1232     i4_mv_y = (i4_mv_y * i4_scale_y + 32768) >> 16;
1233 
1234     /* subtract the offsets */
1235     i4_x = i4_part_frm_x - ps_lyr_mem->i4_offset_x;
1236     i4_y = i4_part_frm_y - ps_lyr_mem->i4_offset_y;
1237 
1238     /* get the scale factors */
1239     i4_scale_x = (((4 * i4_dsw) << 16) + (i4_curr_lyr_width >> 1)) / i4_curr_lyr_width;
1240     i4_scale_y = (((4 * i4_dsh) << 16) + (i4_curr_lyr_height >> 1)) / i4_curr_lyr_height;
1241 
1242     /* add the correction */
1243     i4_mv_x += ((i4_x * i4_scale_x + 32768) >> 16) - 4 * i4_dox;
1244     i4_mv_y += ((i4_y * i4_scale_y + 32768) >> 16) - 4 * i4_doy;
1245 
1246     /* store the final motion vectors */
1247     ps_motion_pred->i2_mv[2 * u1_list_x] = i4_mv_x;
1248     ps_motion_pred->i2_mv[1 + 2 * u1_list_x] = i4_mv_y;
1249 }
1250 
1251 /*****************************************************************************/
1252 /*                                                                           */
1253 /*  Function Name :  isvcd_interlayer_motion_scale                            */
1254 /*                                                                           */
1255 /*  Description   : This function does the up scaling of motion vectors and  */
1256 /*                  and stores the inter layer MV and reference indices      */
1257 /*                  in the mv prediction structure for a 4x4 part            */
1258 /*  Inputs        : pv_comp_mode_mv_ctxt : mode motion handle                */
1259 /*                  pi4_ref_part_idc   : pointer current 4x4 part ref_idc    */
1260 /*                  pv_motion_pred : pointer to current 4x4 part mv pred     */
1261 /*                  i4_listx : lists to be processed                         */
1262 /*                  i4_part_frm_x: horz location in the picture of the       */
1263 /*                                 current sub partition                     */
1264 /*                  i4_part_frm_y: vertical location in the picture of the   */
1265 /*                                 current sub partition                     */
1266 /*  Globals       :                                                          */
1267 /*  Processing    : it stores the default values if the refernce indx of     */
1268 /*                  ref lyr partiton is -1. if not it upscales the motion    */
1269 /*                  vectors based on scale factors. it takes care of cropping*/
1270 /*                  change flag                                              */
1271 /*  Outputs       : it stores the interlayer MV pred in the structure        */
1272 /*  Returns       : none                                                     */
1273 /*                                                                           */
1274 /*  Issues        : none                                                     */
1275 /*                                                                           */
1276 /*  Revision History:                                                        */
1277 /*                                                                           */
1278 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1279 /*         06 09 2021   vijayakumar          creation                        */
1280 /*                                                                           */
1281 /*****************************************************************************/
isvcd_interlyr_motion_scale(void * pv_comp_mode_mv_ctxt,WORD32 * pi4_ref_part_idc,dec_mb_info_t * ps_mb_params,void * pv_motion_pred,WORD32 i4_listx,WORD32 i4_part_frm_x,WORD32 i4_part_frm_y,void ** ppv_map_ref_idx_to_poc)1282 WORD32 isvcd_interlyr_motion_scale(void *pv_comp_mode_mv_ctxt, WORD32 *pi4_ref_part_idc,
1283                                    dec_mb_info_t *ps_mb_params, void *pv_motion_pred,
1284                                    WORD32 i4_listx, WORD32 i4_part_frm_x, WORD32 i4_part_frm_y,
1285                                    void **ppv_map_ref_idx_to_poc)
1286 {
1287     /*! Flow of the module is as follows                                   */
1288     /*! 1. derive the offsets form part idc                                */
1289     /*! 2. takes the motion vector and scales it based on scale factor     */
1290     /*! 3. adds the correction factors for crop window change cases        */
1291     /*! 4. store the default motion params for intra projected blocks      */
1292 
1293     mode_motion_ctxt_t *ps_ctxt;
1294     mode_motion_lyr_ctxt *ps_lyr_mem;
1295     mv_pred_t *ps_motion_pred;
1296     mv_pred_t *ps_ref_mv;
1297     WORD32 i4_lists;
1298     WORD32 i4_ref_16x16_flag = 0;
1299     WORD32 i4_scale_x, i4_scale_y;
1300     WORD16 i2_max_mv_x, i2_max_mv_y;
1301 
1302     ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
1303 
1304     /* get the current layer ctxt */
1305     ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
1306 
1307     /* ----------- Get the reference layer MV structure ---------- */
1308     {
1309         mv_pred_t *ps_ref_lyr_motion_prms;
1310         WORD32 i4_ref_x, i4_ref_y;
1311         WORD32 i4_ref_mb_x, i4_ref_mb_y;
1312         WORD32 i4_ref_width;
1313 
1314         ps_ref_lyr_motion_prms = (mv_pred_t *) ps_lyr_mem->pv_ref_mv_bank_l0;
1315         i4_ref_width = ps_lyr_mem->i4_ref_width;
1316         i2_max_mv_x = i4_ref_width << 2;
1317         i2_max_mv_y = ps_lyr_mem->i4_ref_height << 2;
1318 
1319         /* extract the reference x and y positions */
1320         i4_ref_x = (*pi4_ref_part_idc) & 0xFFFF;
1321         i4_ref_y = (*pi4_ref_part_idc) >> 16;
1322 
1323         /* get the reference mb x and y */
1324         i4_ref_mb_x = (i4_ref_x >> 4);
1325         i4_ref_mb_y = (i4_ref_y >> 4);
1326 
1327         /* get the reference layer motion struct pointing  */
1328         /* to first 4x4 partition of the refernce layer MB */
1329         ps_ref_mv = ps_ref_lyr_motion_prms + (i4_ref_mb_x << 4);
1330         ps_ref_mv += (i4_ref_mb_y * i4_ref_width);
1331 
1332         /* if reference layer mb type is non 16x16 */
1333         if(0 == i4_ref_16x16_flag)
1334         {
1335             /* increment the pointer to appropaite 4x4 */
1336             ps_ref_mv += ((i4_ref_x >> 2) & 0x03);
1337             ps_ref_mv += (((i4_ref_y >> 2) & 0x03) << 2);
1338         }
1339     }
1340 
1341     /* motion pred structure */
1342     ps_motion_pred = pv_motion_pred;
1343 
1344     /* retrive the scale factors */
1345     i4_scale_x = ps_lyr_mem->i4_scale_mv_x;
1346     i4_scale_y = ps_lyr_mem->i4_scale_mv_y;
1347 
1348     /* loop on the lists given as input */
1349     for(i4_lists = 0; i4_lists < i4_listx; i4_lists++)
1350     {
1351         WORD32 i4_mv_x, i4_mv_y;
1352         WORD16 i2_mv_x, i2_mv_y;
1353 
1354         /* if the refernce index is -1 set the default values */
1355         if(-1 == ps_ref_mv->i1_ref_frame[i4_lists])
1356         {
1357             ps_motion_pred->i1_ref_frame[i4_lists] = -1;
1358             ps_motion_pred->i2_mv[2 * i4_lists] = 0;
1359             ps_motion_pred->i2_mv[1 + 2 * i4_lists] = 0;
1360         }
1361         else
1362         {
1363             /* field MB and field pictures modification are present */
1364             /* currently not implemented */
1365             ps_motion_pred->i1_ref_frame[i4_lists] = ps_ref_mv->i1_ref_frame[i4_lists];
1366 
1367             i2_mv_x = ps_ref_mv->i2_mv[2 * i4_lists];
1368             i2_mv_y = ps_ref_mv->i2_mv[1 + 2 * i4_lists];
1369             i2_mv_x = CLIP3(-i2_max_mv_x, i2_max_mv_x, i2_mv_x);
1370             i2_mv_y = CLIP3(-i2_max_mv_y, i2_max_mv_y, i2_mv_y);
1371             /* scale the motion vectors */
1372             i4_mv_x = (i2_mv_x * i4_scale_x + 32768) >> 16;
1373             i4_mv_y = (i2_mv_y * i4_scale_y + 32768) >> 16;
1374 
1375             /* store the final motion vectors */
1376             ps_motion_pred->i2_mv[2 * i4_lists] = i4_mv_x;
1377             ps_motion_pred->i2_mv[1 + 2 * i4_lists] = i4_mv_y;
1378 
1379             /* if cropping change flag is present */
1380             if(SVCD_TRUE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_cropping_change_flag)
1381             {
1382                 /* over write the motion vectors x and y */
1383                 isvcd_motion_scale_crop_wdw_change(ps_ctxt, ps_lyr_mem, ps_mb_params, ps_ref_mv,
1384                                                    ps_motion_pred, i4_listx, i4_part_frm_x,
1385                                                    i4_part_frm_y, ppv_map_ref_idx_to_poc, i4_lists);
1386             }
1387         }
1388     } /* end of lists loop */
1389 
1390     return (i4_ref_16x16_flag);
1391 }
1392 
1393 /*****************************************************************************/
1394 /*                                                                           */
1395 /*  Function Name : isvcd_store_motion_map                                    */
1396 /*                                                                           */
1397 /*  Description   : this fucntion copies the  souce structure contents to    */
1398 /*                  destination entires of part width x part height          */
1399 /*                                                                           */
1400 /*  Inputs        : pv_motion_pred : pointer to the source structure         */
1401 /*                  ps_curr_lyr_motion_map : pointer to the destination      */
1402 /*                  in the map                                               */
1403 /*                  i4_src_stride : source stride                            */
1404 /*                  i4_dst_stride : destination stride                       */
1405 /*                  i4_part_width : width to be copied in terms of sub mbs   */
1406 /*                  i4_part_height : height to be copied                     */
1407 /*                  i4_src_update_flag : source update flag                  */
1408 /*  Globals       : none                                                     */
1409 /*  Processing    : it copies the src contents to destination                */
1410 /*                                                                           */
1411 /*  Outputs       : none                                                     */
1412 /*  Returns       : none                                                     */
1413 /*                                                                           */
1414 /*  Issues        : none                                                     */
1415 /*                                                                           */
1416 /*  Revision History:                                                        */
1417 /*                                                                           */
1418 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1419 /*         06 09 2021   vijayakumar          creation                        */
1420 /*                                                                           */
1421 /*****************************************************************************/
isvcd_store_motion_map(void * pv_motion_pred,void * pv_curr_lyr_motion_map,WORD32 i4_src_stride,WORD32 i4_dst_stride,WORD32 i4_part_width,WORD32 i4_part_height,WORD32 i4_src_update_flag)1422 void isvcd_store_motion_map(void *pv_motion_pred, void *pv_curr_lyr_motion_map,
1423                             WORD32 i4_src_stride, WORD32 i4_dst_stride, WORD32 i4_part_width,
1424                             WORD32 i4_part_height, WORD32 i4_src_update_flag)
1425 {
1426     /*! Flow of the module is as follows                                   */
1427     /*! 1. loops over part_width and part_height                           */
1428     /*! 2. copies the src params toi destination                           */
1429     /*! 3. updates the source pointer if src_update flag is set to 1       */
1430 
1431     WORD32 i4_i, i4_j;
1432     mv_pred_t *ps_mv_pred_src;
1433     mv_pred_t *ps_mv_map_dst;
1434 
1435     ps_mv_pred_src = (mv_pred_t *) pv_motion_pred;
1436     ps_mv_map_dst = (mv_pred_t *) pv_curr_lyr_motion_map;
1437 
1438     /* store the current motion pred to all the motion map structures */
1439     for(i4_i = 0; i4_i < i4_part_height; i4_i++)
1440     {
1441         for(i4_j = 0; i4_j < i4_part_width; i4_j++)
1442         {
1443             /* copy form source to destination */
1444             *(ps_mv_map_dst + i4_j) = *(ps_mv_pred_src + (i4_src_update_flag * i4_j));
1445 
1446         } /* end of loop over partition width */
1447 
1448         ps_mv_map_dst += i4_dst_stride;
1449         ps_mv_pred_src += (i4_src_stride * i4_src_update_flag);
1450 
1451     } /* end of loop over partition height */
1452     return;
1453 }
1454 /*****************************************************************************/
1455 /*                                                                           */
1456 /*  Function Name : isvcd_check_mv_diff                                       */
1457 /*                                                                           */
1458 /*  Description   :this function calculates the MV diff b/w to motion vectors*/
1459 /*                 and returns 1 if it is under threshold                    */
1460 /*                                                                           */
1461 /*  Inputs        : pv_motion_prm_a : pointer to motion struct part A        */
1462 /*                  pv_motion_prm_b : pointer to motion struct part B        */
1463 /*                  i4_listx        : lists to be checked                    */
1464 /*                  i4_actual_threshold : threshold with which the mv diff   */
1465 /*                   is to be compared with                                  */
1466 /*  Globals       : none                                                     */
1467 /*  Processing    : it calculates the mv diff and compares it with threshold */
1468 /*                  returns 1 if under threshold                              */
1469 /*  Outputs       : none                                                     */
1470 /*  Returns       : 1 if under threshold 0 if not under threshold            */
1471 /*                                                                           */
1472 /*  Issues        : none                                                     */
1473 /*                                                                           */
1474 /*  Revision History:                                                        */
1475 /*                                                                           */
1476 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1477 /*         06 09 2021   vijayakumar          creation                        */
1478 /*                                                                           */
1479 /*****************************************************************************/
isvcd_check_mv_diff(void * pv_motion_prm_a,void * pv_motion_prm_b,WORD32 i4_listx,WORD32 i4_actual_threshold)1480 WORD32 isvcd_check_mv_diff(void *pv_motion_prm_a, void *pv_motion_prm_b, WORD32 i4_listx,
1481                            WORD32 i4_actual_threshold)
1482 {
1483     mv_pred_t *ps_part_a;
1484     mv_pred_t *ps_part_b;
1485     WORD32 i4_cntr;
1486     WORD32 i4_mv_treshold;
1487     WORD32 i4_flag;
1488 
1489     ps_part_a = (mv_pred_t *) pv_motion_prm_a;
1490     ps_part_b = (mv_pred_t *) pv_motion_prm_b;
1491 
1492     i4_flag = 1;
1493     for(i4_cntr = 0; i4_cntr < i4_listx; i4_cntr++)
1494     {
1495         /* calculate the absolute diff of both components */
1496         i4_mv_treshold = ABS((ps_part_a->i2_mv[2 * i4_cntr]) - (ps_part_b->i2_mv[2 * i4_cntr]));
1497         i4_mv_treshold +=
1498             ABS((ps_part_a->i2_mv[1 + (2 * i4_cntr)]) - (ps_part_b->i2_mv[1 + (2 * i4_cntr)]));
1499 
1500         if(i4_actual_threshold < i4_mv_treshold)
1501         {
1502             i4_flag = 0;
1503             break;
1504         }
1505 
1506     } /* end of loop over lists */
1507     return (i4_flag);
1508 }
1509 
1510 /*****************************************************************************/
1511 /*                                                                           */
1512 /*  Function Name :  isvcd_interlayer_motion_submbmode_pred                   */
1513 /*                                                                           */
1514 /*  Description   : this function does the inter layer motion predcition for */
1515 /*                   all sub partitions of a macro block                     */
1516 /*                                                                           */
1517 /*  Inputs        : pv_comp_mode_mv_ctxt : motion mode handle                */
1518 /*                  pv_mb_params : pointer to MB params structure            */
1519 /*                  ai4_ref_part_idc : ref partitons idc of all 4x4 blocks   */
1520 /*                  pi4_sub_mb_mode  : pointer to store the sub mb modes     */
1521 /*                  i4_mb_addr       : current mb address                    */
1522 /*                  pi4_intra_flag   : location to store the intra status    */
1523 /*  Globals       : none                                                     */
1524 /*  Processing    : it computes the motion vectors and futher modifictaion is*/
1525 /*                  done for NON -DYAdic cases                               */
1526 /*  Outputs       : inter layer predicted motion vectors and ref indices     */
1527 /*                  sub mbmodes of the 4 mb partitions                       */
1528 /*  Returns       : none                                                     */
1529 /*                                                                           */
1530 /*  Issues        : none                                                     */
1531 /*                                                                           */
1532 /*  Revision History:                                                        */
1533 /*                                                                           */
1534 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1535 /*         06 09 2021   vijayakumar          creation                        */
1536 /*                                                                           */
1537 /*****************************************************************************/
isvcd_interlyr_motion_submbmode_pred(void * pv_comp_mode_mv_ctxt,void * pv_mb_params,void * pv_svc_mb_params,WORD32 ai4_ref_part_idc[4][4],WORD32 * pi4_sub_mb_mode,void * pv_dec)1538 void isvcd_interlyr_motion_submbmode_pred(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
1539                                           void *pv_svc_mb_params, WORD32 ai4_ref_part_idc[4][4],
1540                                           WORD32 *pi4_sub_mb_mode, void *pv_dec)
1541 {
1542     /*! Flow of the module is as follows                                   */
1543     /*! 1. if dyadic case it calculates the motion vectors based on dyadic
1544            scale factor and loop counts calculated at layer level          */
1545     /*! 2. if non dyadic then it calculates the motion vectors based on
1546             reference layer part idc                                        */
1547     /*! 3. does the motion vector modification for non dyayic cases, by
1548            calculating the minimum positive of reference indices of 4 4x4
1549            blocks and getiing a single reference index for 8x8             */
1550     /*! 4. if direct 8x8 inference is present and current slice is
1551            B OR EB, then it stores the corner motion vectors for each 8x8  */
1552     /*! 5. does the sub mb mode prediction and merging of motion vectors
1553            which are closely related by setting appropriate thresholds
1554            for MVs                                                         */
1555     /*! 6. stores the sub mb modes in the array given as input             */
1556 
1557     mode_motion_ctxt_t *ps_ctxt;
1558     mode_motion_lyr_ctxt *ps_lyr_mem;
1559     mv_pred_t *ps_motion_pred;
1560     dec_mb_info_t *ps_mb_params;
1561     dec_svc_mb_info_t *ps_svc_mb_params;
1562     WORD32 i4_blk_y, i4_blk_x;
1563     WORD32 i4_i;
1564     WORD32 i4_listx;
1565     WORD32 i4_mv_treshold;
1566     WORD32 ai4_temp_ref_indx[NUM_REF_LISTS][NUM_MB_PARTS] = {0};
1567     WORD32 i4_mb_x, i4_mb_y;
1568     WORD32 i4_mb_pic_x, i4_mb_pic_y;
1569     dec_struct_t *ps_dec;
1570 
1571     ps_dec = (dec_struct_t *) pv_dec;
1572     ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
1573 
1574     /* get the current layer ctxt */
1575     ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
1576 
1577     ps_mb_params = (dec_mb_info_t *) pv_mb_params;
1578     ps_svc_mb_params = (dec_svc_mb_info_t *) pv_svc_mb_params;
1579     ps_motion_pred = ps_ctxt->ps_motion_pred_struct;
1580 
1581     i4_listx = ps_ctxt->i4_listx;
1582 
1583     /* derive the MB_X and MB_Y for the current MB */
1584     i4_mb_x = ps_mb_params->u2_mbx;
1585     i4_mb_y = ps_mb_params->u2_mby;
1586 
1587     /* convert into picture units */
1588     i4_mb_pic_x = i4_mb_x << 4;
1589     i4_mb_pic_y = i4_mb_y << 4;
1590 
1591     /* compute the motion vectors and reference indices of all part */
1592     for(i4_blk_y = 0; i4_blk_y < NUM_SUB_MB_PARTS; i4_blk_y++)
1593     {
1594         for(i4_blk_x = 0; i4_blk_x < NUM_SUB_MB_PARTS; i4_blk_x++)
1595         {
1596             isvcd_interlyr_motion_scale(pv_comp_mode_mv_ctxt, &ai4_ref_part_idc[i4_blk_y][i4_blk_x],
1597                                         ps_mb_params, (ps_motion_pred + (4 * i4_blk_y) + i4_blk_x),
1598                                         i4_listx, (i4_mb_pic_x + (i4_blk_x << 2) + 1),
1599                                         (i4_mb_pic_y + (i4_blk_y << 2) + 1),
1600                                         ps_dec->ppv_map_ref_idx_to_poc);
1601 
1602         } /* end of blk x loop */
1603     }     /* end of blk y loop */
1604 
1605     /********************************************************/
1606     /* get the final reference index into a temparory array */
1607     /********************************************************/
1608 
1609     /* set reference indices */
1610     for(i4_i = 0; i4_i < i4_listx; i4_i++)
1611     {
1612         ai4_temp_ref_indx[i4_i][0] = ps_motion_pred[0].i1_ref_frame[i4_i];
1613         ai4_temp_ref_indx[i4_i][1] = ps_motion_pred[2].i1_ref_frame[i4_i];
1614         ai4_temp_ref_indx[i4_i][2] = ps_motion_pred[8].i1_ref_frame[i4_i];
1615         ai4_temp_ref_indx[i4_i][3] = ps_motion_pred[10].i1_ref_frame[i4_i];
1616 
1617     } /* end of loop over lists */
1618 
1619     /* if restricted spatial resolution change is not set */
1620     if(SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag)
1621     {
1622         WORD32 i4_xp, i4_yp;
1623         WORD32 i4_xs, i4_ys;
1624 
1625         /* merge reference indices and modify the motion vectors */
1626         for(i4_i = 0; i4_i < i4_listx; i4_i++)
1627         {
1628             for(i4_yp = 0; i4_yp < 2; i4_yp++)
1629             {
1630                 for(i4_xp = 0; i4_xp < 2; i4_xp++)
1631                 {
1632                     /* get the minimum positive of the refernce index */
1633                     for(i4_ys = 0; i4_ys < 2; i4_ys++)
1634                     {
1635                         for(i4_xs = 0; i4_xs < 2; i4_xs++)
1636                         {
1637                             mv_pred_t *ps_temp;
1638                             ps_temp = ps_motion_pred + (i4_xp << 1) + i4_xs;
1639                             ps_temp += 4 * ((i4_yp << 1) + i4_ys);
1640 
1641                             /* get the minimum positive */
1642                             ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] =
1643                                 isvcd_get_min_positive(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp],
1644                                                        ps_temp->i1_ref_frame[i4_i]);
1645                         }
1646                     }
1647                     /* update motion vectors */
1648                     for(i4_ys = 0; i4_ys < 2; i4_ys++)
1649                     {
1650                         for(i4_xs = 0; i4_xs < 2; i4_xs++)
1651                         {
1652                             mv_pred_t *ps_temp;
1653                             ps_temp = ps_motion_pred + (i4_xp << 1) + i4_xs;
1654                             ps_temp += 4 * ((i4_yp << 1) + i4_ys);
1655 
1656                             /* check if the current part reference index is */
1657                             /* not choosen as the final reference index */
1658                             /* if not copy the neighbours MV */
1659                             if(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] !=
1660                                ps_temp->i1_ref_frame[i4_i])
1661                             {
1662                                 mv_pred_t *ps_temp_1;
1663                                 WORD32 i4_updated_flag = SVCD_FALSE;
1664 
1665                                 ps_temp_1 = ps_motion_pred + (i4_xp << 1) + (1 - i4_xs);
1666                                 ps_temp_1 += 4 * ((i4_yp << 1) + i4_ys);
1667 
1668                                 /* store the appropriate neighbours */
1669                                 if(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] ==
1670                                    ps_temp_1->i1_ref_frame[i4_i])
1671                                 {
1672                                     ps_temp->i2_mv[2 * i4_i] = ps_temp_1->i2_mv[2 * i4_i];
1673 
1674                                     ps_temp->i2_mv[1 + (2 * i4_i)] =
1675                                         ps_temp_1->i2_mv[1 + (2 * i4_i)];
1676                                     i4_updated_flag = SVCD_TRUE;
1677                                 }
1678 
1679                                 if(SVCD_FALSE == i4_updated_flag)
1680                                 {
1681                                     ps_temp_1 = ps_motion_pred + (i4_xp << 1) + i4_xs;
1682 
1683                                     ps_temp_1 += 4 * ((i4_yp << 1) + 1 - i4_ys);
1684 
1685                                     if(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] ==
1686                                        ps_temp_1->i1_ref_frame[i4_i])
1687                                     {
1688                                         ps_temp->i2_mv[2 * i4_i] = ps_temp_1->i2_mv[2 * i4_i];
1689 
1690                                         ps_temp->i2_mv[1 + (2 * i4_i)] =
1691                                             ps_temp_1->i2_mv[1 + (2 * i4_i)];
1692                                         i4_updated_flag = SVCD_TRUE;
1693                                     }
1694                                 }
1695                                 if(SVCD_FALSE == i4_updated_flag)
1696                                 {
1697                                     ps_temp_1 = ps_motion_pred + (i4_xp << 1) + (1 - i4_xs);
1698                                     ps_temp_1 += 4 * ((i4_yp << 1) + 1 - i4_ys);
1699 
1700                                     ps_temp->i2_mv[2 * i4_i] = ps_temp_1->i2_mv[2 * i4_i];
1701 
1702                                     ps_temp->i2_mv[1 + (2 * i4_i)] =
1703                                         ps_temp_1->i2_mv[1 + (2 * i4_i)];
1704 
1705                                     i4_updated_flag = SVCD_TRUE;
1706                                 }
1707                             } /* end of replacement of mv based on ref indx */
1708                         }     /* end of loop over sub partition xs */
1709                     }         /* end of loop over sub partition ys */
1710                 }             /* end of loop over partition xp */
1711             }                 /* end of loop over partition yp */
1712         }                     /* end of loop over lists */
1713     }
1714 
1715     /************************************************************************/
1716     /* if restircted saptial resolution change flag is 0                    */
1717     /* modify the reference indixes and motion vectors                      */
1718     /************************************************************************/
1719     if((SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag) &&
1720        (2 == i4_listx) && (SVCD_TRUE == ps_ctxt->u1_direct_8x8_inference_flag))
1721     {
1722         /* only applicable for EB Slice */
1723         /* store the corner 4x4 motion vectors to the whole block */
1724         /* 2 lists and 4 partitions */
1725         mot_vec_t s_temp_mv[2][4];
1726         WORD32 i4_xp, i4_yp;
1727         memset(&s_temp_mv[0][0], 0, sizeof(s_temp_mv));
1728 
1729         for(i4_i = 0; i4_i < i4_listx; i4_i++)
1730         {
1731             s_temp_mv[i4_i][0].i2_mv_x = ps_motion_pred[0].i2_mv[2 * i4_i];
1732             s_temp_mv[i4_i][0].i2_mv_y = ps_motion_pred[0].i2_mv[1 + (2 * i4_i)];
1733 
1734             s_temp_mv[i4_i][1].i2_mv_x = ps_motion_pred[3].i2_mv[2 * i4_i];
1735             s_temp_mv[i4_i][1].i2_mv_y = ps_motion_pred[3].i2_mv[1 + (2 * i4_i)];
1736 
1737             s_temp_mv[i4_i][2].i2_mv_x = ps_motion_pred[12].i2_mv[2 * i4_i];
1738             s_temp_mv[i4_i][2].i2_mv_y = ps_motion_pred[12].i2_mv[1 + (2 * i4_i)];
1739 
1740             s_temp_mv[i4_i][3].i2_mv_x = ps_motion_pred[15].i2_mv[2 * i4_i];
1741             s_temp_mv[i4_i][3].i2_mv_y = ps_motion_pred[15].i2_mv[1 + (2 * i4_i)];
1742 
1743         } /* end of loop over lists */
1744 
1745         /* replace the motion vectors */
1746         for(i4_i = 0; i4_i < i4_listx; i4_i++)
1747         {
1748             for(i4_yp = 0; i4_yp < 4; i4_yp++)
1749             {
1750                 for(i4_xp = 0; i4_xp < 4; i4_xp++)
1751                 {
1752                     mv_pred_t *ps_temp;
1753                     ps_temp = ps_motion_pred + i4_xp;
1754                     ps_temp += 4 * i4_yp;
1755 
1756                     ps_temp->i2_mv[2 * i4_i] =
1757                         s_temp_mv[i4_i][2 * (i4_yp >> 1) + (i4_xp >> 1)].i2_mv_x;
1758 
1759                     ps_temp->i2_mv[1 + (2 * i4_i)] =
1760                         s_temp_mv[i4_i][2 * (i4_yp >> 1) + (i4_xp >> 1)].i2_mv_y;
1761 
1762                 } /* end of loop over sub partitions xp */
1763             }     /* end of loop over sub partitions yp */
1764         }         /* end of loop over lists */
1765     }
1766 
1767     /* store the final reference index for all sub partitions */
1768     /* approporiate reference index is stored for each 4x4 belonging to 8x8 */
1769     {
1770         WORD32 i4_xp, i4_yp;
1771 
1772         for(i4_i = 0; i4_i < i4_listx; i4_i++)
1773         {
1774             for(i4_yp = 0; i4_yp < 4; i4_yp++)
1775             {
1776                 for(i4_xp = 0; i4_xp < 4; i4_xp++)
1777                 {
1778                     mv_pred_t *ps_temp;
1779                     ps_temp = ps_motion_pred + i4_xp;
1780                     ps_temp += 4 * i4_yp;
1781 
1782                     ps_temp->i1_ref_frame[i4_i] =
1783                         ai4_temp_ref_indx[i4_i][2 * (i4_yp >> 1) + (i4_xp >> 1)];
1784 
1785                 } /* end of loop over partition xp */
1786             }     /* end of loop over partition yp */
1787         }         /* end of loop over lists */
1788     }
1789 
1790     /********************************************************************/
1791     /* modify the motion vectors for non dyadic cases, set the mv       */
1792     /* threshold appropraitely to derive the sub MB type                */
1793     /********************************************************************/
1794     if(SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag)
1795     {
1796         /* non dyadic cases set the mv treshold to 1 */
1797         i4_mv_treshold = 1;
1798     }
1799     else
1800     {
1801         /* dyadic cases set the mv treshold to 0 */
1802         i4_mv_treshold = 0;
1803     }
1804 
1805     /* modify the motion vectors and get sub mb mode if base mode flag is 1 */
1806     if((SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag) ||
1807        (1 == ps_svc_mb_params->u1_base_mode_flag))
1808     {
1809         WORD32 i4_xp, i4_yp;
1810         for(i4_yp = 0; i4_yp < 2; i4_yp++)
1811         {
1812             for(i4_xp = 0; i4_xp < 2; i4_xp++)
1813             {
1814                 mv_pred_t *ps_temp;
1815                 WORD32 i4_part_size = 0;
1816                 WORD32 i4_horz1_match, i4_vert1_match;
1817                 WORD32 i4_horz2_match, i4_vert2_match;
1818                 WORD32 i4_diag_match;
1819 
1820                 WORD32 i4_8x8_match, i4_horz_match, i4_vert_match;
1821                 WORD32 i4_mv_x, i4_mv_y;
1822 
1823                 ps_temp = ps_motion_pred + (i4_xp << 1);
1824                 ps_temp += 4 * ((i4_yp << 1));
1825 
1826                 /* default init */
1827                 i4_8x8_match = i4_horz_match = i4_vert_match = SVCD_TRUE;
1828 
1829                 /* check if the mv diff in horz direction is under threshold*/
1830                 i4_horz1_match =
1831                     isvcd_check_mv_diff(ps_temp, (ps_temp + 1), i4_listx, i4_mv_treshold);
1832 
1833                 i4_horz2_match =
1834                     isvcd_check_mv_diff((ps_temp + 4), (ps_temp + 4 + 1), i4_listx, i4_mv_treshold);
1835 
1836                 /* check if the mv diff in horz direction is under threshold*/
1837                 i4_vert1_match =
1838                     isvcd_check_mv_diff(ps_temp, (ps_temp + 4), i4_listx, i4_mv_treshold);
1839 
1840                 i4_vert2_match =
1841                     isvcd_check_mv_diff((ps_temp + 1), (ps_temp + 4 + 1), i4_listx, i4_mv_treshold);
1842 
1843                 /* check if in diagonal direction is under threshold*/
1844                 i4_diag_match =
1845                     isvcd_check_mv_diff(ps_temp, (ps_temp + 4 + 1), i4_listx, i4_mv_treshold);
1846 
1847                 /* calculate the excat matching points*/
1848                 i4_8x8_match = i4_8x8_match && i4_horz1_match && i4_vert1_match && i4_diag_match;
1849                 i4_horz_match = i4_horz_match && i4_horz1_match && i4_horz2_match;
1850                 i4_vert_match = i4_vert_match && i4_vert1_match && i4_vert2_match;
1851 
1852                 /* modify the motion vectors appropriately */
1853 
1854                 for(i4_i = 0; i4_i < i4_listx; i4_i++)
1855                 {
1856                     /* 8x8 mode all the 4 blocks are under threshold */
1857                     if(SVCD_TRUE == i4_8x8_match)
1858                     {
1859                         /* calculate the avarage */
1860                         i4_mv_x =
1861                             ((ps_temp[0].i2_mv[2 * i4_i]) + (ps_temp[1].i2_mv[2 * i4_i]) +
1862                              (ps_temp[4].i2_mv[2 * i4_i]) + (ps_temp[5].i2_mv[2 * i4_i] + 2)) >>
1863                             2;
1864 
1865                         i4_mv_y = ((ps_temp[0].i2_mv[1 + (2 * i4_i)]) +
1866                                    (ps_temp[1].i2_mv[1 + (2 * i4_i)]) +
1867                                    (ps_temp[4].i2_mv[1 + (2 * i4_i)]) +
1868                                    (ps_temp[5].i2_mv[1 + (2 * i4_i)] + 2)) >>
1869                                   2;
1870 
1871                         /* store the modified motion vectors */
1872                         ps_temp[0].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1873                         ps_temp[1].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1874                         ps_temp[4].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1875                         ps_temp[5].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1876 
1877                         ps_temp[0].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1878                         ps_temp[1].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1879                         ps_temp[4].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1880                         ps_temp[5].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1881 
1882                         /* store the sub mb partition size */
1883                         i4_part_size = SUBMB_8x8;
1884                     }
1885                     /* 8x4 mode  */
1886                     else if(SVCD_TRUE == i4_horz_match)
1887                     {
1888                         /* horizontal directional merging */
1889                         /* calculate the average of first two and store back*/
1890                         i4_mv_x =
1891                             ((ps_temp[0].i2_mv[2 * i4_i]) + (ps_temp[1].i2_mv[2 * i4_i] + 1)) >> 1;
1892 
1893                         i4_mv_y = ((ps_temp[0].i2_mv[1 + (2 * i4_i)]) +
1894                                    (ps_temp[1].i2_mv[1 + (2 * i4_i)] + 1)) >>
1895                                   1;
1896 
1897                         ps_temp[0].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1898                         ps_temp[1].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1899 
1900                         ps_temp[0].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1901                         ps_temp[1].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1902 
1903                         /* calculate the average of next two and store back*/
1904                         i4_mv_x =
1905                             ((ps_temp[4].i2_mv[2 * i4_i]) + (ps_temp[5].i2_mv[2 * i4_i] + 1)) >> 1;
1906 
1907                         i4_mv_y = ((ps_temp[4].i2_mv[1 + (2 * i4_i)]) +
1908                                    (ps_temp[5].i2_mv[1 + (2 * i4_i)] + 1)) >>
1909                                   1;
1910 
1911                         ps_temp[4].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1912                         ps_temp[5].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1913 
1914                         ps_temp[4].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1915                         ps_temp[5].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1916                         /* store the sub mb partition size */
1917                         i4_part_size = SUBMB_8x4;
1918                     }
1919                     /* 4x8 mode all the 4 blocks are under threshold */
1920                     else if(SVCD_TRUE == i4_vert_match)
1921                     {
1922                         /* vertical directional merging */
1923                         i4_mv_x =
1924                             ((ps_temp[0].i2_mv[2 * i4_i]) + (ps_temp[4].i2_mv[2 * i4_i] + 1)) >> 1;
1925 
1926                         i4_mv_y = ((ps_temp[0].i2_mv[1 + (2 * i4_i)]) +
1927                                    (ps_temp[4].i2_mv[1 + (2 * i4_i)] + 1)) >>
1928                                   1;
1929 
1930                         ps_temp[0].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1931                         ps_temp[4].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1932 
1933                         ps_temp[0].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1934                         ps_temp[4].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1935 
1936                         /* calculate the average of next two and store back*/
1937                         i4_mv_x =
1938                             ((ps_temp[1].i2_mv[2 * i4_i]) + (ps_temp[5].i2_mv[2 * i4_i] + 1)) >> 1;
1939 
1940                         i4_mv_y = ((ps_temp[1].i2_mv[1 + (2 * i4_i)]) +
1941                                    (ps_temp[5].i2_mv[1 + (2 * i4_i)] + 1)) >>
1942                                   1;
1943 
1944                         ps_temp[1].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1945                         ps_temp[5].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
1946 
1947                         ps_temp[1].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1948                         ps_temp[5].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
1949                         /* store the sub mb partition size */
1950                         i4_part_size = SUBMB_4x8;
1951                     }
1952                     else
1953                     {
1954                         /* store the sub mb partition size */
1955                         i4_part_size = SUBMB_4x4;
1956                     }
1957 
1958                 } /* end of loop over lists */
1959 
1960                 /* store the sub MB type B slice */
1961                 if(2 == i4_listx)
1962                 {
1963                     WORD32 i4_part_mode_a;
1964                     WORD32 i4_indx;
1965 
1966                     i4_part_mode_a = 0;
1967                     /* check the 0th partiton reference indices */
1968                     if(0 <= ps_temp[0].i1_ref_frame[0])
1969                     {
1970                         i4_part_mode_a += 1;
1971                     }
1972                     if(0 <= ps_temp[0].i1_ref_frame[1])
1973                     {
1974                         i4_part_mode_a += 2;
1975                     }
1976                     i4_indx = 3 * i4_part_size + (i4_part_mode_a - 1);
1977 
1978                     pi4_sub_mb_mode[2 * i4_yp + i4_xp] = g_au1_eb_submb_type[i4_indx];
1979                 }
1980                 /* P slice */
1981                 else
1982                 {
1983                     pi4_sub_mb_mode[2 * i4_yp + i4_xp] = g_au1_ep_submb_type[i4_part_size];
1984                 }
1985             } /* end of loop over partition xp */
1986 
1987         }     /* end of loop over partition yp */
1988     }
1989 
1990     return;
1991 }
1992 
1993 /*****************************************************************************/
1994 /*                                                                           */
1995 /*  Function Name : isvcd_interlyr_mbmode_pred_bmb                          */
1996 /*                                                                           */
1997 /*  Description   : this module does the mode predcition for base mode B_MB  */
1998 /*                                                                           */
1999 /*                                                                           */
2000 /*  Inputs        : pv_comp_mode_mv_ctxt : motion mode hanldle               */
2001 /*  Globals       : none                                                     */
2002 /*  Processing    : it checks the sub MB type derived motion prediction. if  */
2003 /*                  all partitions are 8x8 then it goes further matching     */
2004 /*                  finally it stores the MB type using a look up table      */
2005 /*  Outputs       : none                                                     */
2006 /*  Returns       : none                                                     */
2007 /*                                                                           */
2008 /*  Issues        : none                                                     */
2009 /*                                                                           */
2010 /*  Revision History:                                                        */
2011 /*                                                                           */
2012 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2013 /*         06 09 2021   vijayakumar          creation                        */
2014 /*                                                                           */
2015 /*****************************************************************************/
isvcd_interlyr_mbmode_pred_bmb(mode_motion_ctxt_t * ps_ctxt,mv_pred_t * ps_motion_pred,WORD32 i4_cur_mot_stride,WORD32 i4_part_size,WORD32 * pi4_sub_mb_mode,void * pv_mb_params,void * pv_part,UWORD8 * pu1_col_info)2016 void isvcd_interlyr_mbmode_pred_bmb(mode_motion_ctxt_t *ps_ctxt, mv_pred_t *ps_motion_pred,
2017                                     WORD32 i4_cur_mot_stride, WORD32 i4_part_size,
2018                                     WORD32 *pi4_sub_mb_mode, void *pv_mb_params, void *pv_part,
2019                                     UWORD8 *pu1_col_info)
2020 {
2021     WORD32 i4_part_mode_a, i4_part_mode_b;
2022     WORD32 i4_idx;
2023     dec_mb_info_t *ps_mb_params = (dec_mb_info_t *) pv_mb_params;
2024     parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
2025 
2026     UNUSED(ps_ctxt);
2027 
2028     i4_part_mode_a = 0;
2029 
2030     /* check the 0th partiton reference indices */
2031     if(PRED_8x8 != i4_part_size)
2032     {
2033         if(0 <= ps_motion_pred[0].i1_ref_frame[0])
2034         {
2035             i4_part_mode_a += 1;
2036         }
2037         if(0 <= ps_motion_pred[0].i1_ref_frame[1])
2038         {
2039             i4_part_mode_a += 2;
2040         }
2041     }
2042 
2043     /* check the 15th partiton reference indices */
2044     /* this done since all the reference indices will be replicated */
2045     i4_part_mode_b = 0;
2046 
2047     if((PRED_16x8 == i4_part_size) || (PRED_8x16 == i4_part_size))
2048     {
2049         ps_motion_pred += (3 * i4_cur_mot_stride) + 3;
2050 
2051         if(0 <= ps_motion_pred[0].i1_ref_frame[0])
2052         {
2053             i4_part_mode_b += 1;
2054         }
2055         if(0 <= ps_motion_pred[0].i1_ref_frame[1])
2056         {
2057             i4_part_mode_b += 2;
2058         }
2059     }
2060     /* update the pred modes for B cases */
2061     /* If partition size is not equal to 8x8 */
2062     /* then update the prediciton mode of    */
2063     /* partitions                            */
2064     if(PRED_8x8 != i4_part_size)
2065     {
2066         UWORD8 u1_pred_mode_part0;
2067         UWORD8 u1_pred_mode_part1;
2068 
2069         i4_idx = 3 * i4_part_size;
2070         i4_idx += 3 * (i4_part_mode_a - 1);
2071         i4_part_mode_b = (i4_part_mode_b > 0) ? i4_part_mode_b : 1;
2072         i4_idx += (i4_part_mode_b - 1);
2073         i4_idx = (i4_idx < 0) ? 0 : i4_idx;
2074         /* Get the mb type                     */
2075         /* From mb type - get prediciton modes */
2076         /*  of parttions                       */
2077         /* Update the prediciton mode parma of */
2078         /* mb param structure                  */
2079 
2080         ps_mb_params->u1_mb_type = g_au1_eb_mb_type[i4_idx + (6 * i4_part_size)];
2081         u1_pred_mode_part0 = g_au1_mb_pred_mode[0][5 + ps_mb_params->u1_mb_type];
2082         u1_pred_mode_part1 = g_au1_mb_pred_mode[1][5 + ps_mb_params->u1_mb_type];
2083         ps_part[0].u1_pred_mode = u1_pred_mode_part0;
2084         ps_part[1].u1_pred_mode = u1_pred_mode_part1;
2085     }
2086     else
2087     {
2088         WORD32 i4_i, i4_ctr, i4_num_submb_part;
2089         UWORD8 u1_sub_mb_type, u1_sub_mb_mc_mode;
2090         UWORD8 u1_pred_mode;
2091 
2092         ps_mb_params->u1_mb_type = B_8x8;
2093 
2094         for(i4_i = 0; i4_i < NUM_MB_PARTS; i4_i++)
2095         {
2096             u1_sub_mb_type = (UWORD8) pi4_sub_mb_mode[i4_i];
2097 
2098             u1_sub_mb_mc_mode = gau1_ih264d_submb_mc_mode[4 + u1_sub_mb_type];
2099             i4_num_submb_part = g_au1_num_sub_mb_part[u1_sub_mb_mc_mode];
2100             *pu1_col_info |= (u1_sub_mb_mc_mode << 4);
2101             pu1_col_info++;
2102             u1_pred_mode = g_au1_sub_mb_pred_mode[4 + u1_sub_mb_type];
2103             for(i4_ctr = 0; i4_ctr < i4_num_submb_part; i4_ctr++)
2104             {
2105                 ps_part->u1_pred_mode = u1_pred_mode;
2106                 ps_part++;
2107             }
2108         }
2109     }
2110 
2111     return;
2112 }
2113 
2114 /*****************************************************************************/
2115 /*                                                                           */
2116 /*  Function Name : isvcd_populate_ref_idx                                    */
2117 /*                                                                           */
2118 /*  Description   : this module populates the reference idx based on the     */
2119 /*                  motion prediction flags                                  */
2120 /*                                                                           */
2121 /*  Inputs        :                                                          */
2122 /*  Globals       : none                                                     */
2123 /*  Processing    :                                                          */
2124 /*  Outputs       : none                                                     */
2125 /*  Returns       : none                                                     */
2126 /*                                                                           */
2127 /*  Issues        : none                                                     */
2128 /*                                                                           */
2129 /*  Revision History:                                                        */
2130 /*                                                                           */
2131 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2132 /*         06 09 2021   vijayakumar          creation                        */
2133 /*                                                                           */
2134 /*****************************************************************************/
2135 
isvcd_populate_ref_idx(dec_mb_info_t * ps_mb_params,dec_svc_mb_info_t * ps_svc_mb_params,mv_pred_t * ps_motion_pred,parse_pmbarams_t * ps_mb_part_info,WORD32 i4_listx)2136 void isvcd_populate_ref_idx(dec_mb_info_t *ps_mb_params, dec_svc_mb_info_t *ps_svc_mb_params,
2137                             mv_pred_t *ps_motion_pred, parse_pmbarams_t *ps_mb_part_info,
2138                             WORD32 i4_listx)
2139 {
2140     UWORD8 u1_mot_pred_flag;
2141     WORD32 i4_lx;
2142 
2143     for(i4_lx = 0; i4_lx < i4_listx; i4_lx++)
2144     {
2145         u1_mot_pred_flag = ps_svc_mb_params->au1_motion_pred_flag[i4_lx];
2146 
2147         if((PRED_16x16 == ps_mb_params->u1_mb_mc_mode) && (u1_mot_pred_flag & 0x1))
2148         {
2149             ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
2150         }
2151         else if((PRED_8x16 == ps_mb_params->u1_mb_mc_mode))
2152         {
2153             if(u1_mot_pred_flag & 0x01)
2154             {
2155                 ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
2156             }
2157             if(u1_mot_pred_flag & 0x02)
2158             {
2159                 ps_mb_part_info->i1_ref_idx[i4_lx][1] = ps_motion_pred[2].i1_ref_frame[i4_lx];
2160             }
2161         }
2162         else if((PRED_16x8 == ps_mb_params->u1_mb_mc_mode))
2163         {
2164             if(u1_mot_pred_flag & 0x01)
2165             {
2166                 ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
2167             }
2168             if(u1_mot_pred_flag & 0x02)
2169             {
2170                 ps_mb_part_info->i1_ref_idx[i4_lx][1] = ps_motion_pred[8].i1_ref_frame[i4_lx];
2171             }
2172         }
2173         else if((PRED_8x8 == ps_mb_params->u1_mb_mc_mode))
2174         {
2175             if(u1_mot_pred_flag & 0x01)
2176             {
2177                 ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
2178             }
2179             if(u1_mot_pred_flag & 0x02)
2180             {
2181                 ps_mb_part_info->i1_ref_idx[i4_lx][1] = ps_motion_pred[2].i1_ref_frame[i4_lx];
2182             }
2183             if(u1_mot_pred_flag & 0x04)
2184             {
2185                 ps_mb_part_info->i1_ref_idx[i4_lx][2] = ps_motion_pred[8].i1_ref_frame[i4_lx];
2186             }
2187             if(u1_mot_pred_flag & 0x08)
2188             {
2189                 ps_mb_part_info->i1_ref_idx[i4_lx][3] = ps_motion_pred[10].i1_ref_frame[i4_lx];
2190             }
2191         }
2192     }
2193 }
2194 
2195 /*****************************************************************************/
2196 /*                                                                           */
2197 /*  Function Name : svcd_interlayer_mbmode_pred                              */
2198 /*                                                                           */
2199 /*  Description   : this module does the mode predcition for base mode MB    */
2200 /*                                                                           */
2201 /*                                                                           */
2202 /*  Inputs        : pv_comp_mode_mv_ctxt : motion mode hanldle               */
2203 /*                  pv_mb_params   : pointer to MB params structure          */
2204 /*                  pi4_sub_mb_mode: pointer to sub mbmodes predicted        */
2205 /*  Globals       : none                                                     */
2206 /*  Processing    : it checks the sub MB type derived motion prediction. if  */
2207 /*                  all partitions are 8x8 then it goes further matching     */
2208 /*                  finally it stores the MB type using a look up table      */
2209 /*  Outputs       : none                                                     */
2210 /*  Returns       : none                                                     */
2211 /*                                                                           */
2212 /*  Issues        : none                                                     */
2213 /*                                                                           */
2214 /*  Revision History:                                                        */
2215 /*                                                                           */
2216 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2217 /*         06 09 2021   vijayakumar          creation                        */
2218 /*                                                                           */
2219 /*****************************************************************************/
isvcd_interlyr_mbmode_pred(void * pv_comp_mode_mv_ctxt,void * pv_mb_params,WORD32 * pi4_sub_mb_mode,WORD32 * pi4_mb_mode,void * pv_dec,void * pv_mb_part_info,void * pv_part)2220 void isvcd_interlyr_mbmode_pred(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
2221                                 WORD32 *pi4_sub_mb_mode, WORD32 *pi4_mb_mode, void *pv_dec,
2222                                 void *pv_mb_part_info, void *pv_part)
2223 {
2224     /*! Flow of the module is as follows                                   */
2225     /*! 1. it checks if all the sub mb modes are 8x8 modes                 */
2226     /*! 2. it matches the motion vectors at 8x8 level and computes the
2227            partiton size. store the same in the part type of mb params     */
2228     /*! 3. stores the pred modes based on slcie type and reference indices */
2229     /*! 4. stores the sub mb type in the mb params if teh part size is 8x8 */
2230     mode_motion_ctxt_t *ps_ctxt;
2231     mv_pred_t *ps_motion_pred;
2232     dec_mb_info_t *ps_mb_params;
2233     WORD32 i4_listx;
2234     WORD32 i4_part_size;
2235     WORD32 i4_mb_mode_flag;
2236     WORD32 i4_i;
2237     WORD32 i4_blk_mode;
2238     parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
2239     parse_pmbarams_t *ps_mb_part_info = (parse_pmbarams_t *) pv_mb_part_info;
2240     UWORD8 *pu1_col_info = ps_mb_part_info->u1_col_info;
2241     UNUSED(pv_dec);
2242 
2243     ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
2244     ps_motion_pred = ps_ctxt->ps_motion_pred_struct;
2245     ps_mb_params = (dec_mb_info_t *) pv_mb_params;
2246 
2247     /*********** store the MB mode as inter *************************/
2248     *pi4_mb_mode = SVC_INTER_MB;
2249 
2250     /***********************************************************************/
2251     /* derivation of part type                                             */
2252     /***********************************************************************/
2253     i4_listx = ps_ctxt->i4_listx;
2254 
2255     /* set the mb mode derivation flag to false */
2256     i4_mb_mode_flag = SVCD_FALSE;
2257 
2258     /* for B and P slice different blk mod treshold */
2259     if(2 == i4_listx)
2260     {
2261         i4_blk_mode = B_BI_8x8;
2262     }
2263     else
2264     {
2265         i4_blk_mode = P_L0_8x8;
2266     }
2267 
2268     /* set the mode derivation flag to true base on conditions */
2269     if((i4_blk_mode >= pi4_sub_mb_mode[0]) && (i4_blk_mode >= pi4_sub_mb_mode[1]) &&
2270        (i4_blk_mode >= pi4_sub_mb_mode[2]) && (i4_blk_mode >= pi4_sub_mb_mode[3]))
2271     {
2272         i4_mb_mode_flag = SVCD_TRUE;
2273     }
2274 
2275     /* store the default 8x8 mode */
2276     ps_mb_part_info->u1_num_part = 4;
2277     i4_part_size = PRED_8x8;
2278 
2279     /* further check is present if all are 8x8 mode */
2280     if(SVCD_TRUE == i4_mb_mode_flag)
2281     {
2282         WORD32 i4_horz_match, i4_vert_match;
2283 
2284         /* check if the motion in horz direction are same*/
2285         i4_horz_match = isvcd_check_motion(ps_motion_pred, (ps_motion_pred + 2), i4_listx);
2286         i4_horz_match += isvcd_check_motion((ps_motion_pred + 8), (ps_motion_pred + 10), i4_listx);
2287 
2288         /* check if the motion in vertical direction is same */
2289         i4_vert_match = isvcd_check_motion(ps_motion_pred, (ps_motion_pred + 8), i4_listx);
2290         i4_vert_match += isvcd_check_motion((ps_motion_pred + 2), (ps_motion_pred + 10), i4_listx);
2291 
2292         /* decide the partition size based on the results of matching */
2293         if((2 == i4_horz_match) && (2 == i4_vert_match))
2294         {
2295             ps_mb_params->u1_mb_type = P_L0_16x16;
2296             i4_part_size = PRED_16x16;
2297             ps_mb_part_info->u1_num_part = 1;
2298             *pu1_col_info++ = (PRED_16x16 << 6);
2299             ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
2300             if(2 == i4_listx) ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
2301 
2302             ps_part->u1_partwidth = 4;  // interms of 4x4
2303             ps_part->u1_partheight = 4;
2304             ps_part->u1_pred_mode = PRED_L0;
2305             ps_part->u1_is_direct = 0;
2306             ps_part->u1_sub_mb_num = 0;
2307         }
2308         else if(2 == i4_horz_match)
2309         {
2310             i4_part_size = PRED_16x8;
2311             ps_mb_params->u1_mb_type = P_L0_L0_16x8;
2312             ps_mb_part_info->u1_num_part = 2;
2313             *pu1_col_info++ = (PRED_16x8 << 6);
2314             *pu1_col_info++ = (PRED_16x8 << 6);
2315 
2316             ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
2317             ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[8].i1_ref_frame[0];
2318             if(2 == i4_listx)
2319             {
2320                 ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
2321                 ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[8].i1_ref_frame[1];
2322             }
2323             ps_part->u1_partwidth = 4;  // interms of 4x4
2324             ps_part->u1_partheight = 2;
2325             ps_part->u1_pred_mode = PRED_L0;
2326             ps_part->u1_is_direct = 0;
2327             ps_part->u1_sub_mb_num = 0;
2328 
2329             ps_part++;
2330             ps_part->u1_partwidth = 4;
2331             ps_part->u1_partheight = 2;
2332             ps_part->u1_pred_mode = PRED_L0;
2333             ps_part->u1_is_direct = 0;
2334             ps_part->u1_sub_mb_num = 8;
2335         }
2336         else if(2 == i4_vert_match)
2337         {
2338             ps_mb_params->u1_mb_type = P_L0_L0_8x16;
2339             i4_part_size = PRED_8x16;
2340             ps_mb_part_info->u1_num_part = 2;
2341             *pu1_col_info++ = (PRED_8x16 << 6);
2342             *pu1_col_info++ = (PRED_8x16 << 6);
2343 
2344             ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
2345             ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
2346             if(2 == i4_listx)
2347             {
2348                 ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
2349                 ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
2350             }
2351             ps_part->u1_partwidth = 2;  // interms of 4x4
2352             ps_part->u1_partheight = 4;
2353             ps_part->u1_pred_mode = PRED_L0;
2354             ps_part->u1_is_direct = 0;
2355             ps_part->u1_sub_mb_num = 0;
2356 
2357             ps_part++;
2358             ps_part->u1_partwidth = 2;
2359             ps_part->u1_partheight = 4;
2360             ps_part->u1_pred_mode = PRED_L0;
2361             ps_part->u1_is_direct = 0;
2362             ps_part->u1_sub_mb_num = 2;
2363         }
2364     }
2365 
2366     /* store the part size to the mb params */
2367     ps_mb_params->u1_mb_mc_mode = i4_part_size;
2368 
2369     /* in case of slice derive the partition modes */
2370 
2371     {
2372         /* store the sub MB modes if 8x8 mode is choosen */
2373         if(PRED_8x8 == i4_part_size)
2374         {
2375             UWORD8 u1_sub_mb_type, u1_sub_mb_mc_mode = 0;
2376 
2377             /* for P_MB sub part type is same as sub mb type */
2378             ps_mb_params->u1_mb_type = P_8x8;
2379             ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred[0].i1_ref_frame[0];
2380             ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
2381             ps_mb_part_info->i1_ref_idx[0][2] = ps_motion_pred[8].i1_ref_frame[0];
2382             ps_mb_part_info->i1_ref_idx[0][3] = ps_motion_pred[10].i1_ref_frame[0];
2383             if(2 == i4_listx)
2384             {
2385                 ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred[0].i1_ref_frame[1];
2386                 ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
2387                 ps_mb_part_info->i1_ref_idx[1][2] = ps_motion_pred[8].i1_ref_frame[1];
2388                 ps_mb_part_info->i1_ref_idx[1][3] = ps_motion_pred[10].i1_ref_frame[1];
2389             }
2390 
2391             ps_mb_part_info->u1_num_part = 0;
2392             for(i4_i = 0; i4_i < NUM_MB_PARTS; i4_i++)
2393             {
2394                 WORD32 i4_num_submb_part, i4_part_width, i4_part_height, i4_ctr;
2395                 u1_sub_mb_type = (UWORD8) pi4_sub_mb_mode[i4_i];
2396 
2397                 if(1 == i4_listx)
2398                 {
2399                     u1_sub_mb_mc_mode = gau1_ih264d_submb_mc_mode[u1_sub_mb_type];
2400                 }
2401                 else if(2 == i4_listx)
2402                 {
2403                     u1_sub_mb_mc_mode = gau1_ih264d_submb_mc_mode[4 + u1_sub_mb_type];
2404                 }
2405                 i4_num_submb_part = g_au1_num_sub_mb_part[u1_sub_mb_mc_mode];
2406 
2407                 ps_mb_part_info->u1_num_part += i4_num_submb_part;
2408 
2409                 i4_part_width = g_au1_sub_mb_part_wd[u1_sub_mb_mc_mode];
2410                 i4_part_height = g_au1_sub_mb_part_ht[u1_sub_mb_mc_mode];
2411                 *pu1_col_info++ = (PRED_8x8 << 6) | (u1_sub_mb_mc_mode << 4);
2412                 for(i4_ctr = 0; i4_ctr < i4_num_submb_part; i4_ctr++)
2413                 {
2414                     ps_part->u1_partwidth = i4_part_width;  // interms of 4x4
2415                     ps_part->u1_partheight = i4_part_height;
2416                     ps_part->u1_pred_mode = PRED_L0;
2417                     ps_part->u1_is_direct = 0;
2418                     ps_part->u1_sub_mb_num = (i4_i & 0x01) * 2 + (i4_i >> 1) * 8;
2419                     if(i4_num_submb_part == 2)
2420                     {
2421                         ps_part->u1_sub_mb_num +=
2422                             i4_ctr ? (((i4_part_width - 1) << 2) + (i4_part_height - 1)) : 0;
2423                     }
2424                     else if(i4_num_submb_part == 4)
2425                     {
2426                         ps_part->u1_sub_mb_num += ((i4_ctr >> 1) << 2) + (i4_ctr & 0x01);
2427                     }
2428 
2429                     ps_part++;
2430                 }
2431             }
2432         }
2433         if(2 == i4_listx)
2434         {
2435             ps_part = (parse_part_params_t *) pv_part;
2436             pu1_col_info = ps_mb_part_info->u1_col_info;
2437             /* B_MBs */
2438             isvcd_interlyr_mbmode_pred_bmb(ps_ctxt, ps_motion_pred, 4, i4_part_size,
2439                                            pi4_sub_mb_mode, ps_mb_params, ps_part, pu1_col_info);
2440         }
2441     }
2442 
2443     return;
2444 }
2445 /*****************************************************************************/
2446 /*                                                                           */
2447 /*  Function Name :  isvcd_compute_interlayer_motion_mode                     */
2448 /*                                                                           */
2449 /*  Description   : this function does the  inter layer motion and mode      */
2450 /*                  prediction. of the current MB                            */
2451 /*                                                                           */
2452 /*  Inputs        : pv_comp_mode_mv_ctxt : mode motion handle                */
2453 /*                  pv_ref_layer_motion_mem_elements :  pointer to memory    */
2454 /*                    elements of reference layer motion params              */
2455 /*                  pv_mb_params : pointer to mb params structure            */
2456 /*  Globals       : none                                                     */
2457 /*  Processing    : it calls the module for cal ref part idc and intra flag  */
2458 /*                  if not intra it calls the motion prediction module       */
2459 /*                  if base mdoe flag then it call teh mode prediction module*/
2460 /*  Outputs       : inter layer predicted parameters                         */
2461 /*  Returns       : none                                                     */
2462 /*                                                                           */
2463 /*  Issues        : none                                                     */
2464 /*                                                                           */
2465 /*  Revision History:                                                        */
2466 /*                                                                           */
2467 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2468 /*         06 09 2021   vijayakumar          creation                        */
2469 /*                                                                           */
2470 /*****************************************************************************/
isvcd_compute_interlyr_motion_mode(void * pv_comp_mode_mv_ctxt,void * pv_mb_params,void * pv_svc_mb_params,void * pv_dec,void * pv_mb_part_info,void * pv_part)2471 WORD32 isvcd_compute_interlyr_motion_mode(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
2472                                           void *pv_svc_mb_params, void *pv_dec,
2473                                           void *pv_mb_part_info, void *pv_part)
2474 {
2475     /*! Flow of the module is as follows                                   */
2476     /*! 1. if dyaydic case then it sets the sub mb mode to 8x8             */
2477     /*! 2. else it call the ref part idc comute fucntion                   */
2478     /*! 3. it calls the motion vectors and submb mode derive function.
2479            if the current mb is not inffered as INTRA                      */
2480     /*! 4. it calls the mode predcition module if base mode flag is 1      */
2481 
2482     mode_motion_ctxt_t *ps_ctxt;
2483     WORD32 i4_intra_flag;
2484     WORD32 ai4_sub_mb_mode[NUM_MB_PARTS] = {0};
2485     dec_mb_info_t *ps_mb_params;
2486     dec_svc_mb_info_t *ps_svc_mb_params;
2487     dec_struct_t *ps_dec = (dec_struct_t *) pv_dec;
2488     WORD32 i4_mb_mode = -1;
2489     parse_pmbarams_t *ps_mb_part_info = (parse_pmbarams_t *) pv_mb_part_info;
2490     parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
2491 
2492     ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
2493     ps_mb_params = (dec_mb_info_t *) pv_mb_params;
2494     ps_svc_mb_params = (dec_svc_mb_info_t *) pv_svc_mb_params;
2495 
2496     i4_intra_flag = SVCD_FALSE;
2497 
2498     isvcd_ref_lyr_part_idc(pv_comp_mode_mv_ctxt, ps_ctxt->ai4_ref_part_idc, &i4_intra_flag,
2499                            pv_mb_params);
2500 
2501     /* If base is Intra */
2502     if(SVCD_TRUE == i4_intra_flag)
2503     {
2504         if(1 == ps_svc_mb_params->u1_base_mode_flag)
2505         {
2506             i4_mb_mode = SVC_IBL_MB;
2507             ps_svc_mb_params->u1_residual_prediction_flag = 0;
2508         }
2509     }
2510     else
2511     {
2512         /* derive the motion and reference index by inter layer predcition */
2513         isvcd_interlyr_motion_submbmode_pred(pv_comp_mode_mv_ctxt, ps_mb_params, ps_svc_mb_params,
2514                                              ps_ctxt->ai4_ref_part_idc, ai4_sub_mb_mode, pv_dec);
2515 
2516         /* derive the MB mode */
2517         if(1 == ps_svc_mb_params->u1_base_mode_flag)
2518         {
2519             isvcd_interlyr_mbmode_pred(pv_comp_mode_mv_ctxt, pv_mb_params, ai4_sub_mb_mode,
2520                                        &i4_mb_mode, ps_dec, ps_mb_part_info, ps_part);
2521         }
2522         else
2523         {
2524             isvcd_populate_ref_idx(ps_mb_params, ps_svc_mb_params, ps_ctxt->ps_motion_pred_struct,
2525                                    ps_mb_part_info, ps_ctxt->i4_listx);
2526         }
2527     }
2528 
2529     return i4_mb_mode;
2530 }
2531 
2532 /*****************************************************************************/
2533 /*                                                                           */
2534 /*  Function Name :  isvcd_interlyr_motion_mode_pred_dyadic                   */
2535 /*                                                                           */
2536 /*  Description   : this function does the inter layer motion predcition for */
2537 /*                   dyadic cases                                            */
2538 /*                                                                           */
2539 /*  Inputs        : pv_comp_mode_mv_ctxt : motion mode handle                */
2540 /*                  pv_ref_layer_motion_mem_elements : pointer to memory     */
2541 /*                    elements of reference layer motion params              */
2542 /*                  pv_mb_params : pointer to MB params structure            */
2543 /*                  ai4_ref_part_idc : ref partitons idc of all 4x4 blocks   */
2544 /*                  pi4_sub_mb_mode  : pointer to store the sub mb modes     */
2545 /*                  i4_mb_addr       : current mb address                    */
2546 /*                  pi4_intra_flag   : location to store the intra status    */
2547 /*  Globals       : none                                                     */
2548 /*  Processing    : it computes the motion vectors and                       */
2549 /*  Outputs       : inter layer predicted motion vectors and ref indices     */
2550 /*                  sub mbmodes of the 4 mb partitions                       */
2551 /*  Returns       : none                                                     */
2552 /*                                                                           */
2553 /*  Issues        : none                                                     */
2554 /*                                                                           */
2555 /*  Revision History:                                                        */
2556 /*                                                                           */
2557 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2558 /*         06 09 2021   vijayakumar          creation                        */
2559 /*                                                                           */
2560 /*****************************************************************************/
isvcd_interlyr_motion_mode_pred_dyadic(void * pv_comp_mode_mv_ctxt,void * pv_mb_params,void * pv_svc_mb_params,void * pv_dec,void * pv_mb_part_info,void * pv_part)2561 WORD32 isvcd_interlyr_motion_mode_pred_dyadic(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
2562                                               void *pv_svc_mb_params, void *pv_dec,
2563                                               void *pv_mb_part_info, void *pv_part)
2564 {
2565     mode_motion_ctxt_t *ps_ctxt;
2566     mode_motion_lyr_ctxt *ps_lyr_mem;
2567     dec_mb_info_t *ps_mb_params;
2568     dec_svc_mb_info_t *ps_svc_mb_params;
2569     WORD32 i4_listx;
2570     WORD32 i4_mb_pic_x, i4_mb_pic_y;
2571     WORD32 i4_ref_x, i4_ref_y;
2572     UWORD8 u1_base_mode_flag;
2573     dec_struct_t *ps_dec = (dec_struct_t *) pv_dec;
2574     WORD32 i4_mb_mode = -1;
2575     parse_pmbarams_t *ps_mb_part_info = (parse_pmbarams_t *) pv_mb_part_info;
2576     UWORD8 *pu1_col_info = ps_mb_part_info->u1_col_info;
2577     parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
2578 
2579     ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
2580 
2581     /* get the current layer ctxt */
2582     ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
2583 
2584     ps_mb_params = (dec_mb_info_t *) pv_mb_params;
2585     ps_svc_mb_params = (dec_svc_mb_info_t *) pv_svc_mb_params;
2586     i4_listx = ps_ctxt->i4_listx;
2587 
2588     {
2589         WORD32 i4_mb_x, i4_mb_y;
2590         /* derive the MB_X and MB_Y for the current MB */
2591         i4_mb_x = ps_mb_params->u2_mbx;
2592         i4_mb_y = ps_mb_params->u2_mby;
2593 
2594         /* get the colocated position in the refernce layer */
2595         i4_ref_x = ps_lyr_mem->pi2_ref_loc_x[i4_mb_x << 4];
2596         i4_ref_y = ps_lyr_mem->pi2_ref_loc_y[i4_mb_y << 4];
2597         i4_ref_x = CLIP3(0, ((ps_lyr_mem->i4_ref_width) - 1), i4_ref_x);
2598         i4_ref_y = CLIP3(0, ((ps_lyr_mem->i4_ref_height) - 1), i4_ref_y);
2599 
2600         /* convert into picture units */
2601         i4_mb_pic_x = i4_mb_x << 4;
2602         i4_mb_pic_y = i4_mb_y << 4;
2603     }
2604 
2605     /* ref layer mb mode */
2606     {
2607         inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
2608         WORD32 i4_inter_lyr_mb_prms_stride;
2609         WORD32 i4_ref_mb_x, i4_ref_mb_y;
2610         WORD8 i1_ref_mb_mode;
2611 
2612         ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) ps_lyr_mem->s_ref_mb_mode.pv_buffer;
2613         i4_inter_lyr_mb_prms_stride = ps_lyr_mem->s_ref_mb_mode.i4_num_element_stride;
2614 
2615         /* get the reference mb x and y */
2616         i4_ref_mb_x = (i4_ref_x >> 4);
2617         i4_ref_mb_y = (i4_ref_y >> 4);
2618 
2619         /* get the appropriate mb params in reference layer */
2620         ps_inter_lyr_mb_prms += i4_ref_mb_x;
2621         ps_inter_lyr_mb_prms += i4_ref_mb_y * i4_inter_lyr_mb_prms_stride;
2622         i1_ref_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
2623         u1_base_mode_flag = ps_svc_mb_params->u1_base_mode_flag;
2624 
2625         /* check if the MB mode of the refernce MB is Intra*/
2626         if(i1_ref_mb_mode > SVC_INTER_MB)
2627         {
2628             if(1 == u1_base_mode_flag)
2629             {
2630                 i4_mb_mode = SVC_IBL_MB;
2631                 ps_svc_mb_params->u1_residual_prediction_flag = 0;
2632             }
2633             return i4_mb_mode;
2634         }
2635     }
2636 
2637     /*-----------------------------------------------------------------------*/
2638     /* Inter MB upsampling process                                           */
2639     /*-----------------------------------------------------------------------*/
2640     {
2641         mv_pred_t *ps_motion_pred;
2642         WORD32 i4_16x16_flag;
2643         WORD32 i4_part_idc;
2644         WORD32 i4_blk_idx;
2645         WORD32 i4_curr_mot_stride;
2646 
2647         /* choose the appropriate mv bank pointer and stride */
2648         if(1 == u1_base_mode_flag)
2649         {
2650             i4_mb_mode = SVC_INTER_MB;
2651         }
2652 
2653         ps_motion_pred = ps_ctxt->ps_motion_pred_struct;
2654         i4_curr_mot_stride = 4;
2655 
2656         /* call the motion upsampling for 1st 4x4 */
2657         i4_part_idc = (i4_ref_y << 16) + i4_ref_x;
2658         i4_16x16_flag = isvcd_interlyr_motion_scale(
2659             pv_comp_mode_mv_ctxt, &i4_part_idc, ps_mb_params, ps_motion_pred, i4_listx,
2660             (i4_mb_pic_x + 1), (i4_mb_pic_y + 1), ps_dec->ppv_map_ref_idx_to_poc);
2661 
2662         /* ---------- reference layer MB is 16x16 ------------------*/
2663         if(i4_16x16_flag)
2664         {
2665             if(1 == u1_base_mode_flag)
2666             {
2667                 ps_mb_params->u1_mb_type = P_L0_16x16;
2668                 ps_mb_params->u1_mb_mc_mode = PRED_16x16;
2669                 ps_mb_part_info->u1_num_part = 1;
2670                 *pu1_col_info++ = (PRED_16x16 << 6);
2671                 ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
2672 
2673                 ps_part->u1_partwidth = 4;  // interms of 4x4
2674                 ps_part->u1_partheight = 4;
2675                 ps_part->u1_pred_mode = PRED_L0;
2676                 ps_part->u1_is_direct = 0;
2677                 ps_part->u1_sub_mb_num = 0;
2678 
2679                 if(2 == i4_listx)
2680                 {
2681                     WORD32 i4_part_mode_a = 0;
2682                     WORD32 i4_temp;
2683 
2684                     ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
2685                     if(0 <= ps_motion_pred[0].i1_ref_frame[0])
2686                     {
2687                         i4_part_mode_a += 1;
2688                     }
2689                     if(0 <= ps_motion_pred[0].i1_ref_frame[1])
2690                     {
2691                         i4_part_mode_a += 2;
2692                     }
2693 
2694                     i4_temp = 3 * PRED_16x16;
2695                     i4_temp += (3 * (i4_part_mode_a - 1) - 1);
2696                     i4_temp = (i4_temp < 0) ? 0 : i4_temp;
2697                     i4_temp = g_au1_eb_mb_type[i4_temp];
2698                     ps_mb_params->u1_mb_type = i4_temp;
2699                     ps_part->u1_pred_mode = g_au1_mb_pred_mode[0][5 + i4_temp];
2700                 }
2701             }
2702             else
2703             {
2704                 /* motion prediction flag cases replicate the motion vectors for entire MB */
2705                 isvcd_store_motion_map(ps_motion_pred, (ps_motion_pred), 0, i4_curr_mot_stride,
2706                                        NUM_MB_PARTS, NUM_MB_PARTS, SVCD_FALSE);
2707 
2708                 isvcd_populate_ref_idx(ps_mb_params, ps_svc_mb_params, ps_motion_pred,
2709                                        ps_mb_part_info, i4_listx);
2710             }
2711             return i4_mb_mode;
2712         }
2713         /* ---------- reference layer MB is non 16x16 ------------------ */
2714         else
2715         {
2716             WORD32 ai4_sub_mb_mode[NUM_MB_PARTS] = {0};
2717 
2718             /* replicate the motion vectors for 8x8 */
2719             isvcd_store_motion_map(ps_motion_pred, ps_motion_pred, 0, i4_curr_mot_stride, 2, 2,
2720                                    SVCD_FALSE);
2721 
2722             if(2 == i4_listx)
2723             {
2724                 WORD32 i4_indx = 0;
2725 
2726                 /* replicate the motion vectors for 8x8 */
2727                 /* check the 0th partiton reference indices */
2728                 if(0 <= ps_motion_pred[0].i1_ref_frame[0])
2729                 {
2730                     i4_indx += 1;
2731                 }
2732                 if(0 <= ps_motion_pred[0].i1_ref_frame[1])
2733                 {
2734                     i4_indx += 2;
2735                 }
2736 
2737                 i4_indx = 3 * PRED_8x8 + (i4_indx - 1);
2738                 ai4_sub_mb_mode[0] = g_au1_eb_submb_type[i4_indx];
2739             }
2740 
2741             /* derive the motion vectors and reference indices of 3 rem partitions */
2742             for(i4_blk_idx = 1; i4_blk_idx < NUM_MB_PARTS; i4_blk_idx++)
2743             {
2744                 WORD32 i4_blk_y, i4_blk_x;
2745                 mv_pred_t *ps_temp;
2746 
2747                 i4_blk_x = i4_blk_idx & 1;
2748                 i4_blk_y = i4_blk_idx >> 1;
2749 
2750                 ps_temp = ps_motion_pred + (i4_blk_x << 1);
2751                 ps_temp += (i4_blk_y * i4_curr_mot_stride << 1);
2752 
2753                 /* store the reference layer positions */
2754                 i4_part_idc = ((i4_ref_y + (i4_blk_y << 2)) << 16) + (i4_ref_x + (i4_blk_x << 2));
2755                 isvcd_interlyr_motion_scale(pv_comp_mode_mv_ctxt, &i4_part_idc, ps_mb_params,
2756                                             ps_temp, i4_listx, (i4_mb_pic_x + (i4_blk_x << 2) + 1),
2757                                             (i4_mb_pic_y + (i4_blk_y << 2) + 1),
2758                                             ps_dec->ppv_map_ref_idx_to_poc);
2759 
2760                 /* replicate the motion vectors for 8x8 */
2761                 isvcd_store_motion_map(ps_temp, ps_temp, 0, i4_curr_mot_stride, 2, 2, SVCD_FALSE);
2762 
2763                 if(2 == i4_listx)
2764                 {
2765                     WORD32 i4_indx = 0;
2766 
2767                     /* check the 0th partiton reference indices */
2768                     if(0 <= ps_temp[0].i1_ref_frame[0])
2769                     {
2770                         i4_indx += 1;
2771                     }
2772                     if(0 <= ps_temp[0].i1_ref_frame[1])
2773                     {
2774                         i4_indx += 2;
2775                     }
2776 
2777                     i4_indx = 3 * PRED_8x8 + (i4_indx - 1);
2778 
2779                     ai4_sub_mb_mode[i4_blk_idx] = g_au1_eb_submb_type[i4_indx];
2780                 }
2781             }
2782 
2783             /* if MB mode has to derivied */
2784             if(1 == u1_base_mode_flag)
2785             {
2786                 WORD32 i4_horz_match, i4_vert_match;
2787                 WORD32 i4_part_size = PRED_8x8;
2788 
2789                 mv_pred_t *ps_motion_1;
2790                 mv_pred_t *ps_motion_2;
2791                 mv_pred_t *ps_motion_3;
2792 
2793                 ps_motion_1 = ps_motion_pred + 2;
2794                 ps_motion_2 = ps_motion_pred + (i4_curr_mot_stride << 1);
2795                 ps_motion_3 = ps_motion_2 + 2;
2796 
2797                 /* check if the motion in horz direction are same*/
2798                 i4_horz_match = isvcd_check_motion(ps_motion_pred, ps_motion_1, i4_listx);
2799                 i4_horz_match += isvcd_check_motion(ps_motion_2, ps_motion_3, i4_listx);
2800 
2801                 /* check if the motion in vertical direction is same */
2802                 i4_vert_match = isvcd_check_motion(ps_motion_pred, ps_motion_2, i4_listx);
2803                 i4_vert_match += isvcd_check_motion(ps_motion_1, ps_motion_3, i4_listx);
2804 
2805                 ps_mb_part_info->u1_num_part = 4;
2806 
2807                 /* decide the partition size based on the results of matching */
2808                 if((2 == i4_horz_match) && (2 == i4_vert_match))
2809                 {
2810                     ps_mb_params->u1_mb_type = P_L0_16x16;
2811                     i4_part_size = PRED_16x16;
2812                     ps_mb_part_info->u1_num_part = 1;
2813                     *pu1_col_info++ = (PRED_16x16 << 6);
2814 
2815                     ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
2816                     if(2 == i4_listx)
2817                         ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
2818 
2819                     ps_part->u1_partwidth = 4;  // interms of 4x4
2820                     ps_part->u1_partheight = 4;
2821                     ps_part->u1_pred_mode = PRED_L0;
2822                     ps_part->u1_is_direct = 0;
2823                     ps_part->u1_sub_mb_num = 0;
2824                 }
2825                 else if(2 == i4_horz_match)
2826                 {
2827                     ps_mb_params->u1_mb_type = P_L0_L0_16x8;
2828                     i4_part_size = PRED_16x8;
2829                     ps_mb_part_info->u1_num_part = 2;
2830                     *pu1_col_info++ = (PRED_16x8 << 6);
2831                     *pu1_col_info++ = (PRED_16x8 << 6);
2832 
2833                     ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
2834                     ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[8].i1_ref_frame[0];
2835                     if(2 == i4_listx)
2836                     {
2837                         ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
2838                         ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[8].i1_ref_frame[1];
2839                     }
2840                     ps_part->u1_partwidth = 4;  // interms of 4x4
2841                     ps_part->u1_partheight = 2;
2842                     ps_part->u1_pred_mode = PRED_L0;
2843                     ps_part->u1_is_direct = 0;
2844                     ps_part->u1_sub_mb_num = 0;
2845 
2846                     ps_part++;
2847                     ps_part->u1_partwidth = 4;
2848                     ps_part->u1_partheight = 2;
2849                     ps_part->u1_pred_mode = PRED_L0;
2850                     ps_part->u1_is_direct = 0;
2851                     ps_part->u1_sub_mb_num = 8;
2852                 }
2853                 else if(2 == i4_vert_match)
2854                 {
2855                     ps_mb_params->u1_mb_type = P_L0_L0_8x16;
2856                     i4_part_size = PRED_8x16;
2857                     ps_mb_part_info->u1_num_part = 2;
2858                     *pu1_col_info++ = (PRED_8x16 << 6);
2859                     *pu1_col_info++ = (PRED_8x16 << 6);
2860 
2861                     ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
2862                     ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
2863                     if(2 == i4_listx)
2864                     {
2865                         ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
2866                         ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
2867                     }
2868                     ps_part->u1_partwidth = 2;  // interms of 4x4
2869                     ps_part->u1_partheight = 4;
2870                     ps_part->u1_pred_mode = PRED_L0;
2871                     ps_part->u1_is_direct = 0;
2872                     ps_part->u1_sub_mb_num = 0;
2873 
2874                     ps_part++;
2875                     ps_part->u1_partwidth = 2;
2876                     ps_part->u1_partheight = 4;
2877                     ps_part->u1_pred_mode = PRED_L0;
2878                     ps_part->u1_is_direct = 0;
2879                     ps_part->u1_sub_mb_num = 2;
2880                 }
2881 
2882                 /* store the part size to the mb params */
2883                 ps_mb_params->u1_mb_mc_mode = i4_part_size;
2884 
2885                 /* store the sub partition size */
2886                 if(PRED_8x8 == i4_part_size)
2887                 {
2888                     UWORD8 u1_ctr;
2889                     /* for P_MB sub part type is P_L0_8x8*/
2890 
2891                     ps_mb_params->u1_mb_type = P_8x8;
2892                     ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred[0].i1_ref_frame[0];
2893                     ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
2894                     ps_mb_part_info->i1_ref_idx[0][2] = ps_motion_pred[8].i1_ref_frame[0];
2895                     ps_mb_part_info->i1_ref_idx[0][3] = ps_motion_pred[10].i1_ref_frame[0];
2896                     if(2 == i4_listx)
2897                     {
2898                         ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred[0].i1_ref_frame[1];
2899                         ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
2900                         ps_mb_part_info->i1_ref_idx[1][2] = ps_motion_pred[8].i1_ref_frame[1];
2901                         ps_mb_part_info->i1_ref_idx[1][3] = ps_motion_pred[10].i1_ref_frame[1];
2902                     }
2903 
2904                     for(u1_ctr = 0; u1_ctr < 4; u1_ctr++)
2905                     {
2906                         *pu1_col_info++ = (PRED_8x8 << 6);
2907 
2908                         ps_part->u1_partwidth = 2;  // interms of 4x4
2909                         ps_part->u1_partheight = 2;
2910                         ps_part->u1_pred_mode = PRED_L0;
2911                         ps_part->u1_is_direct = 0;
2912                         ps_part->u1_sub_mb_num = (u1_ctr & 0x01) * 2 + (u1_ctr >> 1) * 8;
2913                         ps_part++;
2914                     }
2915                 }
2916 
2917                 if(2 == i4_listx)
2918                 {
2919                     ps_part = (parse_part_params_t *) pv_part;
2920                     pu1_col_info = ps_mb_part_info->u1_col_info;
2921                     isvcd_interlyr_mbmode_pred_bmb(ps_ctxt, ps_motion_pred, i4_curr_mot_stride,
2922                                                    i4_part_size, &ai4_sub_mb_mode[0], ps_mb_params,
2923                                                    ps_part, pu1_col_info);
2924                 }
2925             } /* end of mode derivation */
2926             else
2927             {
2928                 isvcd_populate_ref_idx(ps_mb_params, ps_svc_mb_params, ps_motion_pred,
2929                                        ps_mb_part_info, i4_listx);
2930 
2931             } /* non 16x16 mv mode derivation */
2932         }
2933     }
2934     return i4_mb_mode;
2935 }
2936 
2937 /*****************************************************************************/
2938 /*                                                                           */
2939 /*  Function Name : isvcd_compute_scaled_offsets                              */
2940 /*                                                                           */
2941 /*  Description   : this module does the projection of the current layer     */
2942 /*                   points (x,0) and (0,y) on to the reference layer and    */
2943 /*                   gets the 1/16 sample of the reference location          */
2944 /*                   x ranges from 0 - frame width                           */
2945 /*                   y ranges from 0 - frame height                          */
2946 /*                   this projection is done for LUMA only                   */
2947 /*  Inputs        :  ps_curr_lyr_slice_prms: pointer to current layer slice  */
2948 /*                                           parameters                      */
2949 /*                   ps_ref_lyr_slice_prms: pointer to ref layer slice prms  */
2950 /*                   pi2_offset_x         : pointer to store x projected     */
2951 /*                   pi2_offset_y         : pointer to store y projected     */
2952 /*  Globals       :  none                                                    */
2953 /*  Processing    :  it store the projected values for those points in the   */
2954 /*                   crop window                                             */
2955 /*  Outputs       :  projected locations                                     */
2956 /*  Returns       :  none                                                    */
2957 /*                                                                           */
2958 /*  Issues        : assumes that outside crop window no projection           */
2959 /*                                                                           */
2960 /*  Revision History:                                                        */
2961 /*                                                                           */
2962 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
2963 /*         06 09 2021   vijayakumar          creation                        */
2964 /*                                                                           */
2965 /*****************************************************************************/
isvcd_compute_scaled_offsets(res_prms_t * ps_curr_res_prms,res_prms_t * ps_ref_res_prms,WORD16 * pi2_offset_x,WORD16 * pi2_offset_y,UWORD8 u1_level_idc)2966 WORD32 isvcd_compute_scaled_offsets(res_prms_t *ps_curr_res_prms, res_prms_t *ps_ref_res_prms,
2967                                     WORD16 *pi2_offset_x, WORD16 *pi2_offset_y, UWORD8 u1_level_idc)
2968 {
2969     WORD32 i4_offset_x, i4_offset_y;
2970     UWORD32 i4_scaled_ref_lyr_width;
2971     UWORD32 i4_scaled_ref_lyr_height;
2972     UWORD32 i4_ref_lyr_width;
2973     UWORD32 i4_ref_lyr_height;
2974     UWORD32 i4_shift_x, i4_shift_y;
2975     UWORD32 i4_scale_x, i4_scale_y;
2976     WORD32 i4_cntr;
2977     WORD32 i4_scale_add_x, i4_scale_add_y;
2978     WORD32 i4_curr_lyr_width, i4_curr_lyr_height;
2979 
2980     if((NULL == ps_curr_res_prms) || (NULL == ps_ref_res_prms) || (NULL == pi2_offset_x) ||
2981        (NULL == pi2_offset_y))
2982     {
2983         return NOT_OK;
2984     }
2985     /* initial calculation */
2986     i4_offset_x = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_left;
2987     i4_offset_y = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_top;
2988 
2989     /* get the width and height */
2990     i4_scaled_ref_lyr_width = ps_curr_res_prms->u2_scaled_ref_width;
2991     i4_scaled_ref_lyr_height = ps_curr_res_prms->u2_scaled_ref_height;
2992     i4_ref_lyr_width = ps_ref_res_prms->i4_res_width;
2993     i4_ref_lyr_height = ps_ref_res_prms->i4_res_height;
2994     i4_curr_lyr_width = ps_curr_res_prms->i4_res_width;
2995     i4_curr_lyr_height = ps_curr_res_prms->i4_res_height;
2996 
2997     /* derive shift x and y based on level idd */
2998     if(u1_level_idc <= 30)
2999     {
3000         i4_shift_x = 16;
3001         i4_shift_y = 16;
3002     }
3003     else
3004     {
3005         i4_shift_x = 31 - isvcd_get_ceil_log2(i4_ref_lyr_width);
3006         i4_shift_y = 31 - isvcd_get_ceil_log2(i4_ref_lyr_height);
3007     }
3008 
3009     /* assert on max ranges of width and shift values */
3010     if((i4_ref_lyr_width > H264_MAX_FRAME_WIDTH) ||
3011        (i4_scaled_ref_lyr_width > H264_MAX_FRAME_WIDTH) ||
3012        (i4_ref_lyr_height > H264_MAX_FRAME_HEIGHT) ||
3013        (i4_scaled_ref_lyr_height > H264_MAX_FRAME_HEIGHT) ||
3014        (i4_curr_lyr_width > H264_MAX_FRAME_WIDTH) || (i4_curr_lyr_height > H264_MAX_FRAME_HEIGHT))
3015     {
3016         return NOT_OK;
3017     }
3018 
3019     /* calculate scale factor x and y */
3020     i4_scale_x = (((UWORD32) i4_ref_lyr_width << i4_shift_x) + (i4_scaled_ref_lyr_width >> 1)) /
3021                  i4_scaled_ref_lyr_width;
3022 
3023     i4_scale_y = (((UWORD32) i4_ref_lyr_height << i4_shift_y) + (i4_scaled_ref_lyr_height >> 1)) /
3024                  i4_scaled_ref_lyr_height;
3025 
3026     /* calcualte the values to be added based on left and top offset */
3027     i4_scale_add_x = (1 << (i4_shift_x - 1)) - (i4_offset_x * (WORD32) i4_scale_x);
3028     i4_scale_add_y = (1 << (i4_shift_y - 1)) - (i4_offset_y * (WORD32) i4_scale_y);
3029 
3030     /* derive the projected locations in the reference layer */
3031     for(i4_cntr = 0; i4_cntr < i4_curr_lyr_width; i4_cntr++)
3032     {
3033         WORD32 i4_ref_x;
3034         i4_ref_x = (i4_cntr * i4_scale_x + i4_scale_add_x) >> i4_shift_x;
3035         *pi2_offset_x++ = (WORD16) i4_ref_x;
3036     }
3037 
3038     /* derive the projected locations in the reference layer */
3039     for(i4_cntr = 0; i4_cntr < i4_curr_lyr_height; i4_cntr++)
3040     {
3041         WORD32 i4_ref_y;
3042         i4_ref_y = (i4_cntr * i4_scale_y + i4_scale_add_y) >> i4_shift_y;
3043         *pi2_offset_y++ = (WORD16) i4_ref_y;
3044     }
3045     return OK;
3046 }
3047 
3048 /*****************************************************************************/
3049 /*                                                                           */
3050 /*  Function Name : isvcd_comp_mode_mv_res_init                               */
3051 /*                                                                           */
3052 /*  Description   : this function calculates the scale factors and initialise*/
3053 /*                  the context structure                                    */
3054 /*                                                                           */
3055 /*  Inputs        : pv_comp_mode_mv_ctxt: handle to private structure        */
3056 /*                  ps_curr_lyr_res_prms: pointer to current resolution      */
3057 /*                                               params                      */
3058 /*                  pi2_ref_loc_x             : pointer to buffer having the */
3059 /*                                              projected locations horz     */
3060 /*                  pi2_ref_loc_y             : pointer to buffer having the */
3061 /*                                              projected location vertical  */
3062 /*  Globals       : none                                                     */
3063 /*  Processing    : it calculates the scale factors and stores it            */
3064 /*                                                                           */
3065 /*  Outputs       : none                                                     */
3066 /*  Returns       : none                                                     */
3067 /*                                                                           */
3068 /*  Issues        : none                                                     */
3069 /*                                                                           */
3070 /*  Revision History:                                                        */
3071 /*                                                                           */
3072 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
3073 /*         06 09 2021   vijayakumar          creation                        */
3074 /*                                                                           */
3075 /*****************************************************************************/
isvcd_comp_mode_mv_res_init(void * pv_svc_dec)3076 WORD32 isvcd_comp_mode_mv_res_init(void *pv_svc_dec)
3077 {
3078     /*! Flow of the module is as follows                                   */
3079     /*! 1. calculates the scale factors for dyadic cases                   */
3080     /*! 2. calculaets the loop counts and part width and height based on
3081            dyadic scale factor                                             */
3082     /*! 2. calculate the MV scale factors                                  */
3083     /*! 3. initialises the default mv ped structure with deafult values    */
3084 
3085     mode_motion_ctxt_t *ps_ctxt;
3086     mode_motion_lyr_ctxt *ps_lyr_mem;
3087     dec_seq_params_t *ps_sps;
3088     svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
3089     dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
3090     svc_dec_lyr_struct_t *ps_svc_dec_ref_layer;
3091     WORD32 ret;
3092     WORD32 i4_scaled_ref_lyr_width;
3093     WORD32 i4_scaled_ref_lyr_height;
3094     WORD32 i4_ref_lyr_width;
3095     WORD32 i4_ref_lyr_height;
3096     res_prms_t *ps_curr_lyr_res_prms = &ps_svc_lyr_dec->s_res_prms;
3097 
3098     ps_svc_dec_ref_layer = ps_svc_lyr_dec->ps_dec_svc_ref_layer;
3099     if(NULL == ps_curr_lyr_res_prms)
3100     {
3101         return NOT_OK;
3102     }
3103 
3104     ps_ctxt = (mode_motion_ctxt_t *) ps_svc_lyr_dec->pv_mode_mv_sample_ctxt;
3105     ps_ctxt->u1_direct_8x8_inference_flag = ps_curr_lyr_res_prms->u1_direct_8x8_inference_flag;
3106 
3107     /* if called for base resolution store deafult values */
3108     if(SVCD_TRUE == ps_svc_lyr_dec->u1_base_res_flag)
3109     {
3110         ps_ctxt->i4_res_id = -1;
3111         ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
3112         ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
3113         return OK;
3114     }
3115 
3116     /* call the function which populates the projected ref locations */
3117     ps_sps = ps_dec->ps_cur_sps;
3118 
3119     /* store the res id appropriately */
3120     ps_ctxt->i4_res_id = ps_svc_lyr_dec->u1_layer_id - 1;
3121 
3122     /* get the current layer ctxt */
3123     ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
3124 
3125     /* store the current and reference res params to the context */
3126     ps_lyr_mem->ps_curr_lyr_res_prms = ps_curr_lyr_res_prms;
3127 
3128     /* store the reference layer mv bank pointer */
3129     ps_lyr_mem->pv_ref_mv_bank_l0 = ps_svc_dec_ref_layer->s_dec.s_cur_pic.ps_mv;
3130 
3131     /* store the reference layer mb mode pointer */
3132     ps_lyr_mem->s_ref_mb_mode.pv_buffer = ps_svc_dec_ref_layer->ps_inter_lyr_mb_prms_frm_start;
3133     ps_lyr_mem->s_ref_mb_mode.i4_num_element_stride =
3134         ps_svc_dec_ref_layer->u2_inter_lyr_mb_prms_stride;
3135     ps_lyr_mem->s_ref_mb_mode.i4_element_size = sizeof(inter_lyr_mb_prms_t);
3136 
3137     /* check for recomputation of mapping required */
3138     if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_remap_req_flag)
3139     {
3140         res_prms_t s_ref_res_prms = {0};
3141 
3142         /* store the reference layer resolution width and height */
3143         s_ref_res_prms.i4_res_width = ps_ctxt->i4_ref_width;
3144         s_ref_res_prms.i4_res_height = ps_ctxt->i4_ref_height;
3145 
3146         /* call projection map calculation function */
3147         ret = isvcd_compute_scaled_offsets(ps_curr_lyr_res_prms, &s_ref_res_prms,
3148                                            ps_lyr_mem->pi2_ref_loc_x, ps_lyr_mem->pi2_ref_loc_y,
3149                                            ps_sps->u1_level_idc);
3150         if(OK != ret)
3151         {
3152             return NOT_OK;
3153         }
3154 
3155         /* derive the scaling variables */
3156         ps_lyr_mem->i4_offset_x = ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left;
3157 
3158         ps_lyr_mem->i4_offset_y = ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top;
3159 
3160         /* get the width and heights */
3161         i4_scaled_ref_lyr_width = ps_curr_lyr_res_prms->u2_scaled_ref_width;
3162         i4_scaled_ref_lyr_height = ps_curr_lyr_res_prms->u2_scaled_ref_height;
3163         i4_ref_lyr_width = ps_ctxt->i4_ref_width;
3164         i4_ref_lyr_height = ps_ctxt->i4_ref_height;
3165 
3166         /*store the reference layer width adn height */
3167         ps_lyr_mem->i4_ref_width = ps_ctxt->i4_ref_width;
3168         ps_lyr_mem->i4_ref_height = ps_ctxt->i4_ref_height;
3169 
3170         if((i4_ref_lyr_width > H264_MAX_FRAME_WIDTH) || (i4_ref_lyr_width <= 0)) return NOT_OK;
3171         if((i4_scaled_ref_lyr_width > H264_MAX_FRAME_WIDTH) || (i4_scaled_ref_lyr_width <= 0))
3172             return NOT_OK;
3173         if((i4_ref_lyr_height > H264_MAX_FRAME_HEIGHT) || (i4_ref_lyr_height <= 0)) return NOT_OK;
3174         if((i4_scaled_ref_lyr_height > H264_MAX_FRAME_HEIGHT) || (i4_scaled_ref_lyr_height <= 0))
3175             return NOT_OK;
3176 
3177         /* derivation of variables for dyadic cases cropping should be MB aligned */
3178         /* default values for flags */
3179         ps_lyr_mem->pf_inter_lyr_pred = &isvcd_compute_interlyr_motion_mode;
3180 
3181         if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_dyadic_flag)
3182         {
3183             ps_lyr_mem->pf_inter_lyr_pred = &isvcd_interlyr_motion_mode_pred_dyadic;
3184         }
3185 
3186         /* Store the Dyadic flag */
3187         ps_lyr_mem->i4_dyadic_flag = ps_curr_lyr_res_prms->u1_dyadic_flag;
3188 
3189         /* derive the scaling factors for motion upscaling */
3190         /* this is derived assuming no crop change flag is present */
3191         ps_lyr_mem->i4_scale_mv_x =
3192             ((i4_scaled_ref_lyr_width << 16) + (i4_ref_lyr_width >> 1)) / i4_ref_lyr_width;
3193 
3194         ps_lyr_mem->i4_scale_mv_y =
3195             ((i4_scaled_ref_lyr_height << 16) + (i4_ref_lyr_height >> 1)) / i4_ref_lyr_height;
3196     }
3197     else
3198     {
3199         /* should take false value */
3200         if(SVCD_FALSE != ps_curr_lyr_res_prms->u1_remap_req_flag)
3201         {
3202             return NOT_OK;
3203         }
3204     }
3205 
3206     /* store the current layer width and height to context */
3207     ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
3208     ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
3209 
3210     return OK;
3211 }
3212