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 Includes */ 23 /*****************************************************************************/ 24 25 /* System include files */ 26 #include "stdio.h" 27 #include "string.h" 28 29 /* User include files */ 30 #include "irc_datatypes.h" 31 #include "irc_cntrl_param.h" 32 #include "irc_mem_req_and_acq.h" 33 #include "irc_picture_type.h" 34 #include "irc_trace_support.h" 35 36 #define MAX_INTER_FRM_INT 10 37 38 /******************************Pic_details ************************************/ 39 typedef struct 40 { 41 /* The id sent by the codec */ 42 WORD32 i4_pic_id; 43 44 /* The pics come in, in this order */ 45 WORD32 i4_pic_disp_order_no; 46 47 /* I,P,B */ 48 picture_type_e e_pic_type; 49 50 } pic_details_t; 51 52 /**************************Pic_handling structure *****************************/ 53 typedef struct pic_handling_t 54 { 55 /*************************************************************************** 56 * Inputs from the codec 57 **************************************************************************/ 58 59 /* Number of frames after which an I frame will repeat in display order */ 60 WORD32 i4_intra_frm_int; 61 62 /* (num_b_pics_in_subgop + 1) */ 63 WORD32 i4_inter_frm_int; 64 65 /* After these many buffered frames, the pics are encoded */ 66 WORD32 i4_max_inter_frm_int; 67 68 /* OPEN or CLOSED */ 69 WORD32 i4_is_gop_closed; 70 71 /* The pic stack */ 72 /* Stack used to store the input pics in encode order */ 73 pic_details_t as_pic_stack[MAX_INTER_FRM_INT + 2]; 74 75 /*************************************************************************** 76 * Counters 77 **************************************************************************/ 78 79 /* Decides whether a B or ref pic */ 80 WORD32 i4_buf_pic_no; 81 82 /* Current pic's number in displayed, and gets reset after an I-frm */ 83 WORD32 i4_pic_disp_order_no; 84 85 /* Number of P frms that have come, in the current gop, so far */ 86 WORD32 i4_p_count_in_gop; 87 88 /* Number of B frms that have come, in the current gop, so far */ 89 WORD32 i4_b_count_in_gop; 90 91 /* Number of B frms that have come, in the current subgop, so far */ 92 WORD32 i4_b_count_in_subgop; 93 94 /*************************************************************************** 95 * Indices to the pic stack (Since we store the pics in the encode order, 96 * these vars are modified to meet that) 97 **************************************************************************/ 98 99 /* B_PIC index */ 100 WORD32 i4_b_pic_idx; 101 102 /* I,P PIC index */ 103 WORD32 i4_ref_pic_idx; 104 105 /*************************************************************************** 106 * Variables operating on the input pics 107 **************************************************************************/ 108 109 /* Flag denoting whether it's the first gop or not */ 110 WORD32 i4_is_first_gop; 111 112 /* Number of B_PICs in an incomplete subgop */ 113 WORD32 i4_b_in_incomp_subgop; 114 115 /* In CLOSED_GOPs, even if inter_frm_int > 1, there can be 2 continous 116 * P_PICs at the GOP end. This takes values of 0 or 1 */ 117 WORD32 i4_extra_p; 118 119 /*************************************************************************** 120 * Arrays storing the number of frms in the gop 121 **************************************************************************/ 122 123 /* In the steady state, what's the pic distribution in display order */ 124 WORD32 i4_frms_in_gop[MAX_PIC_TYPE]; 125 126 /* 127 * In case of a change in inter frm int call, the pic distribution in 128 * that gop in display order 129 */ 130 WORD32 i4_frms_in_cur_gop[MAX_PIC_TYPE]; 131 132 /* 133 * This is used to denote the number of frms remaining to be encoded in the 134 * current gop 135 */ 136 WORD32 i4_rem_frms_in_gop[MAX_PIC_TYPE]; 137 138 /*************************************************************************** 139 * Variables operating on the output pics 140 **************************************************************************/ 141 142 /* Counts the frms encoded in a gop */ 143 WORD32 i4_coded_pic_no; 144 145 /* Counts from the start of stack to the end repeatedly */ 146 WORD32 i4_stack_count; 147 148 /*************************************************************************** 149 * Tracking a change in the inputs from the codec 150 **************************************************************************/ 151 152 /* A flag that is set when the codec calls for a change in inter_frm_int */ 153 WORD32 i4_change_in_inter_frm_int; 154 155 /* 156 * When a change_in_inter_frm_int is called, this stores the new 157 * inter_frm_int 158 */ 159 WORD32 i4_new_inter_frm_int; 160 161 /* 162 * When a change_in_inter_frm_int is called in the middle of a gop,this 163 * stores the B_PICs in the incomplete subgop of the mixed gop 164 */ 165 WORD32 i4_b_in_incomp_subgop_mix_gop; 166 167 /* 168 * For a CLOSED GOP, when a change_in_inter_frm_int is called in the middle 169 * of a gop,this is a flag denoting if there is an extra P_PIC in the mixed 170 * gop 171 */ 172 WORD32 i4_extra_p_mix_gop; 173 174 /* A flag that is set when the codec calls for a change in intra_frm_int */ 175 WORD32 i4_change_in_intra_frm_int; 176 177 /* 178 * When a change_in_intra_frm_int is called, this stores the new 179 * intra_frm_int 180 */ 181 WORD32 i4_new_intra_frm_int; 182 183 /*************************************************************************** 184 * Previous pic_stack_indices & details 185 **************************************************************************/ 186 pic_details_t s_prev_pic_details; 187 188 WORD32 i4_prev_b_pic_idx; 189 190 WORD32 i4_last_frm_in_gop; 191 192 WORD32 i4_first_gop_encoded; 193 194 /* NITT TBR */ 195 picture_type_e e_previous_pic_type; 196 197 WORD32 i4_force_I_frame; 198 199 WORD32 i4_forced_I_frame_cur_frame; 200 201 WORD32 i4_sum_remaining_frm_in_gop; 202 203 WORD32 i4_mod_temp_ref_cnt; 204 205 WORD32 i4_frames_in_fif_gop; 206 207 WORD32 i4_prev_intra_frame_interval; 208 209 } pic_handling_t; 210 211 static void irc_update_pic_distbn(pic_handling_t *ps_pic_handling, 212 WORD32 i4_intra_frm_int, 213 WORD32 i4_inter_frm_int, 214 WORD32 i4_gop_boundary); 215 216 static void find_pic_distbn_in_gop(WORD32 i4_frms_in_gop[MAX_PIC_TYPE], 217 WORD32 i4_intra_frm_int, 218 WORD32 i4_inter_frm_int, 219 WORD32 i4_is_gop_closed, 220 WORD32 *pi4_b_in_incomp_subgop, 221 WORD32 *pi4_extra_p); 222 223 WORD32 irc_pic_handling_num_fill_use_free_memtab(pic_handling_t **pps_pic_handling, 224 itt_memtab_t *ps_memtab, 225 ITT_FUNC_TYPE_E e_func_type) 226 { 227 WORD32 i4_mem_tab_idx = 0; 228 pic_handling_t s_pic_handling_temp; 229 230 /* 231 * Hack for al alloc, during which we dont have any state memory. 232 * Dereferencing can cause issues 233 */ 234 if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) 235 { 236 (*pps_pic_handling) = &s_pic_handling_temp; 237 } 238 239 /*for src rate control state structure*/ 240 if(e_func_type != GET_NUM_MEMTAB) 241 { 242 fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(pic_handling_t), 243 ALIGN_128_BYTE, PERSISTENT, DDR); 244 use_or_fill_base(&ps_memtab[0], (void**)pps_pic_handling, e_func_type); 245 } 246 i4_mem_tab_idx++; 247 248 return (i4_mem_tab_idx); 249 } 250 251 /****************************************************************************** 252 Description : initializes the pic handling state struct 253 *****************************************************************************/ 254 void irc_init_pic_handling(pic_handling_t *ps_pic_handling, 255 WORD32 i4_intra_frm_int, 256 WORD32 i4_inter_frm_int, 257 WORD32 i4_max_inter_frm_int, 258 WORD32 i4_is_gop_closed) 259 { 260 /* Declarations */ 261 WORD32 i; 262 263 /* Checks */ 264 /* Codec Parameters */ 265 ps_pic_handling->i4_intra_frm_int = i4_intra_frm_int; 266 ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int; 267 ps_pic_handling->i4_max_inter_frm_int = i4_max_inter_frm_int; 268 ps_pic_handling->i4_is_gop_closed = i4_is_gop_closed; 269 270 /* Pic_stack */ 271 memset(ps_pic_handling->as_pic_stack, 0, 272 sizeof(ps_pic_handling->as_pic_stack)); 273 memset(&ps_pic_handling->s_prev_pic_details, 0, 274 sizeof(ps_pic_handling->s_prev_pic_details)); 275 276 /* Counters */ 277 ps_pic_handling->i4_buf_pic_no = 0; 278 ps_pic_handling->i4_pic_disp_order_no = 0; 279 280 /* Indices to the pic_stack */ 281 ps_pic_handling->i4_ref_pic_idx = 0; 282 /* 283 * B frame index should be ref_frame_num, 284 * which is 2 in out case 285 */ 286 ps_pic_handling->i4_b_pic_idx = 2; 287 ps_pic_handling->i4_prev_b_pic_idx = 2; 288 289 /* Variables working on the input frames */ 290 ps_pic_handling->i4_is_first_gop = 1; 291 ps_pic_handling->i4_p_count_in_gop = 0; 292 ps_pic_handling->i4_b_count_in_gop = 0; 293 ps_pic_handling->i4_b_count_in_subgop = 0; 294 295 /* Variables working on the output frames */ 296 ps_pic_handling->i4_coded_pic_no = -1; 297 ps_pic_handling->i4_stack_count = -1; 298 299 /* Tracks the changes in the Codec Parameters */ 300 ps_pic_handling->i4_change_in_inter_frm_int = 0; 301 ps_pic_handling->i4_new_inter_frm_int = i4_max_inter_frm_int; 302 303 /* Tracks the changes in the Codec Parameters */ 304 ps_pic_handling->i4_change_in_intra_frm_int = 0; 305 ps_pic_handling->i4_new_intra_frm_int = i4_intra_frm_int; 306 307 /* Variables on which the bit allocation is dependent */ 308 /* Get the pic distribution in the gop */ 309 find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_gop, i4_intra_frm_int, 310 i4_inter_frm_int, i4_is_gop_closed, 311 &ps_pic_handling->i4_b_in_incomp_subgop, 312 &ps_pic_handling->i4_extra_p); 313 314 for(i = 0; i < MAX_PIC_TYPE; i++) 315 { 316 ps_pic_handling->i4_frms_in_cur_gop[i] = 317 ps_pic_handling->i4_frms_in_gop[i]; 318 ps_pic_handling->i4_rem_frms_in_gop[i] = 319 ps_pic_handling->i4_frms_in_gop[i]; 320 } 321 322 ps_pic_handling->e_previous_pic_type = I_PIC; 323 ps_pic_handling->i4_prev_intra_frame_interval = i4_intra_frm_int; 324 ps_pic_handling->i4_force_I_frame = 0; 325 ps_pic_handling->i4_forced_I_frame_cur_frame = 0; 326 ps_pic_handling->i4_sum_remaining_frm_in_gop = 0; 327 ps_pic_handling->i4_mod_temp_ref_cnt = 0; 328 329 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop = 330 ps_pic_handling->i4_b_in_incomp_subgop; 331 ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p; 332 333 ps_pic_handling->i4_last_frm_in_gop = 0; 334 ps_pic_handling->i4_first_gop_encoded = 0; 335 ps_pic_handling->i4_frames_in_fif_gop = 0; 336 337 } 338 339 /******************************************************************************* 340 * @brief registers the new intra frame interval value 341 ******************************************************************************/ 342 void irc_pic_handling_register_new_int_frm_interval(pic_handling_t *ps_pic_handling, 343 WORD32 i4_intra_frm_int) 344 { 345 ps_pic_handling->i4_change_in_intra_frm_int = 1; 346 ps_pic_handling->i4_new_intra_frm_int = i4_intra_frm_int; 347 } 348 349 void irc_pic_handling_register_new_inter_frm_interval(pic_handling_t *ps_pic_handling, 350 WORD32 i4_inter_frm_int) 351 { 352 /* Update the state structure with the latest values */ 353 ps_pic_handling->i4_change_in_inter_frm_int = 1; 354 ps_pic_handling->i4_new_inter_frm_int = i4_inter_frm_int; 355 } 356 357 static void start_new_gop(pic_handling_t *ps_pic_handling) 358 { 359 WORD32 i; 360 WORD32 i4_sum_remaining_frm_in_gop = 0; 361 362 /* Now, the end of gop updates */ 363 ps_pic_handling->i4_pic_disp_order_no = 0; 364 ps_pic_handling->i4_buf_pic_no = 0; 365 ps_pic_handling->i4_is_first_gop = 0; 366 ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p; 367 368 if(ps_pic_handling->i4_is_gop_closed) 369 { 370 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop = 371 ps_pic_handling->i4_b_in_incomp_subgop; 372 } 373 /* 374 * Store the number of frames in the gop that is encoded till now 375 * just before Force I frame call is made 376 */ 377 ps_pic_handling->i4_frames_in_fif_gop = ps_pic_handling->i4_b_count_in_gop 378 + ps_pic_handling->i4_p_count_in_gop + 1; 379 for(i = 0; i < MAX_PIC_TYPE; i++) 380 { 381 i4_sum_remaining_frm_in_gop += ps_pic_handling->i4_rem_frms_in_gop[i]; 382 } 383 ps_pic_handling->i4_sum_remaining_frm_in_gop = i4_sum_remaining_frm_in_gop; 384 for(i = 0; i < MAX_PIC_TYPE; i++) 385 { 386 ps_pic_handling->i4_frms_in_cur_gop[i] = 387 ps_pic_handling->i4_frms_in_gop[i]; 388 ps_pic_handling->i4_rem_frms_in_gop[i] = 389 ps_pic_handling->i4_frms_in_cur_gop[i]; 390 } 391 } 392 393 /******************************************************************************* 394 * @brief Fills the pic_stack with the incoming pics in encode order 395 ******************************************************************************/ 396 void irc_add_pic_to_stack(pic_handling_t *ps_pic_handling, WORD32 i4_enc_pic_id) 397 { 398 /* Declarations */ 399 WORD32 i4_inter_frm_int, i4_max_inter_frm_int, 400 i4_intra_frm_int, i4_new_inter_frm_int; 401 WORD32 i4_is_gop_closed; 402 WORD32 i4_buf_pic_no, i4_pic_disp_order_no; 403 WORD32 i4_b_pic_idx, i4_ref_pic_idx; 404 WORD32 i4_is_first_gop, i4_b_in_incomp_subgop, i4_p_count_in_gop, 405 i4_b_count_in_gop, i4_b_count_in_subgop; 406 WORD32 i, i4_p_frms_in_prd, i4_b_frms_in_prd, 407 i4_num_b_in_subgop, i4_extra_p; 408 WORD32 i4_condn_for_change_in_inter_frm_int; 409 picture_type_e e_previous_pic_type, e_cur_pic_type; 410 WORD32 i4_force_I_frame; 411 412 /* 413 * Initialize the local vars with the state struct values needed by the 414 * change calls 415 */ 416 i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int; 417 i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int; 418 i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int; 419 i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed; 420 421 i4_buf_pic_no = ps_pic_handling->i4_buf_pic_no; 422 i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no; 423 i4_b_count_in_gop = ps_pic_handling->i4_b_count_in_gop; 424 i4_b_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[B_PIC]; 425 i4_is_first_gop = ps_pic_handling->i4_is_first_gop; 426 i4_new_inter_frm_int = ps_pic_handling->i4_new_inter_frm_int; 427 e_previous_pic_type = ps_pic_handling->e_previous_pic_type; 428 i4_force_I_frame = ps_pic_handling->i4_force_I_frame; 429 430 /* Force I frame : 431 * Two different cases 432 * 1)OPEN_GOP: New GOP is started after number of B pictures in the last 433 * sub gop of a gop to mimic the GOP structure. 434 * 2)Closed GOP:Wait till P frame at input and The frame after a P frame 435 * a new GOP is started to mimic the GOP structure. 436 */ 437 if(i4_force_I_frame) 438 { 439 WORD32 i4_temp_is_gop_closed; 440 WORD32 i4_codn = 0; 441 /* A special case of Open GOP where the it behaves like Closed GOP*/ 442 if((i4_intra_frm_int % i4_inter_frm_int) == 1) 443 { 444 i4_temp_is_gop_closed = 1; 445 } 446 else 447 { 448 i4_temp_is_gop_closed = i4_is_gop_closed; 449 } 450 /* Get the current picture type to aid decision to force an I frame*/ 451 if((i4_buf_pic_no % i4_inter_frm_int) 452 && !(i4_is_gop_closed&& (i4_b_count_in_gop == i4_b_frms_in_prd))) 453 { 454 e_cur_pic_type = B_PIC; 455 } 456 else 457 { 458 if(i4_pic_disp_order_no == 0) 459 { 460 e_cur_pic_type = I_PIC; 461 } 462 else 463 { 464 e_cur_pic_type = P_PIC; 465 } 466 } 467 if((i4_intra_frm_int % i4_inter_frm_int) == 0) 468 { 469 i4_codn = (e_cur_pic_type == P_PIC); 470 } 471 else 472 { 473 i4_codn = (ps_pic_handling->i4_b_count_in_subgop 474 == ps_pic_handling->i4_b_in_incomp_subgop); 475 } 476 if(e_cur_pic_type == I_PIC) 477 { 478 /* 479 * Don't do anything. Resetting the force I frame flag 480 * since the current picture type is already a I frame 481 */ 482 i4_force_I_frame = 0; 483 } 484 else if(i4_inter_frm_int == 1) 485 { 486 /*IPP case , Force I frame immediately*/ 487 start_new_gop(ps_pic_handling); 488 } 489 else if((!i4_temp_is_gop_closed) && i4_codn) 490 { 491 start_new_gop(ps_pic_handling); 492 if(ps_pic_handling->i4_b_count_in_subgop) 493 { 494 ps_pic_handling->i4_b_pic_idx += 1; 495 ps_pic_handling->i4_b_pic_idx %= (i4_max_inter_frm_int + 1); 496 } 497 } 498 else if(i4_temp_is_gop_closed && (e_previous_pic_type == P_PIC) 499 && (e_cur_pic_type != P_PIC)) 500 { 501 start_new_gop(ps_pic_handling); 502 ps_pic_handling->i4_b_pic_idx++; 503 ps_pic_handling->i4_b_pic_idx %= (i4_max_inter_frm_int + 1); 504 } 505 i4_is_first_gop = ps_pic_handling->i4_is_first_gop; 506 } 507 508 509 /***********************CHANGE_INTRA_FRM_INTERVAL************************** 510 * 511 * Call the irc_update_pic_distbn if 512 * 1)Change in intra frm interval flag is set 513 * 2)It's the first B_PIC of a gop 514 */ 515 if((ps_pic_handling->i4_change_in_intra_frm_int == 1) 516 && ((i4_pic_disp_order_no == 1))) 517 { 518 irc_update_pic_distbn(ps_pic_handling, 519 ps_pic_handling->i4_new_intra_frm_int, 520 ps_pic_handling->i4_inter_frm_int, 1); 521 522 ps_pic_handling->i4_change_in_intra_frm_int = 0; 523 524 if(ps_pic_handling->i4_new_intra_frm_int == 1) 525 { 526 ps_pic_handling->i4_pic_disp_order_no = 0; 527 } 528 } 529 /*********************CHANGE_INTER_FRM_INTERVAL****************************/ 530 /* Call irc_update_pic_distbn if 531 * 1)Change in inter frm interval flag is set 532 * 2)It's the first B_PIC after gop/subgop start, and 533 * 3)The new inter-frm-interval won't cross the intra_frm_interval 534 */ 535 if((ps_pic_handling->i4_change_in_inter_frm_int == 1) 536 && ((i4_buf_pic_no % i4_inter_frm_int == 1)|| (i4_pic_disp_order_no == 1) || (i4_inter_frm_int == 1))) 537 { 538 /* 539 * Condition which checks if the new inter_frm_int will cross the 540 * intra_frm_int 541 */ 542 i4_condn_for_change_in_inter_frm_int = ((i4_pic_disp_order_no 543 + i4_new_inter_frm_int - 1) < i4_intra_frm_int); 544 545 if(i4_condn_for_change_in_inter_frm_int) 546 { 547 /* 548 * If there is a change in inter frame interval. We should set the b 549 * frame IDX to the (num ref frame - num ref frame in buf)+ i4_ref_pic_idx 550 * Since our case we have a structure of I B P or I B...B P only 551 * we have three cases 552 * 1) current incoming frame is I. Then we have to leave space for 553 * current I and next P hence write b idx as to ref idx + 2 554 * 2) Current incoming frame is B. In that case, we have I in buffer. 555 * Only one P needs space hence write b idx as ref idx +1 556 * 3) Current incoming frame is P. In that case we are at the end of 557 * gop [sub gop?] and we have to leave space for next gops I and P. 558 * Thus b idx = ref idx + 2 559 * 560 * In case of an closed Gop. The last frame has to be forced to be a P. 561 * Hence we may have problems in that case. 562 * 563 * Also this has the implicit assumption of only 2 ref frames 564 */ 565 WORD32 i4_is_curr_frm_b = (i4_buf_pic_no % i4_new_inter_frm_int)&& 566 !(i4_is_gop_closed && (i4_b_count_in_gop == i4_b_frms_in_prd)); 567 568 /*If the inter_frm_int = 1, then the b_pic_idx needs to be modified */ 569 if(i4_inter_frm_int == 1) 570 { 571 ps_pic_handling->i4_b_pic_idx = ((i4_is_curr_frm_b ? 1 : 2) 572 + ps_pic_handling->i4_ref_pic_idx) 573 % (i4_max_inter_frm_int + 1); 574 } 575 576 /* 577 * Depending on the gop/subgop boundary, call the change_inter_frm_int 578 * 579 * TO DO: make a single call, change the name of the fxn to 580 * update_state, 581 * where state = frms_in_gop + b_incomp_subgop + extra_p 582 */ 583 584 /* GOP boundary */ 585 if(i4_pic_disp_order_no == 1) 586 { 587 irc_update_pic_distbn(ps_pic_handling, 588 ps_pic_handling->i4_intra_frm_int, 589 ps_pic_handling->i4_new_inter_frm_int, 1); 590 } 591 /* Subgop boundary */ 592 else 593 { 594 irc_update_pic_distbn(ps_pic_handling, 595 ps_pic_handling->i4_intra_frm_int, 596 ps_pic_handling->i4_new_inter_frm_int, 0); 597 } 598 599 ps_pic_handling->i4_change_in_inter_frm_int = 0; 600 ps_pic_handling->i4_new_inter_frm_int = 601 ps_pic_handling->i4_inter_frm_int; 602 } 603 604 } 605 606 /* Initialize the local vars with the state struct values */ 607 i4_buf_pic_no = ps_pic_handling->i4_buf_pic_no; 608 i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no; 609 i4_b_pic_idx = ps_pic_handling->i4_b_pic_idx; 610 i4_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx; 611 i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop_mix_gop; 612 i4_p_count_in_gop = ps_pic_handling->i4_p_count_in_gop; 613 i4_b_count_in_gop = ps_pic_handling->i4_b_count_in_gop; 614 i4_b_count_in_subgop = ps_pic_handling->i4_b_count_in_subgop; 615 i4_p_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[P_PIC]; 616 i4_b_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[B_PIC]; 617 i4_extra_p = ps_pic_handling->i4_extra_p_mix_gop; 618 i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int; 619 i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int; 620 621 /* Initializing the prev_state vars */ 622 ps_pic_handling->i4_prev_b_pic_idx = ps_pic_handling->i4_b_pic_idx; 623 624 i4_num_b_in_subgop = (i4_inter_frm_int - 1); 625 626 /*********************** Fill the stack ***********************************/ 627 /* The next part of the code is organized as 628 * 629 * if(B_PIC conditions satisfied) 630 * { 631 * Fill the pic_stack using the b_pic_index 632 * Update the b_pic_index and the other b_pic related vars for the 633 * next B_PIC 634 * } 635 * else 636 * { 637 * if(I_PIC conditions are satisfied) 638 * { 639 * Fill the pic_stack using the ref_pic_index 640 * Update the ref_pic_index and the other ref_pic related vars for the next 641 * I_PIC/P_PIC 642 * } 643 * else 644 * { 645 * Fill the pic_stack using the ref_pic_index 646 * Update the ref_pic_index and the other ref_pic related vars for the next 647 * I_PIC/P_PIC 648 * } 649 * } 650 */ 651 /* 652 * Condition for a B_PIC - 653 * 1) Other than the first I_PIC and the periodically appearing P_PICs, after 654 * every inter_frm_int, rest all pics are B_PICs 655 * 2) In case of CLOSED_GOP, the last frame of the gop has to be a P_PIC 656 */ 657 658 if((i4_buf_pic_no % i4_inter_frm_int)&& !(i4_is_gop_closed 659 && (i4_b_count_in_gop == i4_b_frms_in_prd))) /**** B_PIC ****/ 660 { 661 /* Fill the pic_stack */ 662 ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_id = i4_enc_pic_id; 663 ps_pic_handling->as_pic_stack[i4_b_pic_idx].e_pic_type = B_PIC; 664 ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_disp_order_no = 665 i4_pic_disp_order_no; 666 667 /* Store Pic type*/ 668 e_previous_pic_type = B_PIC; 669 670 /* Update the prev_pic_details */ 671 memcpy(&ps_pic_handling->s_prev_pic_details, 672 &ps_pic_handling->as_pic_stack[i4_b_pic_idx], 673 sizeof(pic_details_t)); 674 675 i4_b_count_in_gop++; 676 i4_b_count_in_subgop++; 677 678 /* Update the i4_b_pic_idx */ 679 if(!i4_is_gop_closed) 680 { 681 /* If this B_PIC features in one of the complete subgops */ 682 if((i4_b_count_in_subgop < i4_num_b_in_subgop) 683 && !(i4_b_count_in_gop == i4_b_frms_in_prd)) 684 { 685 i4_b_pic_idx++; 686 } 687 else /* Else if this B_PIC is the last one in a subgop or gop */ 688 { 689 /* 690 * If this is the last B_PIC of a GOP, depending on the number 691 * of incomp B_pics in the subgop, there can be either only I 692 * or I,P pics between this and the next B_PIC 693 */ 694 if(i4_b_count_in_gop == i4_b_frms_in_prd) 695 { 696 i4_b_pic_idx += (2 + (!i4_b_in_incomp_subgop)); /*Prev*/ 697 i4_b_count_in_gop = 0; 698 } 699 /* 700 * For the last B_PIC of a subgop, there's always a P b/w 701 * this & the next B_PIC 702 */ 703 else 704 { 705 i4_b_pic_idx += 2; 706 } 707 i4_b_count_in_subgop = 0; 708 } 709 } 710 else 711 { 712 /* For the last B_PIC of a gop 713 * Normally,there will be 3 pics (P,I,P) between this and the next 714 * B_PIC for a CLOSED gop, except when 715 * 1)Number of P_pics in the gop = 1 716 * 2)There is an extra P at the end of the gop 717 */ 718 if(i4_b_count_in_gop == i4_b_frms_in_prd) 719 { 720 i4_b_pic_idx += (3 + ((i4_b_in_incomp_subgop == 0) 721 && (i4_p_frms_in_prd> 1) 722 && (i4_pic_disp_order_no 723 != (i4_p_frms_in_prd+ i4_b_frms_in_prd- 1)))); 724 725 i4_b_count_in_subgop = 0; 726 } 727 /* For a B_PIC which is not the last one in a subgop */ 728 else if(i4_b_count_in_subgop < i4_num_b_in_subgop) 729 { 730 i4_b_pic_idx++; 731 } 732 else /* For the last B_PIC of a subgop */ 733 { 734 i4_b_pic_idx += 2; 735 i4_b_count_in_subgop = 0; 736 } 737 } 738 i4_b_pic_idx %= (i4_max_inter_frm_int + 1); 739 } 740 /*********** I or P pic *********/ 741 else 742 { 743 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id = i4_enc_pic_id; 744 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no = 745 i4_pic_disp_order_no; 746 /* Store Pic type*/ 747 e_previous_pic_type = I_PIC; 748 749 /**** I_PIC ****/ 750 if(i4_pic_disp_order_no == 0) 751 { 752 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = I_PIC; 753 754 /* Update the prev_pic_details */ 755 memcpy(&ps_pic_handling->s_prev_pic_details, 756 &ps_pic_handling->as_pic_stack[i4_ref_pic_idx], 757 sizeof(pic_details_t)); 758 /* 759 * In case of an I-frame depending on OPEN or CLOSED gop, 760 * the ref_pic_idx changes 761 */ 762 if((!i4_is_gop_closed) && (i4_is_first_gop == 0)) 763 { 764 if((i4_p_frms_in_prd <= 1) && (i4_b_in_incomp_subgop == 0)) 765 { 766 i4_ref_pic_idx++; 767 } 768 /* 769 * From the 2nd gop onwards, the I and first P frame are 770 * separated by the num_b_in_incomp_subgop 771 */ 772 else 773 { 774 i4_ref_pic_idx += (i4_b_in_incomp_subgop + 1); 775 } 776 777 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop = 778 ps_pic_handling->i4_b_in_incomp_subgop; 779 } 780 else 781 { 782 i4_ref_pic_idx++; 783 } 784 785 i4_b_count_in_gop = 0; 786 i4_p_count_in_gop = 0; 787 i4_b_count_in_subgop = 0; 788 789 } 790 /**** P_PIC ****/ 791 else 792 { 793 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = P_PIC; 794 /* Store Pic type*/ 795 e_previous_pic_type = P_PIC; 796 797 /* Update the prev_pic_details */ 798 memcpy(&ps_pic_handling->s_prev_pic_details, 799 &ps_pic_handling->as_pic_stack[i4_ref_pic_idx], 800 sizeof(pic_details_t)); 801 802 i4_p_count_in_gop++; 803 ps_pic_handling->i4_prev_intra_frame_interval = i4_intra_frm_int; 804 805 /* 806 * In case of an P-frame depending on OPEN or CLOSED gop, the 807 * ref_pic_idx changes 808 */ 809 if(i4_is_gop_closed && (i4_p_count_in_gop == i4_p_frms_in_prd)) 810 { 811 /* 812 * For the last P_PIC in a gop, if extra_p or incomp_b are 813 * present, the number of such pics between this and the next 814 * ref_pic is (i4_b_in_incomp_subgop + 1) 815 */ 816 if((i4_p_count_in_gop > 1) 817 && (i4_b_in_incomp_subgop || i4_extra_p)) 818 { 819 i4_ref_pic_idx += (i4_b_in_incomp_subgop + 1); 820 } 821 else 822 { 823 i4_ref_pic_idx += i4_inter_frm_int; 824 } 825 } 826 else 827 { 828 i4_ref_pic_idx += i4_inter_frm_int; 829 } 830 } 831 832 i4_ref_pic_idx %= (i4_max_inter_frm_int + 1); 833 } 834 835 /* Update those variables working on the input frames */ 836 i4_pic_disp_order_no++; 837 i4_buf_pic_no++; 838 839 #if 0 840 /* For any gop */ 841 /* BUG FIX 842 * This piece of code resets the gop upon I frame(?) 843 * This introduces a problem of GOP getting reset not at I frames as it should be 844 * The reason AFAIK is that 845 * 1) This code uses i4_pic_disp_order_no to reset GOP. I assume it computes 846 * if are at GOP boundary and does it, but not sure 847 * 2) The frames rmainign in GOP is done in post enc as it should be. 848 * 849 * Also ps_pic_handling->i4_pic_disp_order_no is incremented when a pic is added 850 * to stack becuase the additon is in disp order while poping is in encode order 851 * 852 * SUppose there is a deay od 1 frame between queue and encode. 853 * then he timing will be. Assume a GOP of IPPIPP 854 * 855 * Input buff Input to qu Output buf/encode buff remaining pic in gop 856 * 1 I I NA rest to 1 2 857 * 2 P P I 0 2 858 * 3 P P P 0 1 859 * 4 I I P reset to 1 2 860 * 5 P P I 1 1 861 * 6 P P P 1 0 862 * 7 NA NA P 863 * 864 * Hence our gop gets reset at I(1) and I(4) in the RC.thus the reaming pic in gop 865 * count will be as shown. We can clearly see that the GOP gets reset at I(4) .Hence 866 * for the correpondinng QP for output buf p(4) will be that of an I frame. 867 * 868 * By hiding this I hope to fix this problem. But Iam not sure exaclty. 869 * This needs to be investigated further 870 * 871 * By hiding this most likely we are in effect disabling the dynanic 872 * update of gop params. 873 */ 874 875 if(ps_pic_handling->i4_pic_disp_order_no 876 == (i4_max_inter_frm_int - 1- ((!i4_is_gop_closed) 877 * ps_pic_handling->i4_b_in_incomp_subgop_mix_gop))) 878 { 879 for(i = 0; i < MAX_PIC_TYPE; i++) 880 { 881 ps_pic_handling->i4_rem_frms_in_gop[i] = 882 ps_pic_handling->i4_frms_in_cur_gop[i]; 883 } 884 885 if((!i4_is_gop_closed) && (i4_is_first_gop) 886 && (ps_pic_handling->i4_rem_frms_in_gop[B_PIC] 887 > ps_pic_handling->i4_b_in_incomp_subgop_mix_gop)) 888 { 889 ps_pic_handling->i4_rem_frms_in_gop[B_PIC] = 890 ps_pic_handling->i4_frms_in_cur_gop[B_PIC] 891 - ps_pic_handling->i4_b_in_incomp_subgop_mix_gop; 892 } 893 } 894 #endif 895 896 /* End of GOP updates */ 897 if(i4_pic_disp_order_no == (i4_p_frms_in_prd + i4_b_frms_in_prd + 1)) 898 { 899 /* Now, the end of gop updates */ 900 i4_pic_disp_order_no = 0; 901 i4_buf_pic_no = 0; 902 i4_is_first_gop = 0; 903 ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p; 904 905 if(i4_is_gop_closed) 906 { 907 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop = 908 ps_pic_handling->i4_b_in_incomp_subgop; 909 } 910 911 for(i = 0; i < MAX_PIC_TYPE; i++) 912 { 913 ps_pic_handling->i4_frms_in_cur_gop[i] = 914 ps_pic_handling->i4_frms_in_gop[i]; 915 } 916 } 917 918 /* Updating the vars which work on the encoded pics */ 919 /* For the first gop */ 920 if ((ps_pic_handling->i4_is_first_gop) 921 && (ps_pic_handling->i4_pic_disp_order_no == 0)) 922 { 923 ps_pic_handling->i4_coded_pic_no = 0; 924 ps_pic_handling->i4_stack_count = 0; 925 } 926 927 /* Update the state struct with the modifiable local vars */ 928 ps_pic_handling->i4_buf_pic_no = i4_buf_pic_no; 929 ps_pic_handling->i4_pic_disp_order_no = i4_pic_disp_order_no; 930 ps_pic_handling->i4_b_pic_idx = i4_b_pic_idx; 931 ps_pic_handling->i4_ref_pic_idx = i4_ref_pic_idx; 932 ps_pic_handling->i4_is_first_gop = i4_is_first_gop; 933 ps_pic_handling->i4_p_count_in_gop = i4_p_count_in_gop; 934 ps_pic_handling->i4_b_count_in_gop = i4_b_count_in_gop; 935 ps_pic_handling->i4_b_count_in_subgop = i4_b_count_in_subgop; 936 ps_pic_handling->e_previous_pic_type = e_previous_pic_type; 937 ps_pic_handling->i4_force_I_frame = i4_force_I_frame; 938 } 939 940 /******************************************************************************* 941 * @brief Returns the picture type, ip and display order number for the frame to 942 * be encoded 943 ******************************************************************************/ 944 void irc_get_pic_from_stack(pic_handling_t *ps_pic_handling, 945 WORD32 *pi4_pic_id, 946 WORD32 *pi4_pic_disp_order_no, 947 picture_type_e *pe_pic_type) 948 { 949 pic_details_t s_pic_details; 950 pic_details_t *ps_pic_details = &s_pic_details; 951 952 if(ps_pic_handling->i4_stack_count < 0) 953 { 954 ps_pic_details->e_pic_type = BUF_PIC; 955 ps_pic_details->i4_pic_disp_order_no = -1; 956 ps_pic_details->i4_pic_id = -1; 957 } 958 else 959 { 960 memcpy(ps_pic_details, 961 &ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count], 962 sizeof(pic_details_t)); 963 964 /* Force I frame updations */ 965 if((ps_pic_handling->i4_force_I_frame == 1) 966 && (ps_pic_details->e_pic_type == I_PIC)) 967 { 968 /* Flag to signal change in remaining bits*/ 969 ps_pic_handling->i4_forced_I_frame_cur_frame = 1; 970 ps_pic_handling->i4_force_I_frame = 0; 971 /* 972 * Indicates count for no. of Pictures whose temporal reference 973 * has to be modified 974 * in the new GOP 975 */ 976 ps_pic_handling->i4_mod_temp_ref_cnt = 977 ps_pic_handling->i4_b_in_incomp_subgop + 1; 978 ps_pic_handling->i4_first_gop_encoded = 1; 979 } 980 981 /* 982 * In MPEG2, the temporal reference of the first displayed frame in a 983 * gop is 0.In case of an OPEN_GOP, the B_PICs of the last subgop in a 984 * gop, maybe coded as a part of the next gop. Hence, in such conditions 985 * the pic_disp_order needs to be modified so that it gives an 986 * indication of the temporal reference 987 */ 988 if((!ps_pic_handling->i4_is_gop_closed) 989 && (ps_pic_handling->i4_first_gop_encoded)) 990 { 991 if(!ps_pic_handling->i4_mod_temp_ref_cnt) 992 { 993 ps_pic_details->i4_pic_disp_order_no = 994 (ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no 995 + ps_pic_handling->i4_b_in_incomp_subgop) 996 % (ps_pic_handling->i4_prev_intra_frame_interval); 997 998 } 999 else 1000 { 1001 /* 1002 * due to force I frame First frame will have only 1003 * ps_pic_handling->i4_frames_in_fif_gop number of frames 1004 */ 1005 ps_pic_details->i4_pic_disp_order_no = 1006 (ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no 1007 + ps_pic_handling->i4_b_in_incomp_subgop) 1008 % (ps_pic_handling->i4_frames_in_fif_gop); 1009 ps_pic_handling->i4_mod_temp_ref_cnt--; 1010 } 1011 } 1012 } 1013 1014 /* Giving this to the Codec */ 1015 *pi4_pic_id = s_pic_details.i4_pic_id; 1016 *pi4_pic_disp_order_no = s_pic_details.i4_pic_disp_order_no; 1017 *pe_pic_type = s_pic_details.e_pic_type; 1018 } 1019 1020 /******************************************************************************* 1021 * @brief Updates the picture handling state whenever there is changes in input 1022 * parameter 1023 * 1024 ******************************************************************************/ 1025 static void irc_update_pic_distbn(pic_handling_t *ps_pic_handling, 1026 WORD32 i4_intra_frm_int, 1027 WORD32 i4_inter_frm_int, 1028 WORD32 i4_gop_boundary) 1029 { 1030 /* Declarations */ 1031 WORD32 i4_is_gop_closed; 1032 WORD32 i, i4_prev_inter_frm_int, i4_max_inter_frm_int, i4_pic_disp_order_no; 1033 WORD32 i4_b_in_incomp_subgop, i4_extra_p, 1034 i4_b_in_incomp_subgop_mix_gop,i4_extra_p_mix_gop; 1035 WORD32 i4_pb_frms_till_prev_p; 1036 WORD32 ai4_diff_in_frms[MAX_PIC_TYPE]; 1037 1038 /* Initialize the local vars from the state struct */ 1039 i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed; 1040 i4_prev_inter_frm_int = ps_pic_handling->i4_inter_frm_int; 1041 i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int; 1042 i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop; 1043 i4_extra_p = ps_pic_handling->i4_extra_p; 1044 i4_b_in_incomp_subgop_mix_gop = 1045 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop; 1046 i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p_mix_gop; 1047 i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no; 1048 1049 i4_pb_frms_till_prev_p = (ps_pic_handling->i4_p_count_in_gop 1050 * i4_prev_inter_frm_int); 1051 1052 /* Check for the validity of the intra_frm_int */ 1053 if(i4_intra_frm_int <= 0) 1054 { 1055 i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int; 1056 } 1057 /* Check for the validity of the inter_frm_int */ 1058 if((i4_inter_frm_int > i4_max_inter_frm_int) || (i4_inter_frm_int < 0)) 1059 { 1060 i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int; 1061 } 1062 1063 /* Keep a copy of the older frms_in_gop */ 1064 for(i = 0; i < MAX_PIC_TYPE; i++) 1065 { 1066 ai4_diff_in_frms[i] = ps_pic_handling->i4_frms_in_cur_gop[i]; 1067 } 1068 1069 /* Update all the variables which are calculated from the inter_frm_int */ 1070 1071 /* Get the new pic distribution in the gop */ 1072 find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_gop, i4_intra_frm_int, 1073 i4_inter_frm_int, i4_is_gop_closed, 1074 &i4_b_in_incomp_subgop, &i4_extra_p); 1075 1076 /* Find the other related variables */ 1077 if(i4_gop_boundary == 0) 1078 { 1079 /* 1080 * Since, the inter frame interval has changed between a gop the 1081 * current gop will be a mixed gop. So, we need to find the values of 1082 * the related variables 1083 */ 1084 find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_cur_gop, 1085 (i4_intra_frm_int - i4_pb_frms_till_prev_p), 1086 i4_inter_frm_int, i4_is_gop_closed, 1087 &i4_b_in_incomp_subgop_mix_gop, 1088 &i4_extra_p_mix_gop); 1089 1090 ps_pic_handling->i4_frms_in_cur_gop[P_PIC] += 1091 ps_pic_handling->i4_p_count_in_gop; 1092 ps_pic_handling->i4_frms_in_cur_gop[B_PIC] += 1093 ps_pic_handling->i4_b_count_in_gop; 1094 } 1095 else 1096 { 1097 /* 1098 * Since, the inter_frm_interval has changed at a gop boundary, the 1099 * new gop will have all the subgops with the new inter_frm_interval 1100 */ 1101 for(i = 0; i < MAX_PIC_TYPE; i++) 1102 { 1103 ps_pic_handling->i4_frms_in_cur_gop[i] = 1104 ps_pic_handling->i4_frms_in_gop[i]; 1105 } 1106 1107 i4_b_in_incomp_subgop_mix_gop = i4_b_in_incomp_subgop; 1108 i4_extra_p_mix_gop = i4_extra_p; 1109 } 1110 1111 /* For bit-allocation the rem_frms_in_gop need to be updated */ 1112 /* Checks needed: 1113 1) If the encoding is happening on the same gop as that of the buffering */ 1114 if(ps_pic_handling->i4_pic_disp_order_no 1115 >= (i4_max_inter_frm_int - 1- ((!i4_is_gop_closed) 1116 * ps_pic_handling->i4_b_in_incomp_subgop_mix_gop))) 1117 { 1118 for(i = 0; i < MAX_PIC_TYPE; i++) 1119 { 1120 ps_pic_handling->i4_rem_frms_in_gop[i] += 1121 (ps_pic_handling->i4_frms_in_cur_gop[i] 1122 - ai4_diff_in_frms[i]); 1123 } 1124 } 1125 1126 /* Update the vars which will affect the proper filling of the pic_stack */ 1127 if(i4_pic_disp_order_no == 0) /*Check if redundant*/ 1128 { 1129 ps_pic_handling->i4_buf_pic_no = 0; 1130 } 1131 else 1132 { 1133 ps_pic_handling->i4_buf_pic_no = 1; 1134 } 1135 1136 ps_pic_handling->i4_b_count_in_subgop = 0; 1137 1138 /* Update the state struct with the new inter_frm_int */ 1139 ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int; 1140 ps_pic_handling->i4_intra_frm_int = i4_intra_frm_int; 1141 ps_pic_handling->i4_b_in_incomp_subgop = i4_b_in_incomp_subgop; 1142 ps_pic_handling->i4_extra_p = i4_extra_p; 1143 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop = 1144 i4_b_in_incomp_subgop_mix_gop; 1145 ps_pic_handling->i4_extra_p_mix_gop = i4_extra_p_mix_gop; 1146 1147 } 1148 1149 /* ***************************************************************************** 1150 * @brief Distributes the frames as I, P and B based on intra/inter frame interval. 1151 * Along with it it fills the number of frames in sub-gop and extra p frame 1152 * 1153 ******************************************************************************/ 1154 static void find_pic_distbn_in_gop(WORD32 i4_frms_in_gop[MAX_PIC_TYPE], 1155 WORD32 i4_intra_frm_int, 1156 WORD32 i4_inter_frm_int, 1157 WORD32 i4_is_gop_closed, 1158 WORD32 *pi4_b_in_incomp_subgop, 1159 WORD32 *pi4_extra_p) 1160 { 1161 /* 1162 * Find the pic distribution in the gop depending on the inter and intra 1163 * frm intervals 1164 */ 1165 i4_frms_in_gop[I_PIC] = 1; 1166 1167 /* All I frames */ 1168 if(i4_intra_frm_int == 1) 1169 { 1170 i4_frms_in_gop[P_PIC] = 0; 1171 i4_frms_in_gop[B_PIC] = 0; 1172 *pi4_b_in_incomp_subgop = 0; 1173 *pi4_extra_p = 0; 1174 } 1175 else 1176 { 1177 if(i4_is_gop_closed) 1178 { 1179 i4_frms_in_gop[P_PIC] = ((i4_intra_frm_int - 2) / i4_inter_frm_int) 1180 + 1; 1181 1182 if((((i4_intra_frm_int - 2) / i4_inter_frm_int) * i4_inter_frm_int) 1183 == (i4_intra_frm_int - 2)) 1184 { 1185 *pi4_extra_p = 1; 1186 } 1187 else 1188 { 1189 *pi4_extra_p = 0; 1190 } 1191 } 1192 else 1193 { 1194 i4_frms_in_gop[P_PIC] = ((i4_intra_frm_int - 1) / i4_inter_frm_int); 1195 1196 *pi4_extra_p = 0; 1197 } 1198 1199 i4_frms_in_gop[B_PIC] = (i4_intra_frm_int - 1 - i4_frms_in_gop[P_PIC]); 1200 1201 *pi4_b_in_incomp_subgop = (i4_frms_in_gop[B_PIC] - (i4_inter_frm_int - 1) 1202 * ((i4_intra_frm_int - 1)/ i4_inter_frm_int)); 1203 } 1204 } 1205 1206 WORD32 irc_pic_type_get_intra_frame_interval(pic_handling_t *ps_pic_handling) 1207 { 1208 1209 return (ps_pic_handling->i4_intra_frm_int); 1210 } 1211 1212 WORD32 irc_pic_type_get_inter_frame_interval(pic_handling_t *ps_pic_handling) 1213 { 1214 return (ps_pic_handling->i4_inter_frm_int); 1215 } 1216 1217 void irc_pic_type_get_rem_frms_in_gop(pic_handling_t *ps_pic_handling, 1218 WORD32 ai4_rem_frms_in_gop[MAX_PIC_TYPE]) 1219 { 1220 memcpy(ai4_rem_frms_in_gop, ps_pic_handling->i4_rem_frms_in_gop, 1221 sizeof(ps_pic_handling->i4_rem_frms_in_gop)); 1222 } 1223 1224 WORD32 irc_pic_type_get_frms_in_gop_force_I_frm(pic_handling_t *ps_pic_handling) 1225 { 1226 return (ps_pic_handling->i4_frames_in_fif_gop); 1227 } 1228 1229 void irc_pic_type_get_frms_in_gop(pic_handling_t *ps_pic_handling, 1230 WORD32 ai4_frms_in_gop[MAX_PIC_TYPE]) 1231 { 1232 memcpy(ai4_frms_in_gop, ps_pic_handling->i4_frms_in_cur_gop, 1233 sizeof(ps_pic_handling->i4_frms_in_cur_gop)); 1234 } 1235 1236 WORD32 irc_pic_type_get_disp_order_no(pic_handling_t *ps_pic_handling) 1237 { 1238 return (ps_pic_handling->i4_pic_disp_order_no); 1239 } 1240 1241 void irc_set_force_I_frame_flag(pic_handling_t *ps_pic_handling) 1242 { 1243 ps_pic_handling->i4_force_I_frame = 1; 1244 } 1245 WORD32 irc_get_forced_I_frame_cur_frm_flag(pic_handling_t *ps_pic_handling) 1246 { 1247 return (ps_pic_handling->i4_forced_I_frame_cur_frame); 1248 } 1249 void irc_reset_forced_I_frame_cur_frm_flag(pic_handling_t *ps_pic_handling) 1250 { 1251 ps_pic_handling->i4_forced_I_frame_cur_frame = 0; 1252 } 1253 1254 /******************************************************************************/ 1255 /* Functions that work on the encoded frames */ 1256 /******************************************************************************/ 1257 1258 /****************************************************************************** 1259 Function Name : irc_update_pic_handling 1260 Description : Will be called only for the frames to be encoded 1261 *****************************************************************************/ 1262 void irc_update_pic_handling(pic_handling_t *ps_pic_handling, 1263 picture_type_e e_pic_type) 1264 { 1265 1266 WORD32 i4_max_inter_frm_int; 1267 WORD32 i; 1268 1269 /* Initializing the local vars with that of the state struct */ 1270 i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int; 1271 1272 /* Update the variables working on the output frames */ 1273 /* Update the stack count */ 1274 ps_pic_handling->i4_stack_count++; 1275 1276 if(ps_pic_handling->i4_stack_count == (i4_max_inter_frm_int + 1)) 1277 { 1278 ps_pic_handling->i4_stack_count = 0; 1279 } 1280 1281 /* Update the rem_frms_in_gop */ 1282 ps_pic_handling->i4_rem_frms_in_gop[e_pic_type]--; 1283 1284 /* Assumption : Rem_frms_in_gop needs to be taken care of, for every change in frms */ 1285 ps_pic_handling->i4_last_frm_in_gop = 0; 1286 if((ps_pic_handling->i4_rem_frms_in_gop[I_PIC] <= 0) 1287 && (ps_pic_handling->i4_rem_frms_in_gop[P_PIC] <= 0) 1288 && (ps_pic_handling->i4_rem_frms_in_gop[B_PIC] <= 0)) 1289 { 1290 /* Copy the cur_frms_in_gop to the rem_frm_in_gop */ 1291 for(i = 0; i < MAX_PIC_TYPE; i++) 1292 { 1293 ps_pic_handling->i4_rem_frms_in_gop[i] = 1294 ps_pic_handling->i4_frms_in_cur_gop[i]; 1295 } 1296 1297 ps_pic_handling->i4_last_frm_in_gop = 1; 1298 ps_pic_handling->i4_first_gop_encoded = 1; 1299 } 1300 } 1301 1302 WORD32 irc_is_last_frame_in_gop(pic_handling_handle ps_pic_handling) 1303 { 1304 return (ps_pic_handling->i4_last_frm_in_gop); 1305 } 1306 1307 /****************************************************************************** 1308 Function Name : irc_skip_encoded_frame 1309 Description : Needs to go to the current pic in the pic_stack. 1310 If it's B_PIC don't do anything 1311 If it's a reference picture, push all but the last B_PICs 1312 in the current subgop one place down (i.e. just copy their 1313 pic_details) and move the last B_PIC in that subgop to the 1314 next slot of the skipped picture and convert it's pic_type 1315 to that of the reference picture 1316 *****************************************************************************/ 1317 void irc_skip_encoded_frame(pic_handling_t *ps_pic_handling, 1318 picture_type_e e_pic_type) 1319 { 1320 pic_details_t s_pic_details; 1321 WORD32 i4_stack_count, i4_next_ref_pic_idx, i4_pic_idx; 1322 WORD32 i4_max_inter_frm_int, i4_last_b_pic_idx, i4_first_b_pic_idx; 1323 WORD32 i4_next_pic_idx; 1324 1325 /* State variables used to initialize the local vars (Not to be changed) */ 1326 i4_stack_count = ps_pic_handling->i4_stack_count; 1327 i4_next_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx; 1328 i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int; 1329 1330 i4_next_pic_idx = ((i4_stack_count + 1) % (i4_max_inter_frm_int + 1)); 1331 1332 /* 1333 * Check what is the encoded frm_type 1334 * Changing a B_PIC to a ref_pic is not reqd if 1335 * there are no B_PICs referring from the skipped ref_pic 1336 */ 1337 if(((e_pic_type == P_PIC) || (e_pic_type == I_PIC)) 1338 && (i4_next_pic_idx != i4_next_ref_pic_idx)) 1339 { 1340 /* Go to the last B_PIC before the next_ref_pic */ 1341 if(i4_next_ref_pic_idx == 0) 1342 { 1343 i4_last_b_pic_idx = i4_max_inter_frm_int; 1344 } 1345 else 1346 { 1347 i4_last_b_pic_idx = (i4_next_ref_pic_idx - 1); 1348 } 1349 1350 /* Keep a copy of the last B_PIC pic_details */ 1351 memcpy(&s_pic_details, 1352 &ps_pic_handling->as_pic_stack[i4_last_b_pic_idx], 1353 sizeof(pic_details_t)); 1354 1355 i4_pic_idx = i4_last_b_pic_idx; 1356 i4_first_b_pic_idx = (i4_stack_count + 1) % (i4_max_inter_frm_int + 1); 1357 1358 /* 1359 * All the B_PICs other than the last one, need to be shifted one place 1360 * in the stack 1361 */ 1362 while((i4_pic_idx != i4_stack_count) 1363 && (i4_first_b_pic_idx != i4_last_b_pic_idx)) 1364 { 1365 if(i4_pic_idx == 0) 1366 { 1367 i4_pic_idx = i4_max_inter_frm_int; 1368 } 1369 else 1370 { 1371 i4_pic_idx--; 1372 } 1373 1374 memcpy(&ps_pic_handling->as_pic_stack[(i4_pic_idx + 1) 1375 % (i4_max_inter_frm_int + 1)], 1376 &ps_pic_handling->as_pic_stack[i4_pic_idx], 1377 sizeof(pic_details_t)); 1378 1379 } 1380 1381 /* 1382 * Copy the last B_PIC pic_details to the first B_PIC place and change 1383 * it's pic type to the ref_PIC 1384 */ 1385 /*e_ref_pic_type*/ 1386 ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].e_pic_type = P_PIC; 1387 1388 ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].i4_pic_disp_order_no = 1389 s_pic_details.i4_pic_disp_order_no; 1390 ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].i4_pic_id = 1391 s_pic_details.i4_pic_id; 1392 1393 /* Change the rem_frms_in_prd so that the update works properly */ 1394 if(ps_pic_handling->i4_rem_frms_in_gop[B_PIC] > 0) 1395 { 1396 ps_pic_handling->i4_rem_frms_in_gop[B_PIC]--; 1397 ps_pic_handling->i4_rem_frms_in_gop[P_PIC]++; 1398 } 1399 } 1400 1401 } 1402 1403 /****************************************************************************** 1404 Function Name : flush_frame 1405 Description : Since when a flush frame is called, there will be no valid 1406 frames after it, the last frame cannot be a B_PIC, as there 1407 will be no reference frame for it (Input in display order) 1408 1409 So,this fxn needs to go to the last added pic in the pic_stack. 1410 If it's reference pic don't do anything 1411 If it's a B_PIC, copy it's pic_details and put it in the 1412 place of the next reference pic, changing the pic_type to 1413 P_PIC 1414 *****************************************************************************/ 1415 void irc_flush_frame_from_pic_stack(pic_handling_t *ps_pic_handling) 1416 { 1417 1418 pic_details_t s_prev_pic_details; 1419 1420 /* Get the last entered pic_details (not to be modified here) */ 1421 WORD32 i4_prev_b_pic_idx = ps_pic_handling->i4_prev_b_pic_idx; 1422 WORD32 i4_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx; 1423 WORD32 i4_b_pic_idx = ps_pic_handling->i4_b_pic_idx; 1424 1425 memcpy(&s_prev_pic_details, &ps_pic_handling->s_prev_pic_details, 1426 sizeof(pic_details_t)); 1427 1428 if(s_prev_pic_details.e_pic_type == B_PIC) 1429 { 1430 /* Copy the last B_PIC details to the next reference pic in display order */ 1431 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no = 1432 s_prev_pic_details.i4_pic_disp_order_no; 1433 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id = 1434 s_prev_pic_details.i4_pic_id; 1435 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = P_PIC; 1436 1437 /* 1438 * Modify the last B_PIC pic_type, so that codec gets to know when 1439 * all the buffered frames 1440 * are flushed 1441 */ 1442 ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].e_pic_type = 1443 MAX_PIC_TYPE; 1444 ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].i4_pic_id = -1; 1445 ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].i4_pic_disp_order_no = 1446 -1; 1447 } 1448 else 1449 { 1450 /* 1451 * Modify the next pic_type details in the stack, so that codec gets to 1452 * know when all the 1453 * buffered frames are flushed 1454 */ 1455 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = MAX_PIC_TYPE; 1456 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id = -1; 1457 ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no = -1; 1458 1459 if(ps_pic_handling->i4_inter_frm_int != 1) 1460 { 1461 ps_pic_handling->as_pic_stack[i4_b_pic_idx].e_pic_type = 1462 MAX_PIC_TYPE; 1463 ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_id = -1; 1464 ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_disp_order_no = 1465 -1; 1466 } 1467 } 1468 } 1469 1470 /****************************************************************************** 1471 Function Name : irc_add_pic_to_stack_re_enc 1472 Description : In case of a re-enc, we can assume the pictures to be coming 1473 in the encode order. 1474 In case of re-encoder basically, there are 2 problematic cases. 1475 1)Inter_frm_int is not known to start with 1476 2)Inter_frm_int can keep changing 1477 3)Intra_frm_int set by the application and that actually in the 1478 decoded bitstream may be different 1479 *****************************************************************************/ 1480 WORD32 irc_add_pic_to_stack_re_enc(pic_handling_t *ps_pic_handling, 1481 WORD32 i4_enc_pic_id, 1482 picture_type_e e_pic_type) 1483 { 1484 WORD32 i4_b_count_in_subgop; 1485 WORD32 i4_max_inter_frm_int, i4_inter_frm_int, i4_intra_frm_int; 1486 WORD32 i4_pic_disp_order_no; 1487 WORD32 i4_is_gop_closed; 1488 picture_type_e e_out_pic_type; 1489 WORD32 i4_b_in_incomp_subgop; 1490 1491 /* Check if a change in intra_frm_int call has been made */ 1492 if(ps_pic_handling->i4_change_in_intra_frm_int == 1) 1493 { 1494 irc_update_pic_distbn(ps_pic_handling, 1495 ps_pic_handling->i4_new_intra_frm_int, 1496 ps_pic_handling->i4_inter_frm_int, 1); 1497 ps_pic_handling->i4_change_in_intra_frm_int = 0; 1498 } 1499 1500 /* Check if a change in inter_frm_int call has been made */ 1501 if(ps_pic_handling->i4_change_in_inter_frm_int == 1) 1502 { 1503 irc_update_pic_distbn(ps_pic_handling, 1504 ps_pic_handling->i4_intra_frm_int, 1505 ps_pic_handling->i4_new_inter_frm_int, 1); 1506 1507 ps_pic_handling->i4_change_in_inter_frm_int = 0; 1508 } 1509 1510 /* Initialize the local vars with the state vars */ 1511 i4_b_count_in_subgop = ps_pic_handling->i4_b_count_in_subgop; 1512 i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int; 1513 i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int; 1514 i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int; 1515 i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no; 1516 i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed; 1517 i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop; 1518 1519 e_out_pic_type = e_pic_type; 1520 1521 /* Initially the rate_control assumes an IPP sequence */ 1522 if(e_pic_type == B_PIC) 1523 { 1524 /* Update the number of B_PICs in a subgop */ 1525 i4_b_count_in_subgop++; 1526 1527 if(i4_b_count_in_subgop > i4_max_inter_frm_int) 1528 { 1529 return (-1); 1530 } 1531 1532 /* If the number of B_PICs exceed the set inter_frm_int then 1533 change the inter_frm_int */ 1534 if(i4_b_count_in_subgop > (i4_inter_frm_int - 1)) 1535 { 1536 i4_inter_frm_int = (i4_b_count_in_subgop + 1); 1537 1538 irc_update_pic_distbn(ps_pic_handling, i4_intra_frm_int, 1539 i4_inter_frm_int, 0); 1540 } 1541 } 1542 else if((e_pic_type == I_PIC) || (e_pic_type == P_PIC)) 1543 { 1544 /* If the B_PICs in the prev subgop were fewer than the current 1545 * (inter_frm_int-1) and none of these conditions occur, it'll mean the 1546 * decrease in the inter_frm_int 1547 * 1)End of a GOP 1548 * 2)Beginning of an OPEN_GOP 1549 */ 1550 if((i4_b_count_in_subgop < (i4_inter_frm_int - 1)) 1551 && !((!i4_is_gop_closed) 1552 && (i4_b_count_in_subgop 1553 >= i4_b_in_incomp_subgop)) 1554 && !((i4_pic_disp_order_no 1555 + (i4_inter_frm_int - 1 1556 - i4_b_count_in_subgop)) 1557 > i4_intra_frm_int)) 1558 { 1559 i4_inter_frm_int = (i4_b_count_in_subgop + 1); 1560 1561 irc_update_pic_distbn(ps_pic_handling, i4_intra_frm_int, 1562 i4_inter_frm_int, 0); 1563 } 1564 1565 /* Reset the number of B_PICs in a subgop */ 1566 i4_b_count_in_subgop = 0; 1567 } 1568 1569 /* Updation of the frame level vars */ 1570 i4_pic_disp_order_no++; 1571 1572 /* End of gop condition 1573 *Two cases can arise : 1574 *1) The intra_frm_int set by the application is greater than the actual 1575 * bitstream intra_frm_int (i.e. we will get an I frame before 1576 * pic_disp_order_no goes to intra_frm_int) 1577 *2) The intra_frm_int set by the application is smaller than the actual bitstream intra_frm_int 1578 * (i.e. we won't get an I_PIC even if pic_disp_order_no goes to 1579 * intra_frm_int) Constraints : 1580 * 1) I_PIC cannot be changed to B_PIC 1581 * 2) B_PIC cannot be changed to I_PIC 1582 */ 1583 if(i4_pic_disp_order_no >= i4_intra_frm_int) 1584 { 1585 if(e_pic_type != B_PIC) 1586 { 1587 e_out_pic_type = I_PIC; 1588 } 1589 else 1590 { 1591 e_out_pic_type = B_PIC; 1592 ps_pic_handling->i4_rem_frms_in_gop[B_PIC]++; 1593 ps_pic_handling->i4_frms_in_cur_gop[B_PIC]++; 1594 ps_pic_handling->i4_frms_in_gop[B_PIC]++; 1595 } 1596 } 1597 else 1598 { 1599 if((e_pic_type == I_PIC) && (!ps_pic_handling->i4_is_first_gop)) 1600 { 1601 e_out_pic_type = P_PIC; 1602 ps_pic_handling->i4_rem_frms_in_gop[P_PIC]++; 1603 ps_pic_handling->i4_frms_in_cur_gop[P_PIC]++; 1604 ps_pic_handling->i4_frms_in_gop[P_PIC]++; 1605 } 1606 else 1607 { 1608 e_out_pic_type = e_pic_type; 1609 } 1610 } 1611 1612 /* Update the frm_vars at the end of the gop */ 1613 if(i4_pic_disp_order_no 1614 == (ps_pic_handling->i4_frms_in_cur_gop[P_PIC] 1615 + ps_pic_handling->i4_frms_in_cur_gop[B_PIC] 1616 + 1)) 1617 { 1618 i4_pic_disp_order_no = 0; 1619 ps_pic_handling->i4_is_first_gop = 0; 1620 } 1621 1622 /* Update the vars working on the encoded pics */ 1623 if((ps_pic_handling->i4_is_first_gop) 1624 && (ps_pic_handling->i4_stack_count == -1)) 1625 { 1626 ps_pic_handling->i4_coded_pic_no = 0; 1627 ps_pic_handling->i4_stack_count = 0; 1628 } 1629 1630 /* Add the pic_details to the pic_stack */ 1631 ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].e_pic_type = 1632 e_out_pic_type; 1633 ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no = 1634 ps_pic_handling->i4_pic_disp_order_no; 1635 ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_id = 1636 i4_enc_pic_id; 1637 1638 /* Writing back those values which need to be updated */ 1639 ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int; 1640 ps_pic_handling->i4_pic_disp_order_no = i4_pic_disp_order_no; 1641 ps_pic_handling->i4_b_count_in_subgop = i4_b_count_in_subgop; 1642 1643 return (0); 1644 } 1645