1 /****************************************************************************** 2 * 3 * Copyright (C) 2015 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 ih264d_thread_parse_decode.c 23 * 24 * \brief 25 * Contains routines that for multi-thread decoder 26 * 27 * Detailed_description 28 * 29 * \date 30 * 20/02/2012 31 * 32 * \author ZR 33 ************************************************************************** 34 */ 35 36 #include "ih264d_error_handler.h" 37 #include "ih264d_debug.h" 38 #include "ithread.h" 39 #include <string.h> 40 #include "ih264d_defs.h" 41 #include "ih264d_debug.h" 42 #include "ih264d_tables.h" 43 #include "ih264d_structs.h" 44 #include "ih264d_defs.h" 45 #include "ih264d_mb_utils.h" 46 #include "ih264d_thread_parse_decode.h" 47 #include "ih264d_inter_pred.h" 48 49 #include "ih264d_process_pslice.h" 50 #include "ih264d_process_intra_mb.h" 51 #include "ih264d_deblocking.h" 52 #include "ih264d_format_conv.h" 53 54 void ih264d_deblock_mb_level(dec_struct_t *ps_dec, 55 dec_mb_info_t *ps_cur_mb_info, 56 UWORD32 nmb_index); 57 58 void ih264d_copy_intra_pred_line(dec_struct_t *ps_dec, 59 dec_mb_info_t *ps_cur_mb_info, 60 UWORD32 nmb_index); 61 62 void ih264d_parse_tfr_nmb(dec_struct_t * ps_dec, 63 UWORD8 u1_mb_idx, 64 UWORD8 u1_num_mbs, 65 UWORD8 u1_num_mbs_next, 66 UWORD8 u1_tfr_n_mb, 67 UWORD8 u1_end_of_row) 68 { 69 WORD32 i, u4_mb_num; 70 71 const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; 72 UWORD32 u4_n_mb_start; 73 74 UNUSED(u1_mb_idx); 75 UNUSED(u1_num_mbs_next); 76 if(u1_tfr_n_mb) 77 { 78 79 80 u4_n_mb_start = (ps_dec->u2_cur_mb_addr + 1) - u1_num_mbs; 81 82 // copy into s_frmMbInfo 83 84 u4_mb_num = u4_n_mb_start; 85 u4_mb_num = (ps_dec->u2_cur_mb_addr + 1) - u1_num_mbs; 86 87 for(i = 0; i < u1_num_mbs; i++) 88 { 89 UPDATE_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u4_mb_num, 90 ps_dec->u2_cur_slice_num); 91 DATA_SYNC(); 92 UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_dec_mb_map, u4_mb_num); 93 94 u4_mb_num++; 95 } 96 97 /****************************************************************/ 98 /* Check for End Of Row in Next iteration */ 99 /****************************************************************/ 100 101 /****************************************************************/ 102 /* Transfer the Following things */ 103 /* N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) */ 104 /* N-Mb Recon Data ( To Ext Frame Buffer ) */ 105 /* N-Mb Intrapredline Data ( Updated Internally) */ 106 /* N-Mb MV Data ( To Ext MV Buffer ) */ 107 /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) */ 108 /****************************************************************/ 109 110 /* Swap top and current pointers */ 111 112 ps_dec->s_tran_addrecon_parse.pu1_dest_y += 113 ps_dec->s_tran_addrecon_parse.u4_inc_y[u1_end_of_row]; 114 ps_dec->s_tran_addrecon_parse.pu1_dest_u += 115 ps_dec->s_tran_addrecon_parse.u4_inc_uv[u1_end_of_row]; 116 ps_dec->s_tran_addrecon_parse.pu1_dest_v += 117 ps_dec->s_tran_addrecon_parse.u4_inc_uv[u1_end_of_row]; 118 119 if(u1_end_of_row) 120 { 121 UWORD16 u2_mb_y; 122 UWORD32 u4_frame_stride, y_offset; 123 124 ps_dec->ps_top_mb_row = ps_dec->ps_cur_mb_row; 125 ps_dec->ps_cur_mb_row += ((ps_dec->u2_frm_wd_in_mbs) << u1_mbaff); 126 127 u2_mb_y = ps_dec->u2_mby + (1 + u1_mbaff); 128 u4_frame_stride = ps_dec->u2_frm_wd_y 129 << ps_dec->ps_cur_slice->u1_field_pic_flag; 130 y_offset = (u2_mb_y * u4_frame_stride) << 4; 131 ps_dec->s_tran_addrecon_parse.pu1_dest_y = 132 ps_dec->s_cur_pic.pu1_buf1 + y_offset; 133 134 u4_frame_stride = ps_dec->u2_frm_wd_uv 135 << ps_dec->ps_cur_slice->u1_field_pic_flag; 136 y_offset = (u2_mb_y * u4_frame_stride) << 3; 137 ps_dec->s_tran_addrecon_parse.pu1_dest_u = 138 ps_dec->s_cur_pic.pu1_buf2 + y_offset; 139 ps_dec->s_tran_addrecon_parse.pu1_dest_v = 140 ps_dec->s_cur_pic.pu1_buf3 + y_offset; 141 142 } 143 144 ps_dec->ps_deblk_mbn += u1_num_mbs; 145 146 /* 147 * The Slice boundary is also a valid condition to transfer. So recalculate 148 * the Left increment, in case the number of MBs is lesser than the 149 * N MB value. c_numMbs will be equal to N of N MB if the entire N Mb is 150 * decoded. 151 */ 152 ps_dec->s_tran_addrecon.u2_mv_left_inc = ((u1_num_mbs >> u1_mbaff) - 1) 153 << (4 + u1_mbaff); 154 ps_dec->s_tran_addrecon.u2_mv_top_left_inc = (u1_num_mbs << 2) - 1 155 - (u1_mbaff << 2); 156 157 /* reassign left MV and cur MV pointers */ 158 ps_dec->ps_mv_left = ps_dec->ps_mv_cur 159 + ps_dec->s_tran_addrecon.u2_mv_left_inc; 160 161 ps_dec->ps_mv_cur += (u1_num_mbs << 4); 162 ps_dec->u4_num_mbs_prev_nmb = u1_num_mbs; 163 164 } 165 } 166 167 void ih264d_decode_tfr_nmb(dec_struct_t * ps_dec, 168 UWORD8 u1_num_mbs, 169 UWORD8 u1_num_mbs_next, 170 UWORD8 u1_end_of_row) 171 { 172 173 UWORD32 u1_end_of_row_next; 174 175 const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; 176 177 /****************************************************************/ 178 /* Check for End Of Row in Next iteration */ 179 /****************************************************************/ 180 u1_end_of_row_next = u1_num_mbs_next && 181 ((u1_num_mbs_next) <= (ps_dec->u1_recon_mb_grp >> u1_mbaff)); 182 183 /****************************************************************/ 184 /* Transfer the Following things */ 185 /* N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) */ 186 /* N-Mb Recon Data ( To Ext Frame Buffer ) */ 187 /* N-Mb Intrapredline Data ( Updated Internally) */ 188 /* N-Mb MV Data ( To Ext MV Buffer ) */ 189 /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) */ 190 /****************************************************************/ 191 if(u1_end_of_row) 192 { 193 ps_dec->i2_dec_thread_mb_y += (1 << u1_mbaff); 194 } 195 ih264d_transfer_mb_group_data(ps_dec, u1_num_mbs, u1_end_of_row, 196 u1_end_of_row_next); 197 198 } 199 200 WORD32 ih264d_decode_recon_tfr_nmb_thread(dec_struct_t * ps_dec, 201 UWORD8 u1_num_mbs, 202 UWORD8 u1_num_mbs_next, 203 UWORD8 u1_end_of_row) 204 { 205 WORD32 i,j; 206 dec_mb_info_t * ps_cur_mb_info; 207 UWORD32 u4_update_mbaff = 0; 208 const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; 209 UWORD32 u1_slice_type, u1_B; 210 WORD32 u1_skip_th; 211 UWORD32 u1_ipcm_th; 212 UWORD32 u4_cond; 213 UWORD16 u2_slice_num,u2_cur_dec_mb_num; 214 WORD32 ret; 215 UWORD32 u4_mb_num; 216 WORD32 nop_cnt = 8*128; 217 u1_slice_type = ps_dec->ps_decode_cur_slice->slice_type; 218 219 u1_B = (u1_slice_type == B_SLICE); 220 221 u1_skip_th = ((u1_slice_type != I_SLICE) ? 222 (u1_B ? B_8x8 : PRED_8x8R0) : -1); 223 224 u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (u1_B ? 23 : 5) : 0); 225 226 u2_cur_dec_mb_num = ps_dec->cur_dec_mb_num; 227 228 while(1) 229 { 230 231 UWORD32 u4_max_mb = (UWORD32)(ps_dec->i2_dec_thread_mb_y + (1 << u1_mbaff)) * ps_dec->u2_frm_wd_in_mbs - 1; 232 u4_mb_num = u2_cur_dec_mb_num; 233 /*introducing 1 MB delay*/ 234 u4_mb_num = MIN(u4_mb_num + u1_num_mbs + 1, u4_max_mb); 235 236 CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond); 237 if(u4_cond) 238 { 239 break; 240 } 241 else 242 { 243 if(nop_cnt > 0) 244 { 245 nop_cnt -= 128; 246 NOP(128); 247 } 248 else 249 { 250 if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) && 251 (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht)) 252 { 253 ps_dec->u4_fmt_conv_num_rows = 254 MIN(FMT_CONV_NUM_ROWS, 255 (ps_dec->s_disp_frame_info.u4_y_ht 256 - ps_dec->u4_fmt_conv_cur_row)); 257 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), 258 ps_dec->u4_fmt_conv_cur_row, 259 ps_dec->u4_fmt_conv_num_rows); 260 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; 261 } 262 else 263 { 264 nop_cnt = 8*128; 265 ithread_yield(); 266 } 267 } 268 } 269 } 270 /* N Mb MC Loop */ 271 for(i = 0; i < u1_num_mbs; i++) 272 { 273 u4_mb_num = u2_cur_dec_mb_num; 274 275 GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u2_cur_dec_mb_num, 276 u2_slice_num); 277 278 if(u2_slice_num != ps_dec->u2_cur_slice_num_dec_thread) 279 { 280 ps_dec->u4_cur_slice_decode_done = 1; 281 break; 282 } 283 284 ps_cur_mb_info = &ps_dec->ps_frm_mb_info[u2_cur_dec_mb_num]; 285 286 ps_dec->u4_dma_buf_idx = 0; 287 ps_dec->u4_pred_info_idx = 0; 288 289 if(ps_cur_mb_info->u1_mb_type <= u1_skip_th) 290 { 291 WORD32 pred_cnt = 0; 292 pred_info_pkd_t *ps_pred_pkd; 293 UWORD32 u4_pred_info_pkd_idx; 294 WORD8 i1_pred; 295 296 u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx; 297 298 while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts) 299 { 300 ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx; 301 302 ps_dec->p_form_mb_part_info_thread(ps_pred_pkd,ps_dec, 303 ps_cur_mb_info->u2_mbx, 304 ps_cur_mb_info->u2_mby, 305 (i >> u1_mbaff), 306 ps_cur_mb_info); 307 308 u4_pred_info_pkd_idx++; 309 pred_cnt++; 310 } 311 ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info); 312 } 313 else if(ps_cur_mb_info->u1_mb_type == MB_SKIP) 314 { 315 WORD32 pred_cnt = 0; 316 pred_info_pkd_t *ps_pred_pkd; 317 UWORD32 u4_pred_info_pkd_idx; 318 WORD8 i1_pred; 319 320 u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx; 321 322 while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts) 323 { 324 ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx; 325 326 ps_dec->p_form_mb_part_info_thread(ps_pred_pkd,ps_dec, 327 ps_cur_mb_info->u2_mbx, 328 ps_cur_mb_info->u2_mby, 329 (i >> u1_mbaff), 330 ps_cur_mb_info); 331 332 u4_pred_info_pkd_idx++; 333 pred_cnt++; 334 } 335 /* Decode MB skip */ 336 ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info); 337 } 338 339 u2_cur_dec_mb_num++; 340 } 341 342 /* N Mb IQ IT RECON Loop */ 343 for(j = 0; j < i; j++) 344 { 345 ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->cur_dec_mb_num]; 346 347 if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag) 348 { 349 if(ps_cur_mb_info->u1_mb_type <= u1_skip_th) 350 { 351 ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j); 352 } 353 else if(ps_cur_mb_info->u1_mb_type != MB_SKIP) 354 { 355 if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type) 356 { 357 ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1); 358 ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j); 359 } 360 } 361 362 363 if(ps_dec->u4_use_intrapred_line_copy == 1) 364 ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j); 365 } 366 367 DATA_SYNC(); 368 369 if(u1_mbaff) 370 { 371 if(u4_update_mbaff) 372 { 373 UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx 374 + ps_dec->u2_frm_wd_in_mbs 375 * (ps_cur_mb_info->u2_mby >> 1); 376 UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num); 377 u4_update_mbaff = 0; 378 } 379 else 380 { 381 u4_update_mbaff = 1; 382 } 383 } 384 else 385 { 386 UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx 387 + ps_dec->u2_frm_wd_in_mbs * ps_cur_mb_info->u2_mby; 388 UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num); 389 } 390 ps_dec->cur_dec_mb_num++; 391 } 392 393 /*N MB deblocking*/ 394 if(ps_dec->u4_nmb_deblk == 1) 395 { 396 UWORD32 u4_wd_y, u4_wd_uv; 397 tfr_ctxt_t *ps_tfr_cxt = &(ps_dec->s_tran_addrecon); 398 UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; 399 const WORD32 i4_cb_qp_idx_ofst = 400 ps_dec->ps_cur_pps->i1_chroma_qp_index_offset; 401 const WORD32 i4_cr_qp_idx_ofst = 402 ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset; 403 404 u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag; 405 u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag; 406 407 ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->u4_cur_deblk_mb_num]; 408 409 ps_dec->u4_deblk_mb_x = ps_cur_mb_info->u2_mbx; 410 ps_dec->u4_deblk_mb_y = ps_cur_mb_info->u2_mby; 411 412 413 for(j = 0; j < i; j++) 414 { 415 ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, 416 i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst, 417 u4_wd_y, u4_wd_uv); 418 419 } 420 } 421 422 /*handle the last mb in picture case*/ 423 if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr) 424 ps_dec->u4_cur_slice_decode_done = 1; 425 426 if(i != u1_num_mbs) 427 { 428 u1_end_of_row = 0; 429 /*Number of MB's left in row*/ 430 u1_num_mbs_next = u1_num_mbs_next + ((u1_num_mbs - i) >> u1_mbaff); 431 } 432 433 ih264d_decode_tfr_nmb(ps_dec, (i), u1_num_mbs_next, u1_end_of_row); 434 435 return OK; 436 } 437 438 WORD32 ih264d_decode_slice_thread(dec_struct_t *ps_dec) 439 { 440 UWORD8 u1_num_mbs_next, u1_num_mbsleft, u1_end_of_row = 0; 441 const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs; 442 UWORD8 u1_mbaff, u1_num_mbs; 443 444 UWORD16 u2_first_mb_in_slice; 445 UWORD16 i16_mb_x, i16_mb_y; 446 UWORD8 u1_field_pic; 447 UWORD32 u4_frame_stride, x_offset, y_offset; 448 WORD32 ret; 449 450 tfr_ctxt_t *ps_trns_addr; 451 452 /*check for mb map of first mb in slice to ensure slice header is parsed*/ 453 while(1) 454 { 455 UWORD32 u4_mb_num = ps_dec->cur_dec_mb_num; 456 UWORD32 u4_cond = 0; 457 WORD32 nop_cnt = 8 * 128; 458 CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond); 459 if(u4_cond) 460 { 461 break; 462 } 463 else 464 { 465 if(nop_cnt > 0) 466 { 467 nop_cnt -= 128; 468 NOP(128); 469 } 470 else if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) && 471 (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht)) 472 { 473 ps_dec->u4_fmt_conv_num_rows = 474 MIN(FMT_CONV_NUM_ROWS, 475 (ps_dec->s_disp_frame_info.u4_y_ht 476 - ps_dec->u4_fmt_conv_cur_row)); 477 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), 478 ps_dec->u4_fmt_conv_cur_row, 479 ps_dec->u4_fmt_conv_num_rows); 480 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; 481 } 482 else 483 { 484 nop_cnt = 8*128; 485 ithread_yield(); 486 } 487 DEBUG_THREADS_PRINTF("waiting for mb mapcur_dec_mb_num = %d,ps_dec->u2_cur_mb_addr = %d\n",u2_cur_dec_mb_num, 488 ps_dec->u2_cur_mb_addr); 489 490 } 491 } 492 493 494 495 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; 496 497 u2_first_mb_in_slice = ps_dec->ps_decode_cur_slice->u4_first_mb_in_slice; 498 499 i16_mb_x = MOD(u2_first_mb_in_slice, i2_pic_wdin_mbs); 500 i16_mb_y = DIV(u2_first_mb_in_slice, i2_pic_wdin_mbs); 501 i16_mb_y <<= u1_mbaff; 502 ps_dec->i2_dec_thread_mb_y = i16_mb_y; 503 504 505 ps_dec->cur_dec_mb_num = u2_first_mb_in_slice << u1_mbaff; 506 507 if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag) 508 { 509 ps_dec->pv_proc_tu_coeff_data = 510 (void *) ps_dec->ps_decode_cur_slice->pv_tu_coeff_data_start; 511 } 512 513 // recalculate recon pointers 514 u1_field_pic = ps_dec->ps_cur_slice->u1_field_pic_flag; 515 u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic; 516 x_offset = i16_mb_x << 4; 517 y_offset = (i16_mb_y * u4_frame_stride) << 4; 518 519 ps_trns_addr = &(ps_dec->s_tran_addrecon); 520 521 ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset; 522 523 u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic; 524 x_offset >>= 1; 525 y_offset = (i16_mb_y * u4_frame_stride) << 3; 526 527 x_offset *= YUV420SP_FACTOR; 528 529 ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset; 530 ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset; 531 532 ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y; 533 ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u; 534 ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v; 535 536 537 /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */ 538 { 539 ps_dec->p_mc_dec_thread = ih264d_motion_compensate_bp; 540 ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_bp; 541 } 542 { 543 UWORD8 uc_nofield_nombaff; 544 uc_nofield_nombaff = ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) 545 && (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) 546 && (ps_dec->ps_decode_cur_slice->slice_type != B_SLICE) 547 && (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0)); 548 549 if(uc_nofield_nombaff == 0) 550 { 551 ps_dec->p_mc_dec_thread = ih264d_motion_compensate_mp; 552 ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_mp; 553 } 554 555 } 556 557 ps_dec->u4_cur_slice_decode_done = 0; 558 559 560 while(ps_dec->u4_cur_slice_decode_done != 1) 561 { 562 563 u1_num_mbsleft = ((i2_pic_wdin_mbs - i16_mb_x) << u1_mbaff); 564 565 if(u1_num_mbsleft <= ps_dec->u1_recon_mb_grp) 566 { 567 u1_num_mbs = u1_num_mbsleft; 568 569 /*Indicate number of mb's left in a row*/ 570 u1_num_mbs_next = 0; 571 u1_end_of_row = 1; 572 i16_mb_x = 0; 573 } 574 else 575 { 576 u1_num_mbs = ps_dec->u1_recon_mb_grp; 577 578 /*Indicate number of mb's left in a row*/ 579 u1_num_mbs_next = i2_pic_wdin_mbs - i16_mb_x 580 - (ps_dec->u1_recon_mb_grp >> u1_mbaff); 581 i16_mb_x += (u1_num_mbs >> u1_mbaff); 582 u1_end_of_row = 0; 583 584 } 585 ret = ih264d_decode_recon_tfr_nmb_thread(ps_dec, u1_num_mbs, u1_num_mbs_next, 586 u1_end_of_row); 587 if(ret != OK) 588 return ret; 589 } 590 return OK; 591 } 592 593 void ih264d_decode_picture_thread(dec_struct_t *ps_dec ) 594 { 595 ithread_set_name("ih264d_decode_picture_thread"); 596 while(1) 597 { 598 /*Complete all writes before processing next slice*/ 599 600 DEBUG_THREADS_PRINTF(" Entering decode slice\n"); 601 602 ih264d_decode_slice_thread(ps_dec); 603 DEBUG_THREADS_PRINTF(" Exit ih264d_decode_slice_thread \n"); 604 605 606 if(ps_dec->cur_dec_mb_num 607 > ps_dec->ps_cur_sps->u2_max_mb_addr) 608 { 609 /*Last slice in frame*/ 610 break; 611 } 612 else 613 { 614 ps_dec->ps_decode_cur_slice++; 615 ps_dec->u2_cur_slice_num_dec_thread++; 616 } 617 618 } 619 if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) && 620 (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht)) 621 { 622 ps_dec->u4_fmt_conv_num_rows = 623 (ps_dec->s_disp_frame_info.u4_y_ht 624 - ps_dec->u4_fmt_conv_cur_row); 625 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), 626 ps_dec->u4_fmt_conv_cur_row, 627 ps_dec->u4_fmt_conv_num_rows); 628 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; 629 } 630 } 631 632 void ih264d_signal_decode_thread(dec_struct_t *ps_dec) 633 { 634 if(ps_dec->u4_dec_thread_created == 1) 635 { 636 ithread_join(ps_dec->pv_dec_thread_handle, NULL); 637 ps_dec->u4_dec_thread_created = 0; 638 } 639 } 640 void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec) 641 { 642 if(ps_dec->u4_bs_deblk_thread_created) 643 { 644 ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL); 645 ps_dec->u4_bs_deblk_thread_created = 0; 646 } 647 648 } 649