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 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