1 /****************************************************************************** 2 * 3 * Copyright (C) 2018 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 ****************************************************************************** 23 * @file 24 * ihevce_lap_interface.c 25 * 26 * @brief 27 * This file contains function definitions related to look-ahead processing 28 * 29 * @author 30 * ittiam 31 * 32 * @par List of Functions: 33 * 34 ****************************************************************************** 35 */ 36 37 /*****************************************************************************/ 38 /* File Includes */ 39 /*****************************************************************************/ 40 41 /* System Include Files */ 42 #include <stdio.h> 43 #include <string.h> 44 #include <stdlib.h> 45 #include <assert.h> 46 47 /* User Include Files */ 48 #include "ihevc_typedefs.h" 49 #include "itt_video_api.h" 50 #include "ihevce_api.h" 51 52 #include "rc_cntrl_param.h" 53 #include "rc_frame_info_collector.h" 54 #include "rc_look_ahead_params.h" 55 56 #include "ihevc_defs.h" 57 #include "ihevc_macros.h" 58 #include "ihevc_debug.h" 59 #include "ihevc_structs.h" 60 #include "ihevc_platform_macros.h" 61 #include "ihevc_deblk.h" 62 #include "ihevc_itrans_recon.h" 63 #include "ihevc_chroma_itrans_recon.h" 64 #include "ihevc_chroma_intra_pred.h" 65 #include "ihevc_intra_pred.h" 66 #include "ihevc_inter_pred.h" 67 #include "ihevc_mem_fns.h" 68 #include "ihevc_padding.h" 69 #include "ihevc_weighted_pred.h" 70 #include "ihevc_sao.h" 71 #include "ihevc_resi_trans.h" 72 #include "ihevc_quant_iquant_ssd.h" 73 #include "ihevc_cabac_tables.h" 74 75 #include "ihevce_defs.h" 76 #include "ihevce_api.h" 77 #include "ihevce_hle_interface.h" 78 #include "ihevce_hle_q_func.h" 79 #include "ihevce_lap_enc_structs.h" 80 #include "ihevce_lap_interface.h" 81 #include "ihevce_lap_structs.h" 82 #include "ihevce_multi_thrd_structs.h" 83 #include "ihevce_function_selector.h" 84 #include "ihevce_me_common_defs.h" 85 #include "ihevce_enc_structs.h" 86 #include "ihevce_rc_enc_structs.h" 87 #include "ihevce_rc_interface.h" 88 #include "ihevce_buffer_que_interface.h" 89 90 /*****************************************************************************/ 91 /* Globals */ 92 /*****************************************************************************/ 93 WORD32 gau1_order_insert_pic_type[MAX_TEMPORAL_LAYERS][8] = { 94 { P_PIC, B_PIC, P_PIC, B_PIC, P_PIC, B_PIC, P_PIC, B_PIC }, 95 { P_PIC, B_PIC, B1_PIC, B1_PIC, P_PIC, B_PIC, B1_PIC, B1_PIC }, 96 { P_PIC, B_PIC, B1_PIC, B2_PIC, B2_PIC, B1_PIC, B2_PIC, B2_PIC }, 97 }; 98 99 UWORD8 gau1_use_by_cur_pic_flag[MAX_REF_PICS] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; 100 101 /*****************************************************************************/ 102 /* Function Definitions */ 103 /*****************************************************************************/ 104 105 /*! 106 ************************************************************************ 107 * \brief 108 * return number of records used by LAP 109 * 110 ************************************************************************ 111 */ 112 WORD32 ihevce_lap_get_num_mem_recs(void) 113 { 114 return (NUM_LAP_MEM_RECS); 115 } 116 117 /*! 118 ************************************************************************ 119 * @brief 120 * return each record attributes of LAP 121 ************************************************************************ 122 */ 123 WORD32 ihevce_lap_get_mem_recs(iv_mem_rec_t *ps_mem_tab, WORD32 i4_mem_space) 124 { 125 /* number of NODE memory */ 126 WORD32 max_nodes = MAX_SUB_GOP_SIZE - 1; 127 128 ps_mem_tab[LAP_CTXT].i4_mem_size = sizeof(lap_struct_t); 129 ps_mem_tab[LAP_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space; 130 ps_mem_tab[LAP_CTXT].i4_mem_alignment = 8; 131 132 /* Node memory for 2 sub-gops*/ 133 ps_mem_tab[LAP_NODE_MEM].i4_mem_size = (max_nodes * sizeof(ihevce_encode_node_t)); 134 135 ps_mem_tab[LAP_NODE_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space; 136 137 ps_mem_tab[LAP_NODE_MEM].i4_mem_alignment = 8; 138 139 return (NUM_LAP_MEM_RECS); 140 } 141 142 /*! 143 ************************************************************************ 144 * @brief 145 * Init LAP structure 146 ************************************************************************ 147 */ 148 void *ihevce_lap_init( 149 iv_mem_rec_t *ps_mem_tab, 150 ihevce_lap_static_params_t *ps_lap_params, 151 ihevce_static_cfg_params_t *ps_static_cfg_prms) 152 { 153 WORD32 i4_src_interlace_field; 154 WORD32 i4_max_temporal_layers; 155 ihevce_encode_node_t *ps_encode_node_struct; 156 lap_struct_t *ps_lap_struct = (lap_struct_t *)ps_mem_tab[LAP_CTXT].pv_base; 157 ihevce_lap_static_params_t *ps_lap_static_params = &ps_lap_struct->s_lap_static_params; 158 ps_lap_struct->aps_encode_node[0] = (ihevce_encode_node_t *)ps_mem_tab[LAP_NODE_MEM].pv_base; 159 160 memcpy( 161 &ps_lap_struct->s_static_cfg_params, 162 ps_static_cfg_prms, 163 sizeof(ihevce_static_cfg_params_t)); 164 memmove(ps_lap_static_params, ps_lap_params, sizeof(ihevce_lap_static_params_t)); 165 ps_lap_static_params->e_arch_type = ps_static_cfg_prms->e_arch_type; 166 167 /* Set the array to zero */ 168 memset(&ps_lap_struct->ai4_capture_order_poc[0], 0, MAX_NUM_ENC_NODES * sizeof(WORD32)); 169 memset(&ps_lap_struct->ai4_encode_order_poc[0], 0, MAX_NUM_ENC_NODES * sizeof(WORD32)); 170 memset(&ps_lap_struct->ref_poc_array[0], 0xFF, sizeof(ps_lap_struct->ref_poc_array)); 171 memset(&ps_lap_struct->ai4_pic_type_to_be_removed, 0, NUM_LAP2_LOOK_AHEAD * sizeof(WORD32)); 172 173 ps_lap_struct->i4_curr_poc = 0; 174 ps_lap_struct->i4_cra_poc = 0; 175 176 i4_max_temporal_layers = ps_lap_static_params->i4_max_temporal_layers; 177 i4_src_interlace_field = ps_lap_static_params->i4_src_interlace_field; 178 ps_lap_struct->i4_max_idr_period = 179 ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period; 180 ps_lap_struct->i4_min_idr_period = 181 ps_static_cfg_prms->s_coding_tools_prms.i4_min_closed_gop_period; 182 ps_lap_struct->i4_max_cra_period = 183 ps_static_cfg_prms->s_coding_tools_prms.i4_max_cra_open_gop_period; 184 ps_lap_struct->i4_max_i_period = 185 ps_static_cfg_prms->s_coding_tools_prms.i4_max_i_open_gop_period; 186 ps_lap_struct->i4_idr_counter = 0; 187 ps_lap_struct->i4_cra_counter = 0; 188 ps_lap_struct->i4_i_counter = 0; 189 ps_lap_struct->i4_idr_gop_num = -1; 190 ps_lap_struct->i4_curr_ref_pics = 0; 191 ps_lap_struct->i4_display_num = 0; 192 ps_lap_struct->i4_num_frames_after_force_idr = 0; 193 ps_lap_struct->i4_num_frm_type_decided = 0; 194 ps_lap_struct->i4_next_start_ctr = 0; 195 ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_IDR; 196 197 ps_lap_struct->i4_enable_logo = ps_lap_static_params->i4_enable_logo; 198 ps_lap_struct->i4_cra_i_pic_flag = 0; 199 ps_lap_struct->i4_force_end_flag = 0; 200 ps_lap_struct->i4_sub_gop_size = (1 << i4_max_temporal_layers); 201 ps_lap_struct->i4_sub_gop_size_idr = 202 ps_lap_struct->i4_sub_gop_size + (i4_max_temporal_layers > 0); 203 204 ps_lap_struct->i4_is_all_i_pic_in_seq = 0; 205 206 if(ps_lap_struct->i4_max_idr_period == 1 || ps_lap_struct->i4_max_cra_period == 1 || 207 ps_lap_struct->i4_max_i_period == 1) 208 { 209 ps_lap_struct->i4_is_all_i_pic_in_seq = 1; 210 } 211 212 if(1 == i4_src_interlace_field && (!ps_lap_struct->i4_is_all_i_pic_in_seq)) 213 { 214 ps_lap_struct->i4_sub_gop_size <<= 1; 215 ps_lap_struct->i4_sub_gop_size_idr <<= 1; 216 } 217 218 ps_lap_struct->i4_fixed_open_gop_period = 1; 219 ps_lap_struct->i4_fixed_i_period = 1; 220 221 if(ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period <= 222 ps_lap_struct->i4_sub_gop_size) 223 { 224 ps_lap_struct->i4_min_idr_period = 225 ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period; 226 } 227 if(ps_lap_struct->i4_max_idr_period) 228 { 229 if(ps_lap_struct->i4_max_cra_period) 230 { 231 ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_cra_period; 232 } 233 else if(ps_lap_struct->i4_max_i_period) 234 { 235 ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_i_period; 236 } 237 else 238 { 239 ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_idr_period; 240 } 241 } 242 else 243 { 244 if(ps_lap_struct->i4_max_i_period) 245 { 246 ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_i_period; 247 } 248 else if(ps_lap_struct->i4_max_cra_period) 249 { 250 ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_cra_period; 251 } 252 } 253 254 if(!ps_lap_struct->i4_max_i_period) 255 { 256 ps_lap_struct->i4_max_i_period = 257 2 * MAX(ps_lap_struct->i4_max_idr_period, ps_lap_struct->i4_max_cra_period); 258 } 259 260 ps_lap_struct->i4_no_back_to_back_i_avoidance = 0; 261 262 /*Infinite GOP case*/ 263 if(!ps_lap_struct->i4_gop_period) 264 { 265 /*max signed 32 bit value which will be ~ 414 days considering 60frames/fields per second*/ 266 ps_lap_struct->i4_max_i_period = 0x7fffffff; 267 ps_lap_struct->i4_gop_period = 268 (INFINITE_GOP_CDR_TIME_S * (ps_static_cfg_prms->s_src_prms.i4_frm_rate_num / 269 ps_static_cfg_prms->s_src_prms.i4_frm_rate_denom)); 270 } 271 272 if(ps_lap_struct->i4_gop_period < (2 * ps_lap_struct->i4_sub_gop_size)) 273 { 274 ps_lap_struct->i4_no_back_to_back_i_avoidance = 1; 275 } 276 277 ps_lap_struct->i4_rc_lap_period = 278 ps_static_cfg_prms->s_lap_prms.i4_rc_look_ahead_pics + MIN_L1_L0_STAGGER_NON_SEQ; 279 ps_lap_struct->pv_prev_inp_buf = NULL; 280 ps_lap_struct->i4_buf_deq_idx = 0; 281 ps_lap_struct->i4_deq_idx = 0; 282 ps_lap_struct->i4_enq_idx = 0; 283 ps_lap_struct->i4_lap2_counter = 0; 284 ps_lap_struct->i4_dyn_sub_gop_size = ps_lap_struct->i4_sub_gop_size; 285 ps_lap_struct->i4_buf_enq_idx = 0; 286 ps_lap_struct->i4_lap_out_idx = 0; 287 ps_lap_struct->i4_capture_idx = 0; 288 ps_lap_struct->i4_idr_flag = 1; 289 ps_lap_struct->i4_num_bufs_encode_order = 0; 290 ps_lap_struct->end_flag = 0; 291 ps_lap_struct->i4_immediate_idr_case = 0; 292 ps_lap_struct->i4_max_buf_in_enc_order = 0; 293 ps_lap_struct->i4_end_flag_pic_idx = 0; 294 memset( 295 &ps_lap_struct->api4_encode_order_array[0], 296 0, 297 sizeof(ihevce_lap_enc_buf_t *) * MAX_NUM_ENC_NODES); 298 299 { 300 WORD32 node_offset, curr_layer; 301 WORD32 i; 302 /*intialization of aps_lap_inp_buf*/ 303 for(i = 0; i < MAX_QUEUE_LENGTH; i++) 304 { 305 ps_lap_struct->aps_lap_inp_buf[i] = NULL; 306 } 307 308 /* init capture order and encode order pointer */ 309 ps_lap_struct->pi4_capture_poc_ptr = &ps_lap_struct->ai4_capture_order_poc[0]; 310 ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0]; 311 312 /* init all the buffer status to default values */ 313 ps_encode_node_struct = ps_lap_struct->aps_encode_node[0]; 314 315 ps_encode_node_struct->pv_left_node = NULL; 316 ps_encode_node_struct->pv_right_node = NULL; 317 318 /* Initialise the tree */ 319 node_offset = 1; 320 curr_layer = 0; 321 ihevce_populate_tree_nodes( 322 ps_encode_node_struct, 323 ps_encode_node_struct, 324 &node_offset, 325 curr_layer, 326 ps_lap_static_params->i4_max_temporal_layers); 327 } 328 329 ps_mem_tab += NUM_LAP_MEM_RECS; 330 331 return ((void *)ps_lap_struct); 332 } 333 334 /*! 335 ****************************************************************************** 336 * \if Function name : ihevce_populate_tree_nodes \endif 337 * 338 * \brief 339 * LAP populate nodes function 340 * 341 * \param[in] encode_parent_node_t node pointer to base 342 * encode_node_t node pointer to current buffer 343 * loop_count layer count 344 * hier_layer total layers 345 * \return 346 * None 347 * 348 * \author 349 * Ittiam 350 * 351 ***************************************************************************** 352 */ 353 void ihevce_populate_tree_nodes( 354 ihevce_encode_node_t *encode_parent_node_t, 355 ihevce_encode_node_t *encode_node_t, 356 WORD32 *loop_count, 357 WORD32 layer, 358 WORD32 hier_layer) 359 { 360 /* If only I/P pictures, return NULL from the child nodes*/ 361 if(hier_layer == 0) 362 { 363 encode_node_t->pv_left_node = NULL; 364 encode_node_t->pv_right_node = NULL; 365 return; 366 } 367 if(layer == hier_layer) 368 return; 369 370 layer = layer + 1; 371 372 /* If the layers are not exhausted */ 373 if(layer < hier_layer) 374 { 375 encode_node_t->pv_left_node = encode_parent_node_t + (*loop_count); 376 encode_node_t->pv_right_node = encode_parent_node_t + (*loop_count + 1); 377 (*loop_count) = (*loop_count) + 2; 378 } 379 else 380 { 381 encode_node_t->pv_left_node = NULL; 382 encode_node_t->pv_right_node = NULL; 383 } 384 385 /* Populate Left tree nodes */ 386 ihevce_populate_tree_nodes( 387 encode_parent_node_t, 388 (ihevce_encode_node_t *)encode_node_t->pv_left_node, 389 loop_count, 390 layer, 391 hier_layer); 392 393 /* Populate right tree nodes */ 394 ihevce_populate_tree_nodes( 395 encode_parent_node_t, 396 (ihevce_encode_node_t *)encode_node_t->pv_right_node, 397 loop_count, 398 layer, 399 hier_layer); 400 } 401 402 /*! 403 ************************************************************************ 404 * \brief 405 * pad input when its dimensions are not aligned to LCU size 406 ************************************************************************ 407 */ 408 void ihevce_lap_pad_input_bufs( 409 ihevce_lap_enc_buf_t *ps_curr_inp, WORD32 align_pic_wd, WORD32 align_pic_ht) 410 { 411 /* local variables */ 412 WORD32 ctr_horz, ctr_vert; 413 414 /* ------- Horizontal Right Padding ------ */ 415 if(align_pic_wd != ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd) 416 { 417 UWORD8 *pu1_inp; 418 UWORD16 *pu2_inp; 419 WORD32 pad_wd; 420 WORD32 pad_ht; 421 422 /* ------------- LUMA ----------------------------- */ 423 /* derive the pointers and dimensions to be padded */ 424 pad_ht = ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht; 425 pad_wd = align_pic_wd - ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd; 426 pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf; 427 pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd; 428 429 /* loops for padding the right region for entire pic */ 430 for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++) 431 { 432 for(ctr_horz = 0; ctr_horz < pad_wd; ctr_horz++) 433 { 434 /* last pixel is replicated */ 435 pu1_inp[ctr_horz] = pu1_inp[-1]; 436 } 437 438 /* row level increments */ 439 pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd; 440 } 441 442 /* ------------- CHROMA ---------------------------- */ 443 /* derive the pointers and dimensions to be padded */ 444 pad_ht = ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht; 445 pad_wd = align_pic_wd - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd; 446 pad_wd >>= 1; 447 pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf; 448 pu2_inp = (UWORD16 *)(pu1_inp + ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd); 449 450 /* loops for padding the right region for entire pic */ 451 for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++) 452 { 453 for(ctr_horz = 0; ctr_horz < pad_wd; ctr_horz++) 454 { 455 /* last pixel is replicated, cb and cr pixel interleaved */ 456 pu2_inp[ctr_horz] = pu2_inp[-1]; 457 } 458 459 /* row level increments */ 460 pu2_inp += (ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd >> 1); 461 } 462 } 463 464 /* ------- Vertical Bottom Padding ------ */ 465 if(align_pic_ht != ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht) 466 { 467 UWORD8 *pu1_inp, *pu1_src; 468 WORD32 pad_ht; 469 470 /* ------------- LUMA ----------------------------- */ 471 /* derive the pointers and dimensions to be padded */ 472 pad_ht = align_pic_ht - ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht; 473 pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf; 474 pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht * 475 ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd; 476 477 /* get the pointer of last row */ 478 pu1_src = pu1_inp - ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd; 479 480 /* loops for padding the bottom region for entire row */ 481 for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++) 482 { 483 /* copy the eniter orw including horz padd region */ 484 memcpy(pu1_inp, pu1_src, align_pic_wd); 485 486 /* row level increments */ 487 pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd; 488 } 489 490 /* ------------- CHROMA ----------------------------- */ 491 /* derive the pointers and dimensions to be padded */ 492 pad_ht = (align_pic_ht >> 1) - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht; 493 pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf; 494 pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht * 495 ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd; 496 497 /* get the pointer of last row */ 498 pu1_src = pu1_inp - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd; 499 500 /* loops for padding the bottom region for entire row */ 501 for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++) 502 { 503 /* copy the eniter orw including horz padd region */ 504 memcpy(pu1_inp, pu1_src, align_pic_wd); 505 506 /* row level increments */ 507 pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd; 508 } 509 } 510 return; 511 } 512 513 /*! 514 ************************************************************************ 515 * \brief 516 * check for last inp buf 517 ************************************************************************ 518 */ 519 WORD32 ihevce_check_last_inp_buf(WORD32 *pi4_cmd_buf) 520 { 521 WORD32 cmd = (*pi4_cmd_buf) & (IHEVCE_COMMANDS_TAG_MASK); 522 523 if(IHEVCE_SYNCH_API_FLUSH_TAG == cmd) 524 return 1; 525 return 0; 526 } 527 528 /*! 529 ************************************************************************ 530 * \brief 531 * lap parse sync commands 532 ************************************************************************ 533 */ 534 void ihevce_lap_parse_sync_cmd( 535 ihevce_hle_ctxt_t *ps_hle_ctxt, 536 ihevce_static_cfg_params_t *ps_static_cfg_prms, 537 WORD32 *pi4_cmd_buf, 538 ihevce_lap_enc_buf_t *ps_lap_inp_buf, 539 WORD32 *pi4_flush_check, 540 WORD32 *pi4_force_idr_check, 541 WORD32 *pi4_set_res_check, 542 WORD32 *pi4_num_frames_after_force_idr) 543 { 544 WORD32 *pi4_end; 545 WORD32 i4_sub_gop_size_mul_2, i4_field_pic, i4_is_first_field; 546 WORD32 *pi4_tag_parse, i4_end_flag = 0, *pi4_next_tag, i4_length, i4_buf_id, i4_next_tag; 547 UWORD32 u4_num_sei = 0; 548 i4_length = ps_lap_inp_buf->s_input_buf.i4_cmd_buf_size; 549 i4_buf_id = ps_lap_inp_buf->s_input_buf.i4_buf_id; 550 pi4_end = pi4_cmd_buf + (i4_length >> 2) - 1; 551 i4_sub_gop_size_mul_2 = (1 << ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers) 552 << 1; 553 i4_field_pic = ps_static_cfg_prms->s_src_prms.i4_field_pic; 554 pi4_tag_parse = pi4_cmd_buf; 555 i4_is_first_field = 1; 556 if(i4_field_pic) 557 { 558 i4_is_first_field = 559 (ps_lap_inp_buf->s_input_buf.i4_topfield_first ^ 560 ps_lap_inp_buf->s_input_buf.i4_bottom_field); 561 } 562 563 while(pi4_tag_parse != (pi4_end + 1)) 564 { 565 switch((*pi4_tag_parse) & (IHEVCE_COMMANDS_TAG_MASK)) 566 { 567 case IHEVCE_SYNCH_API_FLUSH_TAG: 568 (*pi4_flush_check) = 1; 569 if((*(pi4_tag_parse + 1))) 570 ps_hle_ctxt->ihevce_cmds_error_report( 571 ps_hle_ctxt->pv_cmd_err_cb_handle, 572 IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO, 573 1, 574 i4_buf_id); 575 pi4_tag_parse += 2; 576 u4_num_sei++; 577 break; 578 case IHEVCE_SYNCH_API_FORCE_IDR_TAG: 579 if(0 == i4_field_pic) 580 { 581 (*pi4_force_idr_check) = 1; 582 if((*(pi4_tag_parse + 1))) 583 ps_hle_ctxt->ihevce_cmds_error_report( 584 ps_hle_ctxt->pv_cmd_err_cb_handle, 585 IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO, 586 1, 587 i4_buf_id); 588 if(*pi4_num_frames_after_force_idr < i4_sub_gop_size_mul_2) 589 { 590 ps_hle_ctxt->ihevce_cmds_error_report( 591 ps_hle_ctxt->pv_cmd_err_cb_handle, 592 IHEVCE_SYNCH_ERR_FREQ_FORCE_IDR_RECEIVED, 593 1, 594 i4_buf_id); 595 } 596 *pi4_num_frames_after_force_idr = 0; 597 } 598 else 599 { 600 if(i4_is_first_field) 601 { 602 (*pi4_force_idr_check) = 1; 603 } 604 if((*(pi4_tag_parse + 1))) 605 ps_hle_ctxt->ihevce_cmds_error_report( 606 ps_hle_ctxt->pv_cmd_err_cb_handle, 607 IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO, 608 1, 609 i4_buf_id); 610 611 if((*pi4_num_frames_after_force_idr < (i4_sub_gop_size_mul_2 << 1))) 612 { 613 ps_hle_ctxt->ihevce_cmds_error_report( 614 ps_hle_ctxt->pv_cmd_err_cb_handle, 615 IHEVCE_SYNCH_ERR_FREQ_FORCE_IDR_RECEIVED, 616 1, 617 i4_buf_id); 618 } 619 *pi4_num_frames_after_force_idr = 0; 620 } 621 pi4_tag_parse += 2; 622 u4_num_sei++; 623 break; 624 case IHEVCE_SYNCH_API_SET_RES_TAG: 625 (*pi4_set_res_check) = 0; 626 ps_hle_ctxt->ihevce_cmds_error_report( 627 ps_hle_ctxt->pv_cmd_err_cb_handle, 628 IHEVCE_SYNCH_ERR_SET_RES_NOT_SUPPORTED, 629 1, 630 i4_buf_id); 631 break; 632 case IHEVCE_SYNCH_API_REG_ALLFRAME_SEI_TAG: 633 pi4_next_tag = 634 pi4_tag_parse + 2 + 635 (((*(pi4_tag_parse + 1) - 1) >> 2) + 1); //Logic to reach the next boundary of 4 636 i4_next_tag = (*pi4_next_tag & IHEVCE_COMMANDS_TAG_MASK); 637 if((i4_next_tag != IHEVCE_SYNCH_API_END_TAG) && 638 (i4_next_tag != IHEVCE_SYNCH_API_FLUSH_TAG) && 639 (i4_next_tag != IHEVCE_SYNCH_API_FORCE_IDR_TAG) && 640 (i4_next_tag != IHEVCE_SYNCH_API_REG_KEYFRAME_SEI_TAG) && 641 (i4_next_tag != IHEVCE_SYNCH_API_REG_ALLFRAME_SEI_TAG)) 642 { 643 if(*(pi4_tag_parse + 1) % 4) 644 ps_hle_ctxt->ihevce_cmds_error_report( 645 ps_hle_ctxt->pv_cmd_err_cb_handle, 646 IHEVCE_SYNCH_ERR_NO_PADDING, 647 1, 648 i4_buf_id); 649 else 650 ps_hle_ctxt->ihevce_cmds_error_report( 651 ps_hle_ctxt->pv_cmd_err_cb_handle, 652 IHEVCE_SYNCH_ERR_WRONG_LENGTH, 653 1, 654 i4_buf_id); 655 } 656 pi4_tag_parse = pi4_next_tag; 657 u4_num_sei++; 658 break; 659 case IHEVCE_SYNCH_API_REG_KEYFRAME_SEI_TAG: 660 pi4_next_tag = 661 pi4_tag_parse + 2 + 662 (((*(pi4_tag_parse + 1) - 1) >> 2) + 1); //Logic to reach the next boundary of 4 663 i4_next_tag = (*pi4_next_tag & IHEVCE_COMMANDS_TAG_MASK); 664 if((i4_next_tag != IHEVCE_SYNCH_API_END_TAG) && 665 (i4_next_tag != IHEVCE_SYNCH_API_FLUSH_TAG) && 666 (i4_next_tag != IHEVCE_SYNCH_API_FORCE_IDR_TAG) && 667 (i4_next_tag != IHEVCE_SYNCH_API_REG_KEYFRAME_SEI_TAG) && 668 (i4_next_tag != IHEVCE_SYNCH_API_REG_ALLFRAME_SEI_TAG)) 669 { 670 if(*(pi4_tag_parse + 1) % 4) 671 ps_hle_ctxt->ihevce_cmds_error_report( 672 ps_hle_ctxt->pv_cmd_err_cb_handle, 673 IHEVCE_SYNCH_ERR_NO_PADDING, 674 1, 675 i4_buf_id); 676 else 677 ps_hle_ctxt->ihevce_cmds_error_report( 678 ps_hle_ctxt->pv_cmd_err_cb_handle, 679 IHEVCE_SYNCH_ERR_WRONG_LENGTH, 680 1, 681 i4_buf_id); 682 } 683 pi4_tag_parse = pi4_next_tag; 684 u4_num_sei++; 685 break; 686 case IHEVCE_SYNCH_API_END_TAG: 687 i4_end_flag = 1; 688 break; 689 default: 690 ps_hle_ctxt->ihevce_cmds_error_report( 691 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_TLV_ERROR, 1, i4_buf_id); 692 } 693 if(i4_end_flag) 694 break; 695 } 696 if(u4_num_sei > MAX_NUMBER_OF_SEI_PAYLOAD) //Checking for max number of SEI messages. 697 ps_hle_ctxt->ihevce_cmds_error_report( 698 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_TOO_MANY_SEI_MSG, 1, i4_buf_id); 699 700 if(!i4_end_flag) 701 ps_hle_ctxt->ihevce_cmds_error_report( 702 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_NO_END_TAG, 1, i4_buf_id); 703 } 704 705 /*! 706 ************************************************************************ 707 * \brief 708 * lap parse Async commands 709 ************************************************************************ 710 */ 711 void ihevce_lap_parse_async_cmd( 712 ihevce_hle_ctxt_t *ps_hle_ctxt, 713 WORD32 *pi4_cmd_buf, 714 WORD32 i4_length, 715 WORD32 i4_buf_id, 716 WORD32 *pi4_num_set_bitrate_cmds, 717 ihevce_dyn_config_prms_t *ps_dyn_br) 718 { 719 WORD32 i4_end_flag = 0; 720 WORD32 *pi4_end = pi4_cmd_buf + (i4_length >> 2) - 1; 721 WORD32 *pi4_tag_parse = pi4_cmd_buf; 722 723 while(pi4_tag_parse != pi4_end) 724 { 725 switch(*pi4_tag_parse) 726 { 727 case IHEVCE_ASYNCH_API_SETBITRATE_TAG: 728 if((*(pi4_tag_parse + 1)) != sizeof(ihevce_dyn_config_prms_t)) 729 ps_hle_ctxt->ihevce_cmds_error_report( 730 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_BR_NOT_BYTE, 1, i4_buf_id); 731 732 memcpy( 733 (void *)ps_dyn_br, (void *)(pi4_tag_parse + 2), sizeof(ihevce_dyn_config_prms_t)); 734 pi4_tag_parse += 2; 735 pi4_tag_parse += (sizeof(ihevce_dyn_config_prms_t) >> 2); 736 *pi4_num_set_bitrate_cmds = *pi4_num_set_bitrate_cmds + 1; 737 ps_dyn_br++; 738 739 break; 740 case IHEVCE_ASYNCH_API_END_TAG: 741 i4_end_flag = 1; 742 break; 743 default: 744 ps_hle_ctxt->ihevce_cmds_error_report( 745 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_TLV_ERROR, 1, i4_buf_id); 746 } 747 if(i4_end_flag) 748 break; 749 } 750 if(!i4_end_flag) 751 ps_hle_ctxt->ihevce_cmds_error_report( 752 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_NO_END_TAG, 1, i4_buf_id); 753 } 754 755 /*! 756 ************************************************************************ 757 * \brief 758 * ref pics weight offset calculation 759 ************************************************************************ 760 */ 761 void ref_pics_weight_offset_calc(ihevce_lap_output_params_t *ps_lap_out, lap_struct_t *ps_lap_struct) 762 { 763 WORD32 i, j; 764 WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array; 765 WORD32 ai4_delta_poc[MAX_REF_PICS]; 766 WORD32 ref_poc_arr_sort[MAX_REF_PICS]; 767 768 /* Default weighted pred parameters populated for now */ 769 ps_lap_out->i4_log2_luma_wght_denom = DENOM_DEFAULT; 770 ps_lap_out->i4_log2_chroma_wght_denom = DENOM_DEFAULT; 771 772 /* sort the ref_poc_array based on delta as 773 * in case weighted pred dup pics are inserted and it should consider 774 * the neighbors first for prediction than farthest */ 775 for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++) 776 { 777 ai4_delta_poc[i] = ref_poc_array[i] - ps_lap_out->i4_poc; 778 } 779 780 for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++) 781 { 782 WORD32 i4_min, temp; 783 i4_min = i; 784 for(j = i; j < ps_lap_struct->i4_curr_ref_pics; j++) 785 { 786 if(abs(ai4_delta_poc[j]) <= abs(ai4_delta_poc[i4_min])) 787 { 788 i4_min = j; 789 } 790 } 791 temp = ai4_delta_poc[i]; 792 ai4_delta_poc[i] = ai4_delta_poc[i4_min]; 793 ai4_delta_poc[i4_min] = temp; 794 ref_poc_arr_sort[i] = ai4_delta_poc[i] + ps_lap_out->i4_poc; 795 } 796 797 for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++) 798 { 799 ps_lap_out->as_ref_pics[i].i4_ref_pic_delta_poc = ref_poc_arr_sort[i] - ps_lap_out->i4_poc; 800 ASSERT(ps_lap_out->as_ref_pics[i].i4_ref_pic_delta_poc); 801 802 /* Enable flag for the reference pics to be used by curr pic */ 803 ps_lap_out->as_ref_pics[i].i4_used_by_cur_pic_flag = gau1_use_by_cur_pic_flag[i]; 804 805 /* Currently no weighted prediction offset added */ 806 ps_lap_out->as_ref_pics[i].i4_num_duplicate_entries_in_ref_list = 1; 807 } 808 return; 809 } 810 811 /*! 812 ************************************************************************ 813 * \brief 814 * ref b picture population 815 ************************************************************************ 816 */ 817 void ref_b_pic_population( 818 WORD32 curr_layer, ihevce_lap_enc_buf_t *ps_lap_inp, lap_struct_t *ps_lap_struct) 819 { 820 ihevce_lap_output_params_t *ps_lap_out = &ps_lap_inp->s_lap_out; 821 WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array; 822 WORD32 *p_ref_poc_array = ref_poc_array; 823 WORD32 i4_interlace_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field; 824 WORD32 i4_max_ref_pics = ps_lap_struct->s_lap_static_params.i4_max_reference_frames; 825 WORD32 max_temporal_layers = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers; 826 827 /* LAP output structure */ 828 ps_lap_out->i4_poc = ps_lap_struct->pi4_encode_poc_ptr[0]; 829 ps_lap_out->i4_idr_gop_num = ps_lap_struct->i4_idr_gop_num; 830 ps_lap_out->i4_assoc_IRAP_poc = ps_lap_struct->i4_assoc_IRAP_poc; 831 ps_lap_out->i4_temporal_lyr_id = curr_layer; 832 ps_lap_out->i4_pic_type = IV_B_FRAME; 833 834 if((ps_lap_out->i4_poc > ps_lap_struct->i4_cra_poc) && 835 (ref_poc_array[0] < ps_lap_struct->i4_cra_poc) && ps_lap_struct->i4_cra_i_pic_flag) 836 { 837 ref_poc_array[0] = ps_lap_struct->i4_cra_poc; 838 ps_lap_struct->i4_curr_ref_pics = 1; 839 } 840 841 ps_lap_out->i4_num_ref_pics = ps_lap_struct->i4_curr_ref_pics; 842 843 /* Default: Cur pic is ref pic*/ 844 ps_lap_out->i4_is_ref_pic = 1; 845 846 if(1 == i4_interlace_field) 847 { 848 WORD32 i4_bottom_field = ps_lap_inp->s_input_buf.i4_bottom_field; 849 WORD32 first_field = (ps_lap_inp->s_input_buf.i4_topfield_first ^ i4_bottom_field); 850 851 /*If current pic is top field B picture and is present in top hierarchical layer */ 852 /* Dereference the curr pic */ 853 if(ps_lap_out->i4_temporal_lyr_id == max_temporal_layers) 854 { 855 if(0 == first_field) 856 ps_lap_out->i4_is_ref_pic = 0; 857 else 858 ps_lap_out->i4_is_ref_pic = 2; 859 } 860 } 861 else 862 { 863 /*If progressive B picture and is present in top hierarchical layer */ 864 if(ps_lap_out->i4_temporal_lyr_id >= max_temporal_layers) 865 { 866 ps_lap_out->i4_temporal_lyr_id = max_temporal_layers; 867 ps_lap_out->i4_is_ref_pic = 0; 868 } 869 } 870 871 ref_pics_weight_offset_calc(ps_lap_out, ps_lap_struct); 872 873 /* Updating number of current reference Pictures for the Given Picture */ 874 /* If the current frame is n-layer B frame, donot increment*/ 875 if(ps_lap_struct->i4_curr_ref_pics < i4_max_ref_pics) 876 { 877 if(ps_lap_out->i4_is_ref_pic) 878 { 879 ps_lap_struct->i4_curr_ref_pics++; 880 } 881 } 882 883 /* Arrange the reference array in ascending order */ 884 { 885 WORD32 i, j, temp; 886 for(i = 0; i < (ps_lap_struct->i4_curr_ref_pics - 1); i++) 887 { 888 for(j = i + 1; j < ps_lap_struct->i4_curr_ref_pics; j++) 889 { 890 if(ref_poc_array[i] > ref_poc_array[j]) 891 { 892 temp = ref_poc_array[i]; 893 ref_poc_array[i] = ref_poc_array[j]; 894 ref_poc_array[j] = temp; 895 } 896 } 897 } 898 } 899 900 { 901 WORD32 ref = ps_lap_out->i4_poc; 902 if(ps_lap_out->i4_is_ref_pic && ref > *p_ref_poc_array) 903 { 904 *p_ref_poc_array = ref; 905 } 906 } 907 908 return; 909 } 910 911 /*! 912 ************************************************************************ 913 * \brief 914 * ref i/p pic population 915 ************************************************************************ 916 */ 917 void ref_pic_population(ihevce_lap_enc_buf_t *ps_lap_inp, lap_struct_t *ps_lap_struct) 918 { 919 ihevce_lap_output_params_t *ps_lap_out = &ps_lap_inp->s_lap_out; 920 WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array; 921 WORD32 *p_ref_poc_array = ref_poc_array; 922 WORD32 i4_max_ref_pics = ps_lap_struct->s_lap_static_params.i4_max_reference_frames; 923 924 /* Update the POC position */ 925 ps_lap_out->i4_poc = ps_lap_struct->pi4_encode_poc_ptr[0]; 926 927 /* picture after CRA can't refer pic before CRA*/ 928 if((ps_lap_out->i4_poc > ps_lap_struct->i4_cra_poc) && 929 (ref_poc_array[0] <= ps_lap_struct->i4_cra_poc) && ps_lap_struct->i4_cra_i_pic_flag) 930 { 931 ref_poc_array[0] = ps_lap_struct->i4_cra_poc; 932 ps_lap_struct->i4_curr_ref_pics = 1; 933 } 934 935 /* For every IDR period, set pic type as IDR frame and reset reference POC array to 0*/ 936 if(IV_IDR_FRAME == ps_lap_out->i4_pic_type) 937 { 938 ps_lap_struct->i4_idr_gop_num++; 939 ps_lap_struct->i4_curr_ref_pics = 0; 940 ps_lap_out->i4_num_ref_pics = 0; 941 ps_lap_struct->i4_cra_i_pic_flag = 1; 942 ps_lap_struct->i4_cra_poc = ps_lap_out->i4_poc; 943 944 memset(ps_lap_struct->ref_poc_array, 0xFF, sizeof(WORD32) * MAX_REF_PICS); 945 } 946 else if(IV_I_FRAME == ps_lap_out->i4_pic_type) 947 { 948 /* For the I-frames after CRA Frame, no pictures should be referenced */ 949 if((1 == ps_lap_struct->i4_cra_i_pic_flag) && ps_lap_out->i4_is_cra_pic) 950 { 951 ps_lap_struct->i4_curr_ref_pics = 0; 952 ps_lap_out->i4_num_ref_pics = 0; 953 } 954 ps_lap_struct->i4_cra_poc = ps_lap_out->i4_poc; 955 ps_lap_struct->i4_cra_i_pic_flag = ps_lap_out->i4_is_cra_pic; 956 } 957 else if(IV_P_FRAME == ps_lap_out->i4_pic_type) 958 { 959 /* If the current POC is the P POC after CRA I POC */ 960 if(1 == ps_lap_struct->i4_cra_i_pic_flag) 961 { 962 ps_lap_struct->i4_curr_ref_pics = 1; 963 ps_lap_struct->i4_cra_i_pic_flag = 0; 964 } 965 } 966 967 if(ps_lap_out->i4_pic_type == IV_IDR_FRAME || 968 (ps_lap_out->i4_pic_type == IV_I_FRAME && ps_lap_out->i4_is_cra_pic)) 969 { 970 ps_lap_struct->i4_assoc_IRAP_poc = ps_lap_out->i4_poc; 971 } 972 973 /*Update ps_lap_out*/ 974 ps_lap_out->i4_idr_gop_num = ps_lap_struct->i4_idr_gop_num; 975 ps_lap_out->i4_is_ref_pic = 1; 976 ps_lap_out->i4_assoc_IRAP_poc = ps_lap_struct->i4_assoc_IRAP_poc; 977 978 /* Reference POCS */ 979 ps_lap_out->i4_num_ref_pics = ps_lap_struct->i4_curr_ref_pics; 980 981 /* I and P frames are always mapped to layer zero*/ 982 ps_lap_out->i4_temporal_lyr_id = 0; 983 984 ref_pics_weight_offset_calc(ps_lap_out, ps_lap_struct); 985 986 if(ps_lap_struct->i4_curr_ref_pics < i4_max_ref_pics) 987 { 988 if(ps_lap_out->i4_is_ref_pic) 989 { 990 ps_lap_struct->i4_curr_ref_pics++; 991 } 992 } 993 994 /* Arrange the reference array in ascending order */ 995 { 996 WORD32 i, j, temp; 997 for(i = 0; i < (ps_lap_struct->i4_curr_ref_pics - 1); i++) 998 { 999 for(j = i + 1; j < (ps_lap_struct->i4_curr_ref_pics); j++) 1000 { 1001 if(ref_poc_array[i] > ref_poc_array[j]) 1002 { 1003 temp = ref_poc_array[i]; 1004 ref_poc_array[i] = ref_poc_array[j]; 1005 ref_poc_array[j] = temp; 1006 } 1007 } 1008 } 1009 } 1010 1011 { 1012 /* add the current pictute at the start of the reference queue */ 1013 /*For I and P pictures, all the previous frames are reference frames */ 1014 /* If the current ref POC is greater than the least POC in reference array*/ 1015 /* Then fill the reference array */ 1016 1017 WORD32 ref = ps_lap_out->i4_poc; 1018 1019 if(ps_lap_out->i4_is_ref_pic && ref > *p_ref_poc_array) 1020 { 1021 *p_ref_poc_array = ref; 1022 } 1023 } 1024 1025 return; 1026 } 1027 1028 /*! 1029 ************************************************************************ 1030 * \brief 1031 * determine next sub-gop state 1032 ************************************************************************ 1033 */ 1034 void ihevce_determine_next_sub_gop_state(lap_struct_t *ps_lap_struct) 1035 { 1036 WORD32 i4_num_b_frames = -1; 1037 WORD32 i4_sd = ps_lap_struct->i4_sub_gop_size; 1038 WORD32 i4_sd_idr = ps_lap_struct->i4_sub_gop_size_idr; 1039 WORD32 i4_Midr = ps_lap_struct->i4_max_idr_period; 1040 WORD32 i4_midr = ps_lap_struct->i4_min_idr_period; 1041 WORD32 i4_Mcra = ps_lap_struct->i4_max_cra_period; 1042 WORD32 i4_Mi = ps_lap_struct->i4_max_i_period; 1043 WORD32 i4_Cd = ps_lap_struct->i4_idr_counter; 1044 WORD32 i4_Cc = ps_lap_struct->i4_cra_counter; 1045 WORD32 i4_Ci = ps_lap_struct->i4_i_counter; 1046 1047 if(i4_Midr) 1048 ASSERT(i4_Cd < i4_Midr); 1049 1050 if(i4_Mcra) 1051 ASSERT(i4_Cc < i4_Mcra); 1052 1053 if(i4_Mi) 1054 ASSERT(i4_Ci < i4_Mi); 1055 1056 /*if all are i pictures */ 1057 if((i4_Midr == 1) || (i4_Mcra == 1) || (i4_Mi == 1)) 1058 { 1059 ps_lap_struct->i4_num_frm_type_decided = 1; 1060 if((i4_Midr == 1) || ((i4_Cd + i4_sd) == i4_Midr)) 1061 { 1062 ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_IDR; 1063 ps_lap_struct->i4_idr_counter = 0; 1064 ps_lap_struct->i4_cra_counter = 0; 1065 ps_lap_struct->i4_i_counter = 0; 1066 } 1067 else if((i4_Mcra == 1) || ((i4_Cc + i4_sd) == i4_Mcra)) 1068 { 1069 ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_CRA; 1070 ps_lap_struct->i4_idr_counter += 1; 1071 ps_lap_struct->i4_cra_counter = 0; 1072 ps_lap_struct->i4_i_counter = 0; 1073 } 1074 else 1075 { 1076 ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_I; 1077 ps_lap_struct->i4_idr_counter += 1; 1078 ps_lap_struct->i4_cra_counter += 1; 1079 ps_lap_struct->i4_i_counter = 0; 1080 } 1081 return; 1082 } 1083 1084 if((i4_Cd + i4_sd_idr >= i4_Midr) && i4_Midr) 1085 { 1086 /*if idr falls already on sub-gop aligned w.r.t Midr or if strict idr use case*/ 1087 if(i4_sd_idr != i4_sd) 1088 { 1089 i4_num_b_frames = i4_Midr - i4_Cd - 2; 1090 memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames); 1091 ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P; 1092 ps_lap_struct->ai1_pic_type[i4_num_b_frames + 2] = PIC_TYPE_IDR; 1093 ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 2; 1094 ps_lap_struct->i4_idr_counter = 0; 1095 ps_lap_struct->i4_cra_counter = 0; 1096 ps_lap_struct->i4_i_counter = 0; 1097 } 1098 else 1099 { 1100 i4_num_b_frames = 0; 1101 ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_IDR; 1102 ps_lap_struct->i4_num_frm_type_decided = 1; 1103 ps_lap_struct->i4_idr_counter = 0; 1104 ps_lap_struct->i4_cra_counter = 0; 1105 ps_lap_struct->i4_i_counter = 0; 1106 } 1107 } 1108 /*if next sub gop is going to have CRA as Cc reaches Mcra*/ 1109 else if(((i4_Cc + i4_sd) >= i4_Mcra) && i4_Mcra) 1110 { 1111 if(((i4_Cc + i4_sd) == i4_Mcra) || (1 == ps_lap_struct->i4_fixed_open_gop_period)) 1112 { 1113 i4_num_b_frames = i4_Mcra - i4_Cc - 1; 1114 memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames); 1115 ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_CRA; 1116 ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1; 1117 ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided; 1118 ps_lap_struct->i4_cra_counter = 0; 1119 ps_lap_struct->i4_i_counter = 0; 1120 } 1121 else 1122 { 1123 ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_CRA; 1124 i4_num_b_frames = i4_sd - 1; 1125 memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames); 1126 ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P; 1127 ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1; 1128 ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided; 1129 ps_lap_struct->i4_cra_counter = ps_lap_struct->i4_num_frm_type_decided; 1130 ps_lap_struct->i4_i_counter = ps_lap_struct->i4_num_frm_type_decided; 1131 } 1132 } 1133 /*if next sub gop is going to have I_slice as Ci reaches Mi*/ 1134 else if((i4_Ci + i4_sd >= i4_Mi) && i4_Mi) 1135 { 1136 if(((i4_Ci + i4_sd) == i4_Mi) || (1 == ps_lap_struct->i4_fixed_i_period)) 1137 { 1138 i4_num_b_frames = i4_Mi - i4_Ci - 1; 1139 memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames); 1140 ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_I; 1141 ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1; 1142 ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided; 1143 ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided; 1144 ps_lap_struct->i4_i_counter = 0; 1145 } 1146 else 1147 { 1148 ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_I; 1149 i4_num_b_frames = i4_sd - 1; 1150 memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames); 1151 ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P; 1152 ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1; 1153 ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided; 1154 ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided; 1155 ps_lap_struct->i4_i_counter = ps_lap_struct->i4_num_frm_type_decided; 1156 } 1157 } 1158 /* if next sub-gop is not going to be idr,cra,I*/ 1159 else 1160 { 1161 i4_num_b_frames = i4_sd - 1; 1162 memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames); 1163 ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P; 1164 ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1; 1165 ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided; 1166 ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided; 1167 ps_lap_struct->i4_i_counter += ps_lap_struct->i4_num_frm_type_decided; 1168 } 1169 ASSERT(i4_num_b_frames != -1); 1170 1171 return; 1172 } 1173 1174 /*! 1175 ************************************************************************ 1176 * \brief 1177 * assign pic type to input buf 1178 ************************************************************************ 1179 */ 1180 void ihevce_assign_pic_type(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_inp_buf) 1181 { 1182 WORD8 pic_type = ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr]; 1183 1184 switch(pic_type) 1185 { 1186 case PIC_TYPE_I: 1187 { 1188 ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_I_FRAME; 1189 ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0; 1190 ps_lap_inp_buf->s_lap_out.i4_is_I_in_any_field = 1; 1191 break; 1192 } 1193 case PIC_TYPE_P: 1194 { 1195 ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_P_FRAME; 1196 ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0; 1197 break; 1198 } 1199 case PIC_TYPE_B: 1200 { 1201 ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_B_FRAME; 1202 ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0; 1203 break; 1204 } 1205 case PIC_TYPE_IDR: 1206 { 1207 ps_lap_struct->i4_curr_poc = 0; 1208 ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_IDR_FRAME; 1209 ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0; 1210 break; 1211 } 1212 case PIC_TYPE_CRA: 1213 { 1214 ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_I_FRAME; 1215 ps_lap_inp_buf->s_lap_out.i4_is_I_in_any_field = 1; 1216 ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 1; 1217 break; 1218 } 1219 default: 1220 ASSERT(0); 1221 } 1222 return; 1223 } 1224 1225 /*! 1226 ************************************************************************ 1227 * \brief 1228 * capture order traversal nodes 1229 ************************************************************************ 1230 */ 1231 void ihevce_encode_order_traversal_nodes( 1232 ihevce_encode_node_t *encode_node_t, 1233 ihevce_lap_enc_buf_t **encode_order, 1234 WORD32 *loop_count, 1235 WORD32 curr_layer, 1236 lap_struct_t *ps_lap_struct) 1237 { 1238 if(encode_node_t == NULL) 1239 return; 1240 1241 encode_order[*loop_count] = (ihevce_lap_enc_buf_t *)encode_node_t->ps_lap_top_buff; 1242 1243 if(encode_order[*loop_count] != NULL) 1244 { 1245 ihevce_lap_enc_buf_t *ps_lap_inp; 1246 1247 ps_lap_struct->pi4_encode_poc_ptr[0] = encode_node_t->data; 1248 ref_b_pic_population(curr_layer, encode_order[*loop_count], ps_lap_struct); 1249 1250 ps_lap_inp = (ihevce_lap_enc_buf_t *)encode_order[*loop_count]; 1251 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out); 1252 1253 ps_lap_struct->pi4_encode_poc_ptr++; 1254 } 1255 1256 (*loop_count) = (*loop_count) + 1; 1257 1258 /* Pre-order Left-node traversal*/ 1259 ihevce_encode_order_traversal_nodes( 1260 (ihevce_encode_node_t *)encode_node_t->pv_left_node, 1261 encode_order, 1262 loop_count, 1263 curr_layer + 1, 1264 ps_lap_struct); 1265 1266 /* Pre-order Right-node traversal*/ 1267 ihevce_encode_order_traversal_nodes( 1268 (ihevce_encode_node_t *)encode_node_t->pv_right_node, 1269 encode_order, 1270 loop_count, 1271 curr_layer + 1, 1272 ps_lap_struct); 1273 } 1274 1275 /*! 1276 ************************************************************************ 1277 * \brief 1278 * capture order traversal nodes 1279 ************************************************************************ 1280 */ 1281 void ihevce_capture_order_traversal_nodes( 1282 ihevce_encode_node_t *encode_node_t, 1283 ihevce_lap_enc_buf_t **api4_capture_order_array, 1284 WORD32 *capture_order_poc_array, 1285 WORD32 *loop_count, 1286 WORD32 i4_interlace_field) 1287 { 1288 if(encode_node_t == NULL) 1289 return; 1290 1291 /* Inorder Insertion for the left-child node */ 1292 ihevce_capture_order_traversal_nodes( 1293 (ihevce_encode_node_t *)encode_node_t->pv_left_node, 1294 api4_capture_order_array, 1295 capture_order_poc_array, 1296 loop_count, 1297 i4_interlace_field); 1298 1299 if(i4_interlace_field) 1300 { 1301 encode_node_t->ps_lap_top_buff = 1302 (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count]; 1303 encode_node_t->data = capture_order_poc_array[*loop_count]; 1304 encode_node_t->ps_lap_bottom_buff = 1305 (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count + 1]; 1306 } 1307 else 1308 { 1309 encode_node_t->ps_lap_top_buff = 1310 (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count]; 1311 encode_node_t->data = capture_order_poc_array[*loop_count]; 1312 } 1313 if(i4_interlace_field) 1314 (*loop_count) = (*loop_count) + 2; 1315 else 1316 (*loop_count) = (*loop_count) + 1; 1317 1318 /* Inorder Insertion for the right-child node */ 1319 ihevce_capture_order_traversal_nodes( 1320 (ihevce_encode_node_t *)encode_node_t->pv_right_node, 1321 api4_capture_order_array, 1322 capture_order_poc_array, 1323 loop_count, 1324 i4_interlace_field); 1325 } 1326 1327 /*! 1328 ************************************************************************ 1329 * \brief 1330 * I/P pic population 1331 ************************************************************************ 1332 */ 1333 void ihevce_ip_pic_population( 1334 ihevce_encode_node_t *ps_encode_node, lap_struct_t *ps_lap_struct, WORD32 i4_first_gop) 1335 { 1336 ihevce_lap_enc_buf_t *ps_lap_inp = NULL; 1337 WORD32 hier_layer = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers; 1338 WORD32 sub_gop_size = ps_lap_struct->i4_dyn_sub_gop_size; 1339 ihevce_lap_enc_buf_t **api4_capture_order_array = ps_lap_struct->api4_capture_order_array; 1340 ihevce_lap_enc_buf_t **api4_encode_order_array = ps_lap_struct->api4_encode_order_array; 1341 WORD32 *ai4_capture_order_poc = ps_lap_struct->pi4_capture_poc_ptr; 1342 1343 /* Populate the encode order POC dependent on IDR frames and Interlace Field*/ 1344 if(1 == ps_lap_struct->i4_idr_flag) 1345 { 1346 if(i4_first_gop) 1347 { 1348 api4_encode_order_array[0] = api4_capture_order_array[0]; 1349 1350 if(api4_encode_order_array[0] != NULL) 1351 { 1352 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[0]; 1353 ref_pic_population(api4_encode_order_array[0], ps_lap_struct); 1354 1355 ps_lap_inp = api4_encode_order_array[0]; 1356 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out); 1357 1358 ps_lap_struct->pi4_encode_poc_ptr++; 1359 } 1360 1361 if(ps_lap_struct->i4_immediate_idr_case != 1) 1362 { 1363 api4_encode_order_array[1] = api4_capture_order_array[sub_gop_size]; 1364 1365 if(api4_encode_order_array[1] != NULL) 1366 { 1367 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size]; 1368 ref_pic_population(api4_encode_order_array[1], ps_lap_struct); 1369 1370 ps_lap_inp = api4_encode_order_array[1]; 1371 ihevce_rc_populate_common_params( 1372 &ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out); 1373 1374 ps_lap_struct->pi4_encode_poc_ptr++; 1375 } 1376 } 1377 } 1378 else 1379 { 1380 api4_encode_order_array[0] = api4_capture_order_array[sub_gop_size - 1]; 1381 1382 if(api4_encode_order_array[0] != NULL) 1383 { 1384 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size - 1]; 1385 ref_pic_population(api4_encode_order_array[0], ps_lap_struct); 1386 1387 ps_lap_inp = api4_encode_order_array[0]; 1388 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out); 1389 1390 ps_lap_struct->pi4_encode_poc_ptr++; 1391 } 1392 } 1393 } 1394 else 1395 { 1396 api4_encode_order_array[0] = api4_capture_order_array[sub_gop_size - 1]; 1397 1398 if(api4_encode_order_array[0] != NULL) 1399 { 1400 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size - 1]; 1401 ref_pic_population(api4_encode_order_array[0], ps_lap_struct); 1402 1403 ps_lap_inp = api4_encode_order_array[0]; 1404 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out); 1405 1406 ps_lap_struct->pi4_encode_poc_ptr++; 1407 } 1408 } 1409 return; 1410 } 1411 1412 /*! 1413 ************************************************************************ 1414 * \brief 1415 * B pic population 1416 ************************************************************************ 1417 */ 1418 void ihevce_b_pic_population(ihevce_encode_node_t *ps_encode_node, lap_struct_t *ps_lap_struct) 1419 { 1420 WORD32 interlace_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field; 1421 ihevce_lap_enc_buf_t **api4_encode_order_array = ps_lap_struct->api4_encode_order_array; 1422 WORD32 *capture_order_poc_array = ps_lap_struct->pi4_capture_poc_ptr; 1423 WORD32 loop_count = 0; 1424 1425 /* encoder_order offset changed dependent on IDR and Interlace Field */ 1426 if(ps_lap_struct->i4_idr_flag) 1427 loop_count = 1 + interlace_field; 1428 1429 /* Inorder Insertion of POC in tree, for capture order */ 1430 ihevce_capture_order_traversal_nodes( 1431 ps_encode_node, 1432 &ps_lap_struct->api4_capture_order_array[0], 1433 capture_order_poc_array, 1434 &loop_count, 1435 interlace_field); 1436 1437 /* encoder_order offset changed dependent on IDR and Interlace Field */ 1438 /* If the gop_size is multiple of CRA period , decrement loop count */ 1439 if(ps_lap_struct->i4_idr_flag) 1440 loop_count = 2 + (interlace_field * 2); 1441 else 1442 loop_count = 1 + interlace_field; 1443 1444 /* Pre-order traversal of the tree to get encode-order POCs*/ 1445 ihevce_encode_order_traversal_nodes( 1446 ps_encode_node, api4_encode_order_array, &loop_count, 1, ps_lap_struct); 1447 1448 return; 1449 } 1450 1451 /*! 1452 ************************************************************************ 1453 * \brief 1454 * rc_update_model_control_by_lap_for_modified_sub_gop 1455 ************************************************************************ 1456 */ 1457 void rc_update_model_control_by_lap_for_modified_sub_gop( 1458 lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf) 1459 { 1460 ihevce_lap_output_params_t *ps_lap_out = &ps_lap_out_buf->s_lap_out; 1461 1462 /* model update flag for rc*/ 1463 if(ps_lap_out->i4_pic_type == IV_P_FRAME) 1464 { 1465 WORD32 i4_loop = 0; 1466 WORD32 i4_min_delta_poc = 0x7FFFFFFF; 1467 1468 for(i4_loop = 0; i4_loop < ps_lap_out->i4_num_ref_pics; i4_loop++) 1469 { 1470 if(i4_min_delta_poc > ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc)) 1471 { 1472 i4_min_delta_poc = ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc); 1473 } 1474 } 1475 } 1476 1477 if(ps_lap_out->i4_pic_type == IV_B_FRAME) 1478 { 1479 WORD32 i4_loop = 0; 1480 WORD32 i4_min_delta_poc = 0x7FFFFFFF; 1481 WORD32 i4_min_delta_poc_for_b = 1482 (1 << ps_lap_struct->s_lap_static_params.i4_max_temporal_layers) / 1483 (ps_lap_out->i4_temporal_lyr_id + 1); 1484 1485 for(i4_loop = 0; i4_loop < ps_lap_out->i4_num_ref_pics; i4_loop++) 1486 { 1487 if(i4_min_delta_poc > ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc)) 1488 { 1489 i4_min_delta_poc = ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc); 1490 } 1491 } 1492 } 1493 return; 1494 } 1495 1496 /*! 1497 ************************************************************************ 1498 * \brief 1499 * Update num of pic type for rc 1500 ************************************************************************ 1501 */ 1502 void update_rc_num_pic_type(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf) 1503 { 1504 WORD32 i4_field_flag = ps_lap_struct->s_lap_static_params.i4_src_interlace_field; 1505 rc_lap_out_params_t *ps_rc_lap_out = &ps_lap_out_buf->s_rc_lap_out; 1506 1507 ps_lap_struct->i4_lap2_counter++; 1508 1509 if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_I_FRAME || 1510 ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME) 1511 { 1512 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = I_PIC; 1513 GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD); 1514 } 1515 else if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_P_FRAME) 1516 { 1517 if(ps_lap_out_buf->s_lap_out.i4_first_field) 1518 { 1519 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = P_PIC; 1520 } 1521 else 1522 { 1523 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = P1_PIC; 1524 } 1525 GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD); 1526 } 1527 else if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_B_FRAME) 1528 { 1529 if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 1) 1530 { 1531 if(ps_lap_out_buf->s_lap_out.i4_first_field) 1532 { 1533 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B_PIC; 1534 } 1535 else 1536 { 1537 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = BB_PIC; 1538 } 1539 GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD); 1540 } 1541 else if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 2) 1542 { 1543 if(ps_lap_out_buf->s_lap_out.i4_first_field) 1544 { 1545 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B1_PIC; 1546 } 1547 else 1548 { 1549 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B11_PIC; 1550 } 1551 GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD); 1552 } 1553 else if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 3) 1554 { 1555 if(ps_lap_out_buf->s_lap_out.i4_first_field) 1556 { 1557 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B2_PIC; 1558 } 1559 else 1560 { 1561 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B22_PIC; 1562 } 1563 GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD); 1564 } 1565 else 1566 { 1567 ASSERT(0); 1568 } 1569 } 1570 else 1571 { 1572 ASSERT(0); 1573 } 1574 1575 if(!ps_lap_struct->i4_rc_lap_period) 1576 { 1577 if(ps_lap_struct->i4_rc_lap_period < ps_lap_struct->i4_gop_period) 1578 { 1579 WORD32 i4_loop; 1580 WORD32 idx = 0; 1581 WORD32 i4_max_temporal_layer = 1582 ps_lap_struct->s_lap_static_params.i4_max_temporal_layers; 1583 1584 for(i4_loop = 0; 1585 i4_loop < (ps_lap_struct->i4_gop_period - ps_lap_struct->i4_rc_lap_period); 1586 i4_loop++) 1587 { 1588 ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++; 1589 1590 if(i4_max_temporal_layer == 0) 1591 { 1592 if(ps_lap_struct->i4_is_all_i_pic_in_seq) 1593 { 1594 ps_rc_lap_out->ai4_num_pic_type[I_PIC]++; 1595 } 1596 else 1597 { 1598 /*second field*/ 1599 if((i4_loop & 1) && i4_field_flag) 1600 { 1601 ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++; 1602 } 1603 else 1604 { 1605 ps_rc_lap_out->ai4_num_pic_type[P_PIC]++; 1606 } 1607 } 1608 } 1609 else 1610 { 1611 ps_rc_lap_out->ai4_num_pic_type 1612 [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++; 1613 1614 GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag)); 1615 } 1616 } 1617 } 1618 } 1619 else 1620 { 1621 ASSERT(ps_lap_struct->i4_lap2_counter <= ps_lap_struct->i4_rc_lap_period); 1622 1623 if(ps_lap_struct->i4_lap2_counter == ps_lap_struct->i4_rc_lap_period) 1624 { 1625 WORD32 i4_loop, i4_period, i4_next_i_pic = 0; 1626 WORD32 i4_stop_count = 0; 1627 WORD32 i4_temp_deq = ps_lap_struct->i4_deq_idx; 1628 WORD32 i4_first_pic_type = ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq]; 1629 1630 if(ps_lap_struct->i4_rc_lap_period >= ps_lap_struct->i4_gop_period) 1631 { 1632 i4_period = ps_lap_struct->i4_gop_period; 1633 } 1634 else 1635 { 1636 i4_period = ps_lap_struct->i4_rc_lap_period; 1637 } 1638 1639 for(i4_loop = 0; i4_loop < i4_period; i4_loop++) 1640 { 1641 if(ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq] == I_PIC && i4_loop && 1642 i4_first_pic_type == I_PIC) 1643 { 1644 i4_stop_count = 1; 1645 } 1646 1647 if(!i4_stop_count) 1648 { 1649 ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++; 1650 } 1651 1652 ps_rc_lap_out 1653 ->ai4_num_pic_type[ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq]]++; 1654 1655 GET_IDX_CIRCULAR_BUF(i4_temp_deq, 1, NUM_LAP2_LOOK_AHEAD); 1656 } 1657 if(ps_lap_struct->i4_rc_lap_period < ps_lap_struct->i4_gop_period) 1658 { 1659 WORD32 i4_loop; 1660 WORD32 idx = 0; 1661 WORD32 i4_max_temporal_layer = 1662 ps_lap_struct->s_lap_static_params.i4_max_temporal_layers; 1663 1664 for(i4_loop = 0; 1665 i4_loop < (ps_lap_struct->i4_gop_period - ps_lap_struct->i4_rc_lap_period) && 1666 (!i4_next_i_pic); 1667 i4_loop++) 1668 { 1669 if(!i4_stop_count) 1670 { 1671 ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++; 1672 } 1673 1674 if(i4_max_temporal_layer == 0) 1675 { 1676 if(ps_lap_struct->i4_is_all_i_pic_in_seq) 1677 { 1678 ps_rc_lap_out->ai4_num_pic_type[I_PIC]++; 1679 } 1680 else 1681 { 1682 /*second field*/ 1683 if((i4_loop & 1) && i4_field_flag) 1684 { 1685 ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++; 1686 } 1687 else 1688 { 1689 ps_rc_lap_out->ai4_num_pic_type[P_PIC]++; 1690 } 1691 } 1692 } 1693 else 1694 { 1695 ps_rc_lap_out->ai4_num_pic_type 1696 [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++; 1697 GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag)); 1698 } 1699 } 1700 } 1701 /*remove one pic type*/ 1702 GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_deq_idx, 1, NUM_LAP2_LOOK_AHEAD); 1703 ps_lap_struct->i4_lap2_counter--; 1704 } 1705 } 1706 1707 { 1708 WORD32 i4_loop; 1709 WORD32 idx = 0; 1710 WORD32 i4_max_temporal_layer = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers; 1711 WORD32 i4_num_pictype = 0; 1712 1713 for(i4_loop = 0; i4_loop < MAX_PIC_TYPE; i4_loop++) 1714 { 1715 i4_num_pictype += ps_rc_lap_out->ai4_num_pic_type[i4_loop]; 1716 } 1717 1718 if(!i4_num_pictype) 1719 { 1720 ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead = ps_lap_struct->i4_gop_period; 1721 1722 for(i4_loop = 0; i4_loop < (ps_lap_struct->i4_gop_period); i4_loop++) 1723 { 1724 if(i4_max_temporal_layer == 0) 1725 { 1726 if(ps_lap_struct->i4_is_all_i_pic_in_seq) 1727 { 1728 ps_rc_lap_out->ai4_num_pic_type[I_PIC]++; 1729 } 1730 else 1731 { 1732 /*second field*/ 1733 if((i4_loop & 1) && i4_field_flag) 1734 { 1735 ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++; 1736 } 1737 else 1738 { 1739 ps_rc_lap_out->ai4_num_pic_type[P_PIC]++; 1740 } 1741 } 1742 } 1743 else 1744 { 1745 ps_rc_lap_out->ai4_num_pic_type 1746 [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++; 1747 1748 GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag)); 1749 } 1750 } 1751 } 1752 } 1753 /*FOR RC : ensure at least 1 I pic in the gop period at any case*/ 1754 if(!ps_rc_lap_out->ai4_num_pic_type[I_PIC]) 1755 { 1756 ASSERT(ps_rc_lap_out->ai4_num_pic_type[P_PIC]); 1757 ps_lap_out_buf->s_rc_lap_out.ai4_num_pic_type[P_PIC]--; 1758 ps_lap_out_buf->s_rc_lap_out.ai4_num_pic_type[I_PIC]++; 1759 } 1760 return; 1761 } 1762 1763 /*! 1764 ************************************************************************ 1765 * \brief 1766 * pre rel lap output update 1767 ************************************************************************ 1768 */ 1769 void ihevce_pre_rel_lapout_update(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf) 1770 { 1771 WORD32 i4_first_field = 1; 1772 WORD32 i4_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field; 1773 1774 if(i4_field) 1775 { 1776 i4_first_field = ps_lap_out_buf->s_lap_out.i4_first_field; 1777 } 1778 1779 ps_lap_out_buf->s_lap_out.i4_used = 0; 1780 1781 rc_update_model_control_by_lap_for_modified_sub_gop(ps_lap_struct, ps_lap_out_buf); 1782 update_rc_num_pic_type(ps_lap_struct, ps_lap_out_buf); 1783 1784 /* curr buf next is null, prev buf next is curr and prev buff equal to curr*/ 1785 1786 ps_lap_out_buf->s_rc_lap_out.ps_rc_lap_out_next_encode = NULL; 1787 if(ps_lap_struct->pv_prev_inp_buf != NULL && 1788 ps_lap_struct->s_lap_static_params.s_lap_params.i4_rc_look_ahead_pics) 1789 { 1790 ((ihevce_lap_enc_buf_t *)ps_lap_struct->pv_prev_inp_buf) 1791 ->s_rc_lap_out.ps_rc_lap_out_next_encode = (void *)&ps_lap_out_buf->s_rc_lap_out; 1792 } 1793 1794 ps_lap_struct->pv_prev_inp_buf = (void *)ps_lap_out_buf; 1795 ps_lap_out_buf->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene = 0; 1796 1797 /*with force idr below check is not valid*/ 1798 #if(!FORCE_IDR_TEST) 1799 if(ps_lap_struct->i4_max_idr_period == ps_lap_struct->i4_min_idr_period) 1800 { 1801 if(!ps_lap_out_buf->s_lap_out.i4_poc) 1802 { 1803 ASSERT(ps_lap_struct->i4_max_prev_poc == (ps_lap_struct->i4_max_idr_period - 1)); 1804 ps_lap_struct->i4_max_prev_poc = 0; 1805 } 1806 } 1807 #endif 1808 1809 /*assert if num of reference frame is zero in case of P or B frame*/ 1810 if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_P_FRAME || 1811 ps_lap_out_buf->s_lap_out.i4_pic_type == IV_B_FRAME) 1812 { 1813 ASSERT(ps_lap_out_buf->s_lap_out.i4_num_ref_pics != 0); 1814 } 1815 1816 /*assert if poc = 0 and pictype is not an idr*/ 1817 if(ps_lap_out_buf->s_lap_out.i4_pic_type != IV_IDR_FRAME && 1818 ps_lap_out_buf->s_lap_out.i4_poc == 0) 1819 { 1820 ASSERT(0); 1821 } 1822 if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME && 1823 ps_lap_out_buf->s_lap_out.i4_poc != 0) 1824 { 1825 ASSERT(0); 1826 } 1827 if(ps_lap_out_buf->s_lap_out.i4_poc < 0) 1828 { 1829 ASSERT(0); 1830 } 1831 1832 #if(!FORCE_IDR_TEST) 1833 if((!ps_lap_struct->i4_max_idr_period) && ps_lap_out_buf->s_lap_out.i4_display_num != 0) 1834 { 1835 ASSERT(ps_lap_out_buf->s_lap_out.i4_pic_type != IV_IDR_FRAME); 1836 } 1837 #endif 1838 if(!ps_lap_struct->i4_max_cra_period) 1839 { 1840 ASSERT(ps_lap_out_buf->s_lap_out.i4_is_cra_pic != 1); 1841 } 1842 1843 if(ps_lap_out_buf->s_lap_out.i4_force_idr_flag) 1844 { 1845 ASSERT(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME); 1846 } 1847 ps_lap_out_buf->s_lap_out.i4_curr_frm_qp = -1; 1848 } 1849 1850 /*! 1851 ************************************************************************ 1852 * \brief 1853 * lap queue input 1854 ************************************************************************ 1855 */ 1856 void ihevce_lap_queue_input( 1857 lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_input_lap_enc_buf, WORD32 *pi4_tree_num) 1858 { 1859 ihevce_encode_node_t *ps_encode_node = 1860 (ihevce_encode_node_t *)ps_lap_struct->aps_encode_node[*pi4_tree_num]; 1861 1862 WORD32 i4_capture_idx = ps_lap_struct->i4_capture_idx; 1863 1864 /* Static Lap parameters */ 1865 ihevce_lap_static_params_t *ps_lap_static_params = 1866 (ihevce_lap_static_params_t *)&ps_lap_struct->s_lap_static_params; 1867 1868 WORD32 hier_layer = ps_lap_static_params->i4_max_temporal_layers; 1869 WORD32 sub_gop_size = ps_lap_struct->i4_dyn_sub_gop_size; 1870 1871 /* queue the current input in capture array */ 1872 { 1873 WORD32 first_gop_flag; 1874 1875 if(!i4_capture_idx) 1876 { 1877 memset( 1878 &ps_lap_struct->api4_capture_order_array[0], 1879 0, 1880 sizeof(ihevce_lap_enc_buf_t *) * MAX_NUM_ENC_NODES); 1881 } 1882 ps_lap_struct->api4_capture_order_array[i4_capture_idx] = ps_input_lap_enc_buf; 1883 1884 if(ps_input_lap_enc_buf != NULL) 1885 { 1886 if(ps_input_lap_enc_buf->s_lap_out.i4_end_flag == 1) 1887 ps_lap_struct->i4_end_flag_pic_idx = i4_capture_idx; 1888 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx] = ps_lap_struct->i4_curr_poc++; 1889 } 1890 i4_capture_idx++; 1891 1892 /* to take care of buffering 1 extra picture at start or at IDR interval*/ 1893 if(!ps_lap_struct->i4_is_all_i_pic_in_seq) 1894 { 1895 if(ps_lap_static_params->i4_src_interlace_field && sub_gop_size <= 2) 1896 { 1897 first_gop_flag = 0; 1898 } 1899 else 1900 { 1901 first_gop_flag = ps_lap_struct->i4_idr_flag 1902 << ps_lap_static_params->i4_src_interlace_field; 1903 } 1904 } 1905 else 1906 { 1907 first_gop_flag = ps_lap_struct->i4_idr_flag; 1908 } 1909 1910 /* For every IDR period, set idr_flag and reset POC value and gop_size to 0*/ 1911 if(ps_input_lap_enc_buf != NULL) 1912 { 1913 if((!first_gop_flag) && (ps_input_lap_enc_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME)) 1914 { 1915 ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0]; 1916 ps_lap_struct->i4_idr_flag = 1; 1917 ps_lap_struct->i4_curr_poc = 0; 1918 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 1] = 1919 ps_lap_struct->i4_curr_poc++; 1920 } 1921 } 1922 1923 if(first_gop_flag && 1924 (ps_lap_struct->i4_is_all_i_pic_in_seq || ps_lap_struct->i4_immediate_idr_case)) 1925 { 1926 sub_gop_size = 0; 1927 } 1928 1929 if(!first_gop_flag && ps_lap_struct->i4_immediate_idr_case && 1930 (i4_capture_idx != (sub_gop_size + first_gop_flag))) 1931 { 1932 sub_gop_size = 1 << ps_lap_static_params->i4_src_interlace_field; 1933 ps_lap_struct->i4_dyn_sub_gop_size = 1 << ps_lap_static_params->i4_src_interlace_field; 1934 } 1935 1936 /* reset the queue idx end of every gop */ 1937 if(i4_capture_idx == (sub_gop_size + first_gop_flag)) 1938 { 1939 if(ps_lap_struct->i4_end_flag_pic_idx) 1940 { 1941 WORD32 i4_temp_poc = 0; 1942 ihevce_lap_enc_buf_t *ps_temp_lap_enc_buf = NULL; 1943 1944 /*swap the lap enc buf and poc*/ 1945 ps_temp_lap_enc_buf = 1946 ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx - 1]; 1947 ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx - 1] = 1948 NULL; 1949 ps_lap_struct->api4_capture_order_array[i4_capture_idx - 2] = 1950 ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx]; 1951 1952 if((i4_capture_idx - 2) != ps_lap_struct->i4_end_flag_pic_idx) 1953 ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx] = 1954 NULL; 1955 1956 ps_temp_lap_enc_buf->s_lap_out.i4_pic_type = IV_P_FRAME; 1957 ps_lap_struct->api4_capture_order_array[i4_capture_idx - 1] = ps_temp_lap_enc_buf; 1958 1959 i4_temp_poc = 1960 ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_end_flag_pic_idx - 1]; 1961 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 2] = 1962 ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_end_flag_pic_idx]; 1963 1964 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 1] = i4_temp_poc; 1965 } 1966 i4_capture_idx = 0; 1967 1968 /* add the number of pics in sub gop to the gop counter */ 1969 /* Get reordered Buffer for encoder, wait till all sub-gop buffers are output */ 1970 1971 /* Popluate I/P pictures */ 1972 ihevce_ip_pic_population(ps_encode_node, ps_lap_struct, first_gop_flag); 1973 1974 /* For hierarchical layers, Populate B picture */ 1975 if((hier_layer > 0) && 1976 sub_gop_size > (1 << ps_lap_static_params->i4_src_interlace_field)) 1977 { 1978 ihevce_b_pic_population(ps_encode_node, ps_lap_struct); 1979 } 1980 1981 ps_lap_struct->i4_num_bufs_encode_order = sub_gop_size + first_gop_flag; 1982 1983 /* correction of encode order in case of multiple non reference B*/ 1984 if(ps_lap_struct->i4_dyn_sub_gop_size > ps_lap_struct->i4_sub_gop_size) 1985 { 1986 WORD32 i4_loop; 1987 ihevce_lap_enc_buf_t *ps_lap_enc_buf, *ps_lap_enc_buf_tmp[MAX_NUM_ENC_NODES]; 1988 WORD32 i4_enc_cnt, i4_cap_cnt; 1989 1990 i4_cap_cnt = first_gop_flag; 1991 i4_enc_cnt = 0; 1992 1993 for(i4_loop = 0; i4_loop < ps_lap_struct->i4_num_bufs_encode_order; i4_loop++) 1994 { 1995 ps_lap_enc_buf = ps_lap_struct->api4_encode_order_array[i4_loop]; 1996 1997 if(ps_lap_enc_buf != NULL && !ps_lap_enc_buf->s_lap_out.i4_is_ref_pic && 1998 (ps_lap_enc_buf->s_lap_out.i4_temporal_lyr_id == 1999 ps_lap_struct->s_lap_static_params.i4_max_temporal_layers)) 2000 { 2001 if(ps_lap_enc_buf != ps_lap_struct->api4_capture_order_array[i4_cap_cnt]) 2002 { 2003 ps_lap_enc_buf_tmp[i4_enc_cnt] = 2004 ps_lap_struct->api4_capture_order_array[i4_cap_cnt]; 2005 i4_enc_cnt++; 2006 i4_loop++; 2007 } 2008 i4_cap_cnt += 2; 2009 ps_lap_enc_buf_tmp[i4_enc_cnt] = ps_lap_enc_buf; 2010 i4_enc_cnt++; 2011 ps_lap_enc_buf_tmp[i4_enc_cnt] = 2012 ps_lap_struct->api4_capture_order_array[i4_cap_cnt]; 2013 i4_enc_cnt++; 2014 i4_cap_cnt += 2; 2015 i4_loop++; 2016 } 2017 else 2018 { 2019 ps_lap_enc_buf_tmp[i4_enc_cnt] = ps_lap_enc_buf; 2020 i4_enc_cnt++; 2021 } 2022 } 2023 for(i4_loop = 0; i4_loop < ps_lap_struct->i4_num_bufs_encode_order; i4_loop++) 2024 { 2025 ps_lap_struct->api4_encode_order_array[i4_loop] = ps_lap_enc_buf_tmp[i4_loop]; 2026 } 2027 } 2028 2029 /* reset the IDR flag */ 2030 ps_lap_struct->i4_idr_flag = 0; 2031 ps_lap_struct->i4_dyn_sub_gop_size = ps_lap_struct->i4_sub_gop_size; 2032 } 2033 2034 if(0 == ps_lap_struct->i4_lap_out_idx) 2035 ps_lap_struct->i4_max_buf_in_enc_order = ps_lap_struct->i4_num_bufs_encode_order; 2036 2037 /* store the capture index */ 2038 ps_lap_struct->i4_capture_idx = i4_capture_idx; 2039 ps_lap_struct->i4_immediate_idr_case = 0; 2040 } 2041 return; 2042 } 2043 2044 /*! 2045 ************************************************************************ 2046 * \brief 2047 * lap process 2048 ************************************************************************ 2049 */ 2050 ihevce_lap_enc_buf_t *ihevce_lap_process(void *pv_interface_ctxt, ihevce_lap_enc_buf_t *ps_curr_inp) 2051 { 2052 lap_intface_t *ps_lap_interface = (lap_intface_t *)pv_interface_ctxt; 2053 lap_struct_t *ps_lap_struct = (lap_struct_t *)ps_lap_interface->pv_lap_module_ctxt; 2054 ihevce_hle_ctxt_t *ps_hle_ctxt = (ihevce_hle_ctxt_t *)ps_lap_interface->pv_hle_ctxt; 2055 ihevce_lap_enc_buf_t *ps_lap_inp_buf = ps_curr_inp; 2056 ihevce_tgt_params_t *ps_tgt_params = 2057 &ps_lap_struct->s_static_cfg_params.s_tgt_lyr_prms.as_tgt_params[0]; 2058 WORD32 i4_field_flag = ps_lap_struct->s_lap_static_params.i4_src_interlace_field; 2059 WORD32 i4_num_frames_after_force_idr = ps_lap_struct->i4_num_frames_after_force_idr; 2060 WORD32 i4_flush_check = 0; 2061 WORD32 i4_force_idr_check = 0; 2062 WORD32 i4_set_res_check = 0; 2063 WORD32 i4_tree_num = 0; 2064 iv_input_ctrl_buffs_t *ps_ctrl_buf = NULL; 2065 WORD32 buf_id = 0; 2066 2067 ps_lap_interface->i4_ctrl_in_que_blocking_mode = BUFF_QUE_NON_BLOCKING_MODE; 2068 2069 /* ----------- LAP processing ----------- */ 2070 if(ps_lap_struct->end_flag != 1) 2071 { 2072 ASSERT(NULL != ps_curr_inp); 2073 2074 /* ---------- get the filled control command buffer ------------ */ 2075 ps_ctrl_buf = (iv_input_ctrl_buffs_t *)ihevce_q_get_filled_buff( 2076 ps_hle_ctxt->apv_enc_hdl[0], 2077 ps_lap_interface->i4_ctrl_in_que_id, 2078 &buf_id, 2079 ps_lap_interface->i4_ctrl_in_que_blocking_mode); 2080 2081 /* ----------- check the command ---------------------- */ 2082 if(NULL != ps_ctrl_buf) 2083 { 2084 /* check for async errors */ 2085 ihevce_dyn_config_prms_t as_dyn_br[MAX_NUM_DYN_BITRATE_CMDS]; 2086 WORD32 i4_num_set_bitrate_cmds = 0; 2087 WORD32 bitrt_ctr = 0; 2088 2089 ihevce_lap_parse_async_cmd( 2090 ps_hle_ctxt, 2091 (WORD32 *)ps_ctrl_buf->pv_asynch_ctrl_bufs, 2092 ps_ctrl_buf->i4_cmd_buf_size, 2093 ps_ctrl_buf->i4_buf_id, 2094 &i4_num_set_bitrate_cmds, 2095 &as_dyn_br[0]); 2096 2097 /* Call the call back function to register the new bitrate */ 2098 for(bitrt_ctr = 0; bitrt_ctr < i4_num_set_bitrate_cmds; bitrt_ctr++) 2099 { 2100 ps_lap_interface->ihevce_dyn_bitrate_cb( 2101 (void *)ps_hle_ctxt, (void *)&as_dyn_br[bitrt_ctr]); 2102 } 2103 } 2104 2105 { 2106 WORD32 *pi4_cmd_buf = (WORD32 *)ps_lap_inp_buf->s_input_buf.pv_synch_ctrl_bufs; 2107 2108 /* check for sync cmd buffer error */ 2109 /* check FLUSH comand and Force IDR in the complete buffer */ 2110 i4_flush_check = 0; 2111 i4_force_idr_check = 0; 2112 i4_set_res_check = 0; 2113 ihevce_lap_parse_sync_cmd( 2114 ps_hle_ctxt, 2115 &ps_lap_struct->s_static_cfg_params, 2116 pi4_cmd_buf, 2117 ps_lap_inp_buf, 2118 &i4_flush_check, 2119 &i4_force_idr_check, 2120 &i4_set_res_check, 2121 &i4_num_frames_after_force_idr); 2122 2123 if(i4_flush_check) 2124 ps_lap_struct->end_flag = 1; 2125 2126 ps_lap_inp_buf->s_lap_out.i4_out_flush_flag = 0; 2127 ps_lap_inp_buf->s_lap_out.i4_end_flag = ps_lap_struct->end_flag; 2128 2129 /* check if input buffer is a valid buffer */ 2130 if(1 == ps_lap_inp_buf->s_input_buf.i4_inp_frm_data_valid_flag) 2131 { 2132 /* Initialise laps input buffer descriptors */ 2133 memset(&ps_lap_inp_buf->s_lap_out, 0, sizeof(ihevce_lap_output_params_t)); 2134 memset(&ps_lap_inp_buf->s_rc_lap_out, 0, sizeof(rc_lap_out_params_t)); 2135 /* Default initialization of lapout parameters */ 2136 ps_lap_inp_buf->s_lap_out.i4_scene_type = SCENE_TYPE_NORMAL; 2137 ps_lap_inp_buf->s_lap_out.u4_scene_num = 0; 2138 ps_lap_inp_buf->s_lap_out.i4_display_num = ps_lap_struct->i4_display_num; 2139 ps_lap_inp_buf->s_lap_out.i4_quality_preset = ps_tgt_params->i4_quality_preset; 2140 ps_lap_inp_buf->s_lap_out.i1_weighted_pred_flag = 0; 2141 ps_lap_inp_buf->s_lap_out.i1_weighted_bipred_flag = 0; 2142 ps_lap_inp_buf->s_lap_out.i4_log2_luma_wght_denom = DENOM_DEFAULT; 2143 ps_lap_inp_buf->s_lap_out.i4_log2_chroma_wght_denom = DENOM_DEFAULT; 2144 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].i4_num_duplicate_entries_in_ref_list = 1; 2145 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].i4_used_by_cur_pic_flag = 1; 2146 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].as_wght_off[0].u1_luma_weight_enable_flag = 2147 0; 2148 ps_lap_inp_buf->s_lap_out.as_ref_pics[0] 2149 .as_wght_off[0] 2150 .u1_chroma_weight_enable_flag = 0; 2151 ps_lap_inp_buf->s_lap_out.i4_first_field = 1; 2152 ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 0; 2153 ps_lap_inp_buf->s_lap_out.i4_curr_frm_qp = ps_tgt_params->ai4_frame_qp[0]; 2154 ps_lap_inp_buf->s_lap_out.i4_used = 1; 2155 if(i4_force_idr_check) 2156 { 2157 ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 1; 2158 } 2159 ASSERT(i4_set_res_check == 0); 2160 2161 /* Populate input params in lap out struct */ 2162 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_y_buf = 2163 ps_lap_inp_buf->s_input_buf.s_input_buf.pv_y_buf; 2164 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_u_buf = 2165 ps_lap_inp_buf->s_input_buf.s_input_buf.pv_u_buf; 2166 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_v_buf = 2167 ps_lap_inp_buf->s_input_buf.s_input_buf.pv_v_buf; 2168 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_wd = 2169 ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_wd; 2170 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_ht = 2171 ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_ht; 2172 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_strd = 2173 ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_strd; 2174 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_wd = 2175 ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_wd; 2176 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_ht = 2177 ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_ht; 2178 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_strd = 2179 ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_strd; 2180 2181 ps_lap_struct->i4_display_num++; 2182 i4_num_frames_after_force_idr++; 2183 2184 ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_enq_idx] = ps_lap_inp_buf; 2185 /* update first field flag */ 2186 ps_lap_inp_buf->s_lap_out.i4_first_field = 1; 2187 if(i4_field_flag) 2188 { 2189 ps_lap_inp_buf->s_lap_out.i4_first_field = 2190 (ps_lap_inp_buf->s_input_buf.i4_topfield_first ^ 2191 ps_lap_inp_buf->s_input_buf.i4_bottom_field); 2192 } 2193 2194 /* force idr in case interlace input can be taken only for first field */ 2195 if(!ps_lap_inp_buf->s_lap_out.i4_first_field) 2196 { 2197 ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 0; 2198 } 2199 2200 /*to be filed*/ 2201 if(0 == 2202 ps_lap_struct->i4_num_frm_type_decided /*&& ps_lap_struct->i4_init_delay_over*/) 2203 { 2204 ps_lap_struct->ai1_pic_type[0] = 2205 ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr]; 2206 2207 ihevce_determine_next_sub_gop_state(ps_lap_struct); 2208 2209 ps_lap_struct->i4_next_start_ctr = 0; 2210 } 2211 2212 if(/*ps_lap_struct->i4_init_delay_over &&*/ 0 != 2213 ps_lap_struct->i4_num_frm_type_decided) 2214 { 2215 ihevce_assign_pic_type( 2216 ps_lap_struct, 2217 ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]); 2218 2219 ps_lap_struct->i4_num_frm_type_decided--; 2220 2221 if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]) 2222 { 2223 /*special case of two consequetive idr at the start of encode or due to force idr*/ 2224 ps_lap_struct->i4_immediate_idr_case = 2225 ps_lap_struct->i4_is_all_i_pic_in_seq; 2226 if(ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx] 2227 ->s_lap_out.i4_pic_type == IV_IDR_FRAME) 2228 { 2229 ps_lap_struct->i4_immediate_idr_case = 1; 2230 } 2231 else 2232 { 2233 WORD32 i4_prev_idx = ps_lap_struct->i4_buf_deq_idx > 0 2234 ? ps_lap_struct->i4_buf_deq_idx - 1 2235 : ps_lap_struct->i4_buf_deq_idx; 2236 /*field case of single IDR field followed by P*/ 2237 if(NULL != ps_lap_struct->aps_lap_inp_buf[i4_prev_idx] && 2238 i4_field_flag && 2239 ps_lap_struct->aps_lap_inp_buf[i4_prev_idx]->s_lap_out.i4_pic_type == 2240 IV_IDR_FRAME && 2241 !ps_lap_struct->i4_num_frm_type_decided) 2242 { 2243 ps_lap_struct->i4_immediate_idr_case = 1; 2244 } 2245 } 2246 } 2247 2248 /* Queue in the current input Buffer to LAP que */ 2249 ihevce_lap_queue_input( 2250 ps_lap_struct, 2251 ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx], 2252 &i4_tree_num); 2253 2254 ps_lap_struct->i4_next_start_ctr++; 2255 ps_lap_struct->i4_buf_deq_idx++; 2256 if(ps_lap_struct->i4_buf_deq_idx >= MAX_QUEUE_LENGTH) 2257 ps_lap_struct->i4_buf_deq_idx = 0; 2258 } 2259 2260 ps_lap_struct->i4_buf_enq_idx++; 2261 if(ps_lap_struct->i4_buf_enq_idx >= MAX_QUEUE_LENGTH) 2262 ps_lap_struct->i4_buf_enq_idx = 0; 2263 } /* end if for valid input buffer check*/ 2264 } 2265 2266 /* source pixel padding if width/height is not aligned to 8 pixel */ 2267 if(ps_lap_inp_buf->s_input_buf.i4_inp_frm_data_valid_flag) 2268 { 2269 ihevce_src_params_t *ps_src_prms = &ps_lap_struct->s_static_cfg_params.s_src_prms; 2270 WORD32 i4_align_wd = ps_src_prms->i4_width; 2271 WORD32 i4_align_ht = ps_src_prms->i4_height; 2272 WORD32 min_cu_size = 2273 (1 << ps_lap_struct->s_static_cfg_params.s_config_prms.i4_min_log2_cu_size); 2274 2275 i4_align_wd += SET_CTB_ALIGN(ps_src_prms->i4_width, min_cu_size); 2276 i4_align_ht += SET_CTB_ALIGN(ps_src_prms->i4_height, min_cu_size); 2277 2278 ihevce_lap_pad_input_bufs(ps_lap_inp_buf, i4_align_wd, i4_align_ht); 2279 } 2280 { 2281 ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_width = 0; 2282 ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_height = 0; 2283 ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_x_offset = 0; 2284 ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_y_offset = 0; 2285 } 2286 } 2287 2288 if(ps_lap_struct->end_flag == 1) 2289 { 2290 ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_enq_idx] = ps_lap_inp_buf; 2291 2292 /*to be filed*/ 2293 if(0 == ps_lap_struct->i4_num_frm_type_decided) 2294 { 2295 ps_lap_struct->ai1_pic_type[0] = 2296 ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr]; 2297 2298 ihevce_determine_next_sub_gop_state(ps_lap_struct); 2299 2300 ps_lap_struct->i4_next_start_ctr = 0; 2301 } 2302 2303 if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]) 2304 { 2305 ihevce_assign_pic_type( 2306 ps_lap_struct, ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]); 2307 } 2308 2309 ps_lap_struct->i4_num_frm_type_decided--; 2310 2311 if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]) 2312 { 2313 /*special case of two consequetive idr at the start of encode or due to force idr*/ 2314 ps_lap_struct->i4_immediate_idr_case = ps_lap_struct->i4_is_all_i_pic_in_seq; 2315 2316 if(ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx] 2317 ->s_lap_out.i4_pic_type == IV_IDR_FRAME) 2318 { 2319 ps_lap_struct->i4_immediate_idr_case = 1; 2320 } 2321 else 2322 { 2323 WORD32 i4_prev_idx = ps_lap_struct->i4_buf_deq_idx > 0 2324 ? ps_lap_struct->i4_buf_deq_idx - 1 2325 : ps_lap_struct->i4_buf_deq_idx; 2326 /*field case of single IDR field followed by P*/ 2327 if(NULL != ps_lap_struct->aps_lap_inp_buf[i4_prev_idx] && i4_field_flag && 2328 ps_lap_struct->aps_lap_inp_buf[i4_prev_idx]->s_lap_out.i4_pic_type == 2329 IV_IDR_FRAME && 2330 !ps_lap_struct->i4_num_frm_type_decided) 2331 { 2332 ps_lap_struct->i4_immediate_idr_case = 1; 2333 } 2334 } 2335 } 2336 /* Queue in the current input Buffer to LAP que */ 2337 ihevce_lap_queue_input( 2338 ps_lap_struct, 2339 ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx], 2340 &i4_tree_num); 2341 2342 ps_lap_struct->i4_next_start_ctr++; 2343 ps_lap_struct->i4_buf_deq_idx++; 2344 2345 if(ps_lap_struct->i4_buf_deq_idx >= MAX_QUEUE_LENGTH) 2346 ps_lap_struct->i4_buf_deq_idx = 0; 2347 2348 ps_lap_struct->i4_buf_enq_idx++; 2349 if(ps_lap_struct->i4_buf_enq_idx >= MAX_QUEUE_LENGTH) 2350 ps_lap_struct->i4_buf_enq_idx = 0; 2351 } 2352 ps_lap_struct->i4_num_frames_after_force_idr = i4_num_frames_after_force_idr; 2353 2354 if(1 == ps_lap_struct->i4_force_end_flag) 2355 { 2356 ihevce_force_end(ps_hle_ctxt); 2357 } 2358 2359 /*return encode order pic to pre enc*/ 2360 ps_lap_inp_buf = NULL; 2361 2362 if(NULL != ps_lap_struct->api4_encode_order_array[ps_lap_struct->i4_lap_out_idx]) 2363 { 2364 ps_lap_inp_buf = ps_lap_struct->api4_encode_order_array[ps_lap_struct->i4_lap_out_idx]; 2365 ps_lap_struct->api4_encode_order_array[ps_lap_struct->i4_lap_out_idx] = NULL; 2366 if(!ps_lap_inp_buf->s_lap_out.i4_end_flag) 2367 ihevce_pre_rel_lapout_update(ps_lap_struct, ps_lap_inp_buf); 2368 } 2369 2370 ps_lap_struct->i4_lap_out_idx++; 2371 if(ps_lap_struct->i4_lap_out_idx == ps_lap_struct->i4_max_buf_in_enc_order) 2372 { 2373 ps_lap_struct->i4_lap_out_idx = 0; 2374 ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0]; 2375 } 2376 2377 return (ps_lap_inp_buf); 2378 } 2379 2380 /*! 2381 ************************************************************************ 2382 * \brief 2383 * lap get input buffer requirement count 2384 ************************************************************************ 2385 */ 2386 WORD32 ihevce_lap_get_num_ip_bufs(ihevce_lap_static_params_t *ps_lap_stat_prms) 2387 { 2388 WORD32 i4_lap_window_size = 1; 2389 WORD32 gop_delay = 1 << ps_lap_stat_prms->i4_max_temporal_layers; 2390 2391 if(ps_lap_stat_prms->s_lap_params.i4_rc_look_ahead_pics != 0) 2392 { 2393 i4_lap_window_size = 1 + ps_lap_stat_prms->s_lap_params.i4_rc_look_ahead_pics; 2394 } 2395 2396 gop_delay += (i4_lap_window_size); 2397 return gop_delay; 2398 } 2399