1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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 /**
19 *******************************************************************************
20 * @file
21 * ihevcd_get_mv.c
22 *
23 * @brief
24 * Contains functions to compute motion vectors
25 *
26 * @author
27 * Ittiam
28 *
29 * @par List of Functions:
30 * - ihevcd_get_mv_ctb()
31 *
32 * @remarks
33 * None
34 *
35 *******************************************************************************
36 */
37 /*****************************************************************************/
38 /* File Includes */
39 /*****************************************************************************/
40
41 #include <stdio.h>
42 #include <stddef.h>
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include "ihevc_typedefs.h"
47 #include "iv.h"
48 #include "ivd.h"
49 #include "ihevcd_cxa.h"
50 #include "ithread.h"
51
52 #include "ihevc_defs.h"
53 #include "ihevc_debug.h"
54 #include "ihevc_structs.h"
55 #include "ihevc_macros.h"
56 #include "ihevc_platform_macros.h"
57 #include "ihevc_cabac_tables.h"
58 #include "ihevc_disp_mgr.h"
59 #include "ihevc_buf_mgr.h"
60 #include "ihevc_dpb_mgr.h"
61
62 #include "ihevcd_defs.h"
63 #include "ihevcd_function_selector.h"
64 #include "ihevcd_structs.h"
65 #include "ihevcd_error.h"
66 #include "ihevcd_nal.h"
67 #include "ihevcd_bitstream.h"
68 #include "ihevcd_fmt_conv.h"
69 #include "ihevcd_job_queue.h"
70 #include "ihevcd_debug.h"
71 #include "ihevcd_mv_merge.h"
72 #include "ihevcd_mv_pred.h"
73 #include "ihevcd_profile.h"
74 /**
75 *******************************************************************************
76 *
77 * @brief
78 * This function computes and stores MV's of all the PU's in CTB
79 *
80 * @par Description:
81 * MV's of a PU will be stored in PU structure. MV computation can be merge or mv pred
82 *
83 * @param[in] ps_proc
84 * processor context
85 *
86 * @param[in] pi4_ctb_top_pu_idx
87 * Pointer to ctb top PU indices
88 *
89 * @param[in] pi4_ctb_left_pu_idx
90 * Pointer to ctb left PU indices
91 *
92 * @param[in] pi4_ctb_top_left_pu_idx
93 * Pointer to ctb top left PU indices
94 *
95 * @returns
96 * number of PU's per ctb
97 *
98 * @remarks
99 *
100 *
101 *******************************************************************************
102 */
103
ihevcd_get_mv_ctb(mv_ctxt_t * ps_mv_ctxt,UWORD32 * pu4_ctb_top_pu_idx,UWORD32 * pu4_ctb_left_pu_idx,UWORD32 * pu4_ctb_top_left_pu_idx)104 WORD32 ihevcd_get_mv_ctb(mv_ctxt_t *ps_mv_ctxt,
105 UWORD32 *pu4_ctb_top_pu_idx,
106 UWORD32 *pu4_ctb_left_pu_idx,
107 UWORD32 *pu4_ctb_top_left_pu_idx)
108 {
109
110 WORD32 i;
111 sps_t *ps_sps;
112 pps_t *ps_pps;
113 pu_t *ps_pu;
114 tile_t *ps_tile;
115 UWORD8 *pu1_pic_pu_map_ctb;
116 WORD32 num_minpu_in_ctb;
117 WORD32 ctb_start_pu_idx;
118 UWORD32 *pu4_top_pu_idx, *pu4_left_pu_idx, *pu4_top_left_pu_idx;
119 WORD32 pu_x_in_4x4, pu_y_in_4x4;
120 WORD32 pu_x_in_4x4_single_mcl, pu_y_in_4x4_single_mcl;
121 pu_mv_t s_pred_mv;
122 WORD32 ctb_size, ctb_size_in_min_pu;
123 WORD32 num_pu_per_ctb, pu_wd, pu_ht, pu_cnt;
124 WORD32 pu_wd_single_mcl, pu_ht_single_mcl;
125 UWORD32 au4_nbr_avail[MAX_CTB_SIZE / MIN_PU_SIZE
126 + 2 /* Top nbr + bot nbr */];
127 UWORD32 *pu4_nbr_pu_idx/* (Left + ctb_size + right ) * (top + ctb_size + bottom) */;
128 WORD32 top_avail_bits;
129 UWORD8 u1_lb_avail, u1_l_avail, u1_t_avail, u1_tr_avail, u1_tl_avail;
130 WORD32 nbr_pu_idx_strd;
131 WORD32 cb_size;
132 WORD32 single_mcl_flag;
133
134 PROFILE_DISABLE_MV_PREDICTION();
135 ps_sps = ps_mv_ctxt->ps_sps;
136 ps_pps = ps_mv_ctxt->ps_pps;
137 ps_pu = ps_mv_ctxt->ps_pu;
138 ps_tile = ps_mv_ctxt->ps_tile;
139
140 pu4_nbr_pu_idx = ps_mv_ctxt->pu4_pic_pu_idx_map;
141
142 ctb_size = (1 << ps_sps->i1_log2_ctb_size);
143
144 ctb_size_in_min_pu = (ctb_size / MIN_PU_SIZE);
145
146 num_minpu_in_ctb = ctb_size_in_min_pu * ctb_size_in_min_pu;
147 pu1_pic_pu_map_ctb = ps_mv_ctxt->pu1_pic_pu_map + (ps_mv_ctxt->i4_ctb_x + ps_mv_ctxt->i4_ctb_y * ps_sps->i2_pic_wd_in_ctb) * num_minpu_in_ctb;
148
149 num_pu_per_ctb = ps_mv_ctxt->i4_ctb_pu_cnt;
150 ctb_start_pu_idx = ps_mv_ctxt->i4_ctb_start_pu_idx;
151 nbr_pu_idx_strd = MAX_CTB_SIZE / MIN_PU_SIZE + 2;
152
153 {
154 /* Updating the initial availability map */
155 WORD32 i;
156 UWORD32 u4_left_ctb_avail, u4_top_lt_ctb_avail, u4_top_rt_ctb_avail,
157 u4_top_ctb_avail;
158
159 u4_left_ctb_avail = ps_mv_ctxt->u1_left_ctb_avail;
160 u4_top_lt_ctb_avail = ps_mv_ctxt->u1_top_lt_ctb_avail;
161 u4_top_ctb_avail = ps_mv_ctxt->u1_top_ctb_avail;
162 u4_top_rt_ctb_avail = ps_mv_ctxt->u1_top_rt_ctb_avail;
163
164 /* Initializing the availability array */
165 memset(au4_nbr_avail, 0,
166 (MAX_CTB_SIZE / MIN_PU_SIZE + 2) * sizeof(UWORD32));
167 /* Initializing the availability array with CTB level availability flags */
168 {
169 WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples
170 - (ps_mv_ctxt->i4_ctb_y << ps_sps->i1_log2_ctb_size);
171 WORD32 ctb_size_left = MIN(ctb_size, rows_remaining);
172 for(i = 0; i < ctb_size_left / MIN_PU_SIZE; i++)
173 {
174 au4_nbr_avail[i + 1] = (u4_left_ctb_avail << 31);
175 }
176 }
177 au4_nbr_avail[0] |= ((u4_top_rt_ctb_avail << 31)
178 >> (1 + ctb_size_in_min_pu)); /* 1+ctb_size/4 position bit pos from msb */
179
180 au4_nbr_avail[0] |= (u4_top_lt_ctb_avail << 31);
181 {
182 WORD32 cols_remaining = ps_sps->i2_pic_width_in_luma_samples
183 - (ps_mv_ctxt->i4_ctb_x << ps_sps->i1_log2_ctb_size);
184 WORD32 ctb_size_top = MIN(ctb_size, cols_remaining);
185 WORD32 shift = (31 - (ctb_size / MIN_TU_SIZE));
186
187 /* ctb_size_top gives number of valid pixels remaining in the current row */
188 /* Since we need pattern of 1's starting from the MSB, an additional shift */
189 /* is needed */
190 shift += ((ctb_size - ctb_size_top) / MIN_TU_SIZE);
191
192 top_avail_bits = ((1 << (ctb_size_top / MIN_PU_SIZE)) - 1) << shift;
193 }
194
195 au4_nbr_avail[0] |= ((u4_top_ctb_avail == 1) ? top_avail_bits : 0x0);
196 /* Starting from msb 2nd bit to (1+ctb_size/4) bit, set 1 if top avail,or 0 */
197
198 }
199
200 {
201 /* In case of a tile boundary, left and top arrays must change*/
202 /*Left*/
203 /* If start of tile row*/
204 if(((ps_tile->u1_pos_x) == (ps_mv_ctxt->i4_ctb_x)) && (ps_mv_ctxt->i4_ctb_x != 0))
205 {
206 WORD32 index_pic_map;
207 WORD32 ctb_pu_idx;
208 UWORD8 *pu1_pic_pu_map;
209
210 /* Goto the left ctb which belongs to another tile */
211 index_pic_map = ((ps_mv_ctxt->i4_ctb_x - 1) + ps_mv_ctxt->i4_ctb_y * ps_sps->i2_pic_wd_in_ctb);
212 ctb_pu_idx = ps_mv_ctxt->pu4_pic_pu_idx[index_pic_map];
213 index_pic_map *= num_minpu_in_ctb;
214
215 /*Replicate the PUs of the last column of the left ctb*/
216 pu1_pic_pu_map = ps_mv_ctxt->pu1_pic_pu_map + index_pic_map + ctb_size_in_min_pu - 1;
217 for(i = 0; i < ctb_size_in_min_pu; i++)
218 {
219 /* Left neighbors change*/
220 pu4_ctb_left_pu_idx[i] = ctb_pu_idx + (WORD32)*pu1_pic_pu_map;
221 pu1_pic_pu_map = pu1_pic_pu_map + ctb_size_in_min_pu;
222 }
223
224
225 index_pic_map = ((ps_mv_ctxt->i4_ctb_x - 1) + (ps_mv_ctxt->i4_ctb_y - 1) * ps_sps->i2_pic_wd_in_ctb);
226 ctb_pu_idx = ps_mv_ctxt->pu4_pic_pu_idx[index_pic_map];
227 index_pic_map *= num_minpu_in_ctb;
228 index_pic_map += (num_minpu_in_ctb - 1);
229 pu4_ctb_top_left_pu_idx[0] = ctb_pu_idx + pu1_pic_pu_map[index_pic_map];
230 }
231 /*Top*/
232 /* If start of tile column*/
233 if(((ps_tile->u1_pos_y) == (ps_mv_ctxt->i4_ctb_y)) && (ps_mv_ctxt->i4_ctb_y != 0))
234 {
235 WORD32 index_pic_map;
236 WORD32 ctb_pu_idx;
237 UWORD8 *pu1_pic_pu_map;
238
239 /* Goto the top ctb which belongs to another tile */
240 index_pic_map = (ps_mv_ctxt->i4_ctb_x) + ((ps_mv_ctxt->i4_ctb_y - 1) * ps_sps->i2_pic_wd_in_ctb);
241 ctb_pu_idx = ps_mv_ctxt->pu4_pic_pu_idx[index_pic_map];
242 index_pic_map *= num_minpu_in_ctb;
243
244 /*Replicate the PUs of the last row of the top ctb*/
245 pu1_pic_pu_map = ps_mv_ctxt->pu1_pic_pu_map + index_pic_map + (ctb_size_in_min_pu * (ctb_size_in_min_pu - 1));
246 for(i = 0; i < ctb_size_in_min_pu; i++)
247 {
248 /* Top neighbors change*/
249 pu4_ctb_top_pu_idx[i] = ctb_pu_idx + (WORD32)*pu1_pic_pu_map;
250 pu1_pic_pu_map++;
251 }
252 }
253
254 /* Updating the initial neighbor pu idx map */
255 /* Initializing the availability array with CTB level availability flags */
256 /* 16x16 array for holding pu info of the ctb, wrt the frame pu count*/
257 for(i = 0; i < ctb_size_in_min_pu; i++)
258 {
259 /* Left */
260 pu4_nbr_pu_idx[(i + 1) * nbr_pu_idx_strd] = pu4_ctb_left_pu_idx[i];
261 /* Top */
262 pu4_nbr_pu_idx[i + 1] = pu4_ctb_top_pu_idx[i];
263 }
264 /* Top right */
265 pu4_nbr_pu_idx[1 + ctb_size_in_min_pu] = pu4_ctb_top_pu_idx[ctb_size_in_min_pu];
266
267 /* Top left */
268 pu4_nbr_pu_idx[0] = pu4_ctb_top_left_pu_idx[0];
269
270 }
271
272 /* CTB level MV pred */
273 for(pu_cnt = 0; pu_cnt < num_pu_per_ctb; pu_cnt++, ps_pu++)
274 {
275 pu_ht = (ps_pu->b4_ht + 1) << 2;
276 pu_wd = (ps_pu->b4_wd + 1) << 2;
277
278 pu_ht_single_mcl = pu_ht;
279 pu_wd_single_mcl = pu_wd;
280
281 pu_x_in_4x4 = ps_pu->b4_pos_x;
282 pu_y_in_4x4 = ps_pu->b4_pos_y;
283
284 pu_x_in_4x4_single_mcl = pu_x_in_4x4;
285 pu_y_in_4x4_single_mcl = pu_y_in_4x4;
286
287 /*******************************************/
288 /* Neighbor location: Graphical indication */
289 /* */
290 /* B2 _____________B1 B0 */
291 /* | | */
292 /* | | */
293 /* | | */
294 /* | PU ht| */
295 /* | | */
296 /* | | */
297 /* A1|______wd_______| */
298 /* A0 */
299 /* */
300 /*******************************************/
301 /* Below code is for merge mode, where if single_mcl_flag == 1,
302 * all the prediction units of the current coding unit share a
303 * single merge candidate list, which is identical to the
304 * merge candidate list of the 2Nx2N prediction unit.
305 */
306 single_mcl_flag = 0;
307 if(1 == ps_pu->b1_merge_flag)
308 {
309 cb_size = MAX(pu_wd_single_mcl, pu_ht_single_mcl);
310 cb_size = MAX(cb_size,
311 (1 << ps_sps->i1_log2_min_coding_block_size));
312 if((ps_pps->i1_log2_parallel_merge_level > 2) && cb_size == 8 && (pu_wd_single_mcl != pu_ht_single_mcl))
313 {
314 single_mcl_flag = 1;
315 if((PART_Nx2N == ps_pu->b3_part_mode) && (1 == ps_pu->b2_part_idx))
316 {
317 pu_x_in_4x4_single_mcl = pu_x_in_4x4_single_mcl - 1;
318 }
319 else if((PART_2NxN == ps_pu->b3_part_mode) && (1 == ps_pu->b2_part_idx))
320 {
321 pu_y_in_4x4_single_mcl = pu_y_in_4x4_single_mcl - 1;
322 }
323 pu_ht_single_mcl = 8;
324 pu_wd_single_mcl = 8;
325 }
326 }
327 pu4_top_pu_idx = &pu4_nbr_pu_idx[(1 + pu_x_in_4x4_single_mcl)
328 + (1 + pu_y_in_4x4_single_mcl - 1) * nbr_pu_idx_strd];
329 pu4_top_left_pu_idx = pu4_top_pu_idx - 1;
330 pu4_left_pu_idx = pu4_top_pu_idx - 1 + nbr_pu_idx_strd;
331
332 /* Get neibhbor availability */
333 {
334 u1_lb_avail = (au4_nbr_avail[1 + pu_y_in_4x4_single_mcl + pu_ht_single_mcl / MIN_PU_SIZE]
335 >> (31 - (1 + pu_x_in_4x4_single_mcl - 1))) & 1;
336 u1_l_avail = (au4_nbr_avail[1 + pu_y_in_4x4_single_mcl]
337 >> (31 - (1 + pu_x_in_4x4_single_mcl - 1))) & 1;
338 u1_t_avail = (au4_nbr_avail[1 + pu_y_in_4x4_single_mcl - 1]
339 >> (31 - (1 + pu_x_in_4x4_single_mcl))) & 1;
340 u1_tr_avail = (au4_nbr_avail[1 + pu_y_in_4x4_single_mcl - 1]
341 >> (31 - (1 + pu_x_in_4x4_single_mcl + pu_wd_single_mcl / MIN_PU_SIZE)))
342 & 1;
343 u1_tl_avail = (au4_nbr_avail[1 + pu_y_in_4x4_single_mcl - 1]
344 >> (31 - (1 + pu_x_in_4x4_single_mcl - 1))) & 1;
345 }
346 if(ps_pu->b1_intra_flag == 0)
347 {
348 if(ps_pu->b1_merge_flag == 0)
349 {
350 WORD32 pred_flag_l0, pred_flag_l1;
351 WORD32 tmp_x, tmp_y, mvd_x, mvd_y, mvp_x, mvp_y;
352 WORD32 two_pow_16, two_pow_15;
353
354 ihevcd_mv_pred(ps_mv_ctxt, pu4_top_pu_idx, pu4_left_pu_idx,
355 pu4_top_left_pu_idx, nbr_pu_idx_strd,
356 ps_pu, u1_lb_avail, u1_l_avail,
357 u1_tr_avail, u1_t_avail, u1_tl_avail,
358 &s_pred_mv);
359
360 pred_flag_l0 = (ps_pu->b2_pred_mode != PRED_L1);
361 pred_flag_l1 = (ps_pu->b2_pred_mode != PRED_L0);
362
363 two_pow_16 = (1 << 16);
364 two_pow_15 = (1 << 15);
365
366 /* L0 MV */
367 if(pred_flag_l0)
368 {
369 mvp_x = s_pred_mv.s_l0_mv.i2_mvx;
370 mvp_y = s_pred_mv.s_l0_mv.i2_mvy;
371 mvd_x = ps_pu->mv.s_l0_mv.i2_mvx;
372 mvd_y = ps_pu->mv.s_l0_mv.i2_mvy;
373
374 tmp_x = (mvp_x + mvd_x + two_pow_16) & (two_pow_16 - 1);
375 tmp_x = tmp_x >= two_pow_15 ?
376 (tmp_x - two_pow_16) : tmp_x;
377 ps_pu->mv.s_l0_mv.i2_mvx = tmp_x;
378 tmp_y = (mvp_y + mvd_y + two_pow_16) & (two_pow_16 - 1);
379 tmp_y = tmp_y >= two_pow_15 ?
380 (tmp_y - two_pow_16) : tmp_y;
381 ps_pu->mv.s_l0_mv.i2_mvy = tmp_y;
382 }
383 /* L1 MV */
384 if(pred_flag_l1)
385 {
386 mvp_x = s_pred_mv.s_l1_mv.i2_mvx;
387 mvp_y = s_pred_mv.s_l1_mv.i2_mvy;
388 mvd_x = ps_pu->mv.s_l1_mv.i2_mvx;
389 mvd_y = ps_pu->mv.s_l1_mv.i2_mvy;
390
391 tmp_x = (mvp_x + mvd_x + two_pow_16) & (two_pow_16 - 1);
392 tmp_x = tmp_x >= two_pow_15 ?
393 (tmp_x - two_pow_16) : tmp_x;
394 ps_pu->mv.s_l1_mv.i2_mvx = tmp_x;
395 tmp_y = (mvp_y + mvd_y + two_pow_16) & (two_pow_16 - 1);
396 tmp_y = tmp_y >= two_pow_15 ?
397 (tmp_y - two_pow_16) : tmp_y;
398 ps_pu->mv.s_l1_mv.i2_mvy = tmp_y;
399 }
400 }
401 else
402 {
403 WORD32 part_mode;
404 WORD32 part_idx;
405 part_mode = ps_pu->b3_part_mode;
406 //TODO: Get part_idx
407 part_idx = ps_pu->b2_part_idx;
408
409 ihevcd_mv_merge(ps_mv_ctxt, pu4_top_pu_idx, pu4_left_pu_idx,
410 nbr_pu_idx_strd, ps_pu, part_mode,
411 part_idx, pu_wd_single_mcl, pu_ht_single_mcl,
412 pu_x_in_4x4_single_mcl << 2, pu_y_in_4x4_single_mcl << 2,
413 single_mcl_flag, u1_lb_avail, u1_l_avail, u1_tr_avail,
414 u1_t_avail, u1_tl_avail);
415
416 if(PRED_BI == ps_pu->b2_pred_mode)
417 {
418 if(((ps_pu->b3_part_mode == PART_2NxN) && (pu_wd == 8))
419 || ((ps_pu->b3_part_mode == PART_Nx2N)
420 && (pu_ht == 8)))
421 {
422 ps_pu->b2_pred_mode = PRED_L0;
423 }
424 }
425 }
426 }
427
428 {
429 slice_header_t *ps_slice_hdr;
430 pic_buf_t *ps_pic_buf_l0, *ps_pic_buf_l1;
431 ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
432 ps_pic_buf_l0 = (pic_buf_t *)((ps_slice_hdr->as_ref_pic_list0[ps_pu->mv.i1_l0_ref_idx].pv_pic_buf));
433 ps_pic_buf_l1 = (pic_buf_t *)((ps_slice_hdr->as_ref_pic_list1[ps_pu->mv.i1_l1_ref_idx].pv_pic_buf));
434 ps_pu->mv.i1_l0_ref_pic_buf_id = ps_pic_buf_l0->u1_buf_id;
435 if(BSLICE == ps_slice_hdr->i1_slice_type)
436 {
437 ps_pu->mv.i1_l1_ref_pic_buf_id = ps_pic_buf_l1->u1_buf_id;
438 }
439 }
440
441 /* Neighbor availability inside CTB */
442 /* 1bit per 4x4. Indicates whether that 4x4 block has been reconstructed(avialable) */
443 /* Used for neighbor availability in intra pred */
444 {
445 WORD32 trans_in_min_tu;
446 UWORD32 cur_tu_in_bits;
447 UWORD32 cur_tu_avail_flag;
448
449 trans_in_min_tu = pu_wd / MIN_PU_SIZE;
450 cur_tu_in_bits = (1 << trans_in_min_tu) - 1;
451 cur_tu_in_bits = cur_tu_in_bits << (32 - trans_in_min_tu);
452
453 cur_tu_avail_flag = cur_tu_in_bits >> (pu_x_in_4x4 + 1);
454
455 for(i = 0; i < pu_ht / MIN_PU_SIZE; i++)
456 au4_nbr_avail[1 + pu_y_in_4x4 + i] |= cur_tu_avail_flag;
457 }
458
459 /* Neighbor PU idx update inside CTB */
460 /* 1byte per 4x4. Indicates the PU idx that 4x4 block belongs to */
461
462 {
463 WORD32 row, col;
464 UWORD32 cur_pu_idx;
465 WORD32 offset;
466 cur_pu_idx = ctb_start_pu_idx + pu_cnt;
467
468 offset = (1 + pu_x_in_4x4 + 0) + (1 + pu_y_in_4x4 + 0) * nbr_pu_idx_strd;
469
470 for(row = 0; row < pu_ht / MIN_PU_SIZE; row++)
471 {
472 for(col = 0; col < pu_wd / MIN_PU_SIZE; col++)
473 {
474 pu4_nbr_pu_idx[offset + col] = cur_pu_idx;
475 }
476 offset += nbr_pu_idx_strd;
477 }
478 }
479
480 }
481
482 /* Updating Top and Left pointers */
483 {
484 WORD32 offset_top, offset_left;
485
486 offset_left = ctb_size_in_min_pu + (0 + 1) * nbr_pu_idx_strd;
487 offset_top = ctb_size_in_min_pu * nbr_pu_idx_strd + 0 + 1;
488
489 /* Top Left */
490 /* saving top left before updating top ptr, as updating top ptr will overwrite the top left for the next ctb */
491 pu4_ctb_top_left_pu_idx[0] = pu4_ctb_top_pu_idx[ctb_size_in_min_pu - 1];
492
493 for(i = 0; i < ctb_size_in_min_pu; i++)
494 {
495 /* Left */
496 /* Last column of au4_nbr_pu_idx */
497 pu4_ctb_left_pu_idx[i] = pu4_nbr_pu_idx[offset_left];
498 /* Top */
499 /* Last row of au4_nbr_pu_idx */
500 pu4_ctb_top_pu_idx[i] = pu4_nbr_pu_idx[offset_top];
501
502 offset_left += nbr_pu_idx_strd;
503 offset_top += 1;
504 }
505 }
506
507 /* Updating the CTB level PU idx (Used for collocated MV pred)*/
508 {
509 WORD32 ctb_row, ctb_col, index_pic_map, index_nbr_map;
510 WORD32 first_pu_of_ctb;
511 first_pu_of_ctb = pu4_nbr_pu_idx[1 + nbr_pu_idx_strd];
512
513 index_pic_map = 0 * ctb_size_in_min_pu + 0;
514 index_nbr_map = (0 + 1) * nbr_pu_idx_strd + (0 + 1);
515
516 for(ctb_row = 0; ctb_row < ctb_size_in_min_pu; ctb_row++)
517 {
518 for(ctb_col = 0; ctb_col < ctb_size_in_min_pu; ctb_col++)
519 {
520 pu1_pic_pu_map_ctb[index_pic_map + ctb_col] = pu4_nbr_pu_idx[index_nbr_map + ctb_col]
521 - first_pu_of_ctb;
522 }
523 index_pic_map += ctb_size_in_min_pu;
524 index_nbr_map += nbr_pu_idx_strd;
525 }
526 }
527 return num_pu_per_ctb;
528 }
529