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