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 ******************************************************************************* 23 * @file 24 * ih264e_time_stamp.c 25 * 26 * @brief 27 * This file contains functions used for source and target time stamp management 28 * 29 * @author 30 * ittiam 31 * 32 * @par List of Functions: 33 * - gcd() 34 * - ih264e_get_range() 35 * - ih264e_frame_time_get_init_free_memtab() 36 * - ih264e_init_frame_time() 37 * - ih264e_should_src_be_skipped() 38 * - ih264e_time_stamp_get_init_free_memtab() 39 * - ih264e_init_time_stamp() 40 * - ih264e_update_time_stamp() 41 * - ih264e_frame_time_get_src_frame_rate() 42 * - ih264e_frame_time_get_tgt_frame_rate() 43 * - ih264e_frame_time_get_src_ticks() 44 * - ih264e_frame_time_get_tgt_ticks() 45 * - ih264e_frame_time_get_src_time() 46 * - ih264e_frame_time_get_tgt_time() 47 * - ih264e_frame_time_update_src_frame_rate() 48 * - ih264e_frame_time_update_tgt_frame_rate() 49 * - ih264_time_stamp_update_frame_rate() 50 * 51 * @remarks 52 * None 53 * 54 ******************************************************************************* 55 */ 56 57 /*****************************************************************************/ 58 /* File Includes */ 59 /*****************************************************************************/ 60 61 /* user include files */ 62 #include "irc_datatypes.h" 63 #include "iv2.h" 64 #include "ive2.h" 65 #include "ih264e_error.h" 66 #include "ih264e_bitstream.h" 67 #include "ih264_defs.h" 68 #include "ih264e_defs.h" 69 #include "ime_distortion_metrics.h" 70 #include "ime_defs.h" 71 #include "ime_structs.h" 72 #include "irc_cntrl_param.h" 73 #include "irc_frame_info_collector.h" 74 #include "ih264e_rate_control.h" 75 #include "ih264_structs.h" 76 #include "ih264_trans_quant_itrans_iquant.h" 77 #include "ih264_inter_pred_filters.h" 78 #include "ih264_mem_fns.h" 79 #include "ih264_padding.h" 80 #include "ih264_intra_pred_filters.h" 81 #include "ih264_deblk_edge_filters.h" 82 #include "ih264_cabac_tables.h" 83 #include "ih264e_cabac_structs.h" 84 #include "ih264e_structs.h" 85 #include "ih264e_rc_mem_interface.h" 86 #include "ih264e_time_stamp.h" 87 #include "irc_common.h" 88 #include "irc_rate_control_api.h" 89 90 91 /*****************************************************************************/ 92 /* Function Definitions */ 93 /*****************************************************************************/ 94 95 /** 96 ******************************************************************************* 97 * 98 * @brief Function to compute gcd of two numbers 99 * 100 * @par Description 101 * Function to compute gcd of two numbers 102 * 103 * @param[in] i4_x 104 * value 1 105 * 106 * @param[in] i4_y 107 * value 2 108 * 109 * @returns 110 * GCD(value 1, value 2) 111 * 112 * @remarks none 113 * 114 ******************************************************************************* 115 */ 116 static WORD32 gcd(WORD32 i4_x, WORD32 i4_y) 117 { 118 if (i4_x > i4_y) 119 { 120 i4_x = i4_y + i4_x; 121 i4_y = i4_x - i4_y; 122 i4_x = i4_x - i4_y; 123 } 124 while (i4_y != 0) 125 { 126 WORD32 temp; 127 i4_x = i4_x % i4_y; 128 temp = i4_x; 129 i4_x = i4_y; 130 i4_y = temp; 131 } 132 return (i4_x); 133 } 134 135 /** 136 ******************************************************************************* 137 * 138 * @brief Function to determine number of bits required to represent a given 139 * value 140 * 141 * @par Description 142 * This function determines the number of bits required to represent the given 143 * value. It is used to find out number of bits to read when the data size is 144 * not fixed (e.g. vop_time_increment_resolution). 145 * 146 * @param[in] u4_value 147 * Value for which the number of bits required to represent is to be determined 148 * 149 * @param[in] u1_no_of_bits 150 * Represents the value's word type = 8/16/32 151 * 152 * @returns 153 * The number of bits required to represent the given number 154 * 155 * @remarks none 156 * 157 ******************************************************************************* 158 */ 159 static UWORD8 ih264e_get_range(UWORD32 u4_value, UWORD8 u1_no_of_bits) 160 { 161 UWORD8 count; 162 UWORD32 temp; 163 164 if (u4_value > (UWORD32) ((1 << (u1_no_of_bits >> 1)) - 1)) 165 { 166 temp = (1 << (u1_no_of_bits - 1)); 167 for (count = 0; count < (u1_no_of_bits >> 1); count++) 168 { 169 if ((temp & u4_value) != 0) 170 { 171 return (UWORD8) (u1_no_of_bits - count); 172 } 173 else 174 { 175 temp >>= 1; 176 } 177 } 178 return 0; 179 } 180 else 181 { 182 temp = (1 << ((u1_no_of_bits >> 1) - 1)); 183 for (count = 0; count < ((u1_no_of_bits >> 1) - 1); count++) 184 { 185 if ((temp & u4_value) != 0) 186 { 187 return (UWORD8) ((u1_no_of_bits >> 1) - count); 188 } 189 else 190 { 191 temp >>= 1; 192 } 193 } 194 return 1; 195 } 196 } 197 198 /** 199 ******************************************************************************* 200 * 201 * @brief 202 * Function to init frame time memtabs 203 * 204 * @par Description 205 * Function to init frame time memtabs 206 * 207 * @param[in] pps_frame_time 208 * Pointer to frame time contexts 209 * 210 * @param[in] ps_memtab 211 * Pointer to memtab 212 * 213 * @param[in] e_func_type 214 * Function type (get memtabs/init memtabs) 215 * 216 * @returns 217 * none 218 * 219 * @remarks 220 * 221 ******************************************************************************* 222 */ 223 WORD32 ih264e_frame_time_get_init_free_memtab(frame_time_handle *pps_frame_time, 224 itt_memtab_t *ps_memtab, 225 ITT_FUNC_TYPE_E e_func_type) 226 { 227 WORD32 i4_mem_tab_idx = 0; 228 frame_time_t s_temp_frame_time_t; 229 230 /* Hack for al alloc, during which we dont have any state memory. 231 Dereferencing can cause issues */ 232 if (e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) 233 (*pps_frame_time) = &s_temp_frame_time_t; 234 235 /* for src rate control state structure */ 236 if (e_func_type != GET_NUM_MEMTAB) 237 { 238 fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(frame_time_t), 239 ALIGN_128_BYTE, PERSISTENT, DDR); 240 use_or_fill_base(&ps_memtab[0], (void**) pps_frame_time, e_func_type); 241 } 242 i4_mem_tab_idx++; 243 244 return (i4_mem_tab_idx); 245 } 246 247 /** 248 ******************************************************************************* 249 * 250 * @brief 251 * Function to init frame time context 252 * 253 * @par Description 254 * Frame time structure stores the time of the source and the target frames to 255 * be encoded. Based on the time we decide whether or not to encode the source 256 * frame 257 * 258 * @param[in] ps_frame_time 259 * Pointer Frame time context 260 * 261 * @param[in] u4_src_frm_rate 262 * Source frame rate 263 * 264 * @param[in] u4_tgt_frm_rate 265 * Target frame rate 266 * 267 * @returns 268 * none 269 * 270 * @remarks 271 * 272 ******************************************************************************* 273 */ 274 void ih264e_init_frame_time(frame_time_t *ps_frame_time, 275 UWORD32 u4_src_frm_rate, 276 UWORD32 u4_tgt_frm_rate) 277 { 278 /* Initialise the common time base based on which the source and target 279 * frame times increase */ 280 WORD32 i4_gcd = gcd(u4_src_frm_rate, u4_tgt_frm_rate); 281 282 /* Avoiding overflow by doing calculations in float */ 283 number_t s_src_frm_rate, s_tgt_frm_rate, s_gcd, s_common_time_base, s_numerator; 284 285 SET_VAR_Q(s_src_frm_rate, u4_src_frm_rate, 0); 286 SET_VAR_Q(s_tgt_frm_rate, u4_tgt_frm_rate, 0); 287 SET_VAR_Q(s_gcd, i4_gcd, 0); 288 mult32_var_q(s_src_frm_rate, s_tgt_frm_rate, &s_numerator); 289 div32_var_q(s_numerator, s_gcd, &s_common_time_base); 290 number_t_to_word32(s_common_time_base, &(ps_frame_time->common_time_base)); 291 292 /* The source and target increment per vop is initialized */ 293 ps_frame_time->u4_src_frm_time_incr = ps_frame_time->common_time_base 294 / u4_src_frm_rate; 295 ps_frame_time->u4_tgt_frm_time_incr = ps_frame_time->common_time_base 296 / u4_tgt_frm_rate; 297 298 /* Initialise the source and target times to 0 (RESET) */ 299 ps_frame_time->u4_src_frm_time = 0; 300 ps_frame_time->u4_tgt_frm_time = 0; 301 302 /* Initialize the number of frms not to be skipped to 0 */ 303 ps_frame_time->u4_num_frms_dont_skip = 0; 304 } 305 306 /** 307 ******************************************************************************* 308 * 309 * @brief 310 * Function to check if frame can be skipped 311 * 312 * @par Description 313 * Based on the source and target frame time and the delta time stamp 314 * we decide whether to code the source or not. 315 * This is based on the assumption 316 * that the source frame rate is greater that target frame rate. 317 * Updates the time_stamp structure 318 * 319 * @param[in] ps_frame_time 320 * Handle to frame time context 321 * 322 * @param[in] u4_delta_time_stamp 323 * Time stamp difference between frames 324 * 325 * @param[out] pu4_frm_not_skipped_for_dts 326 * Flag to indicate if frame is already skipped by application 327 * 328 * @returns 329 * Flag to skip frame 330 * 331 * @remarks 332 * 333 ******************************************************************************* 334 */ 335 UWORD8 ih264e_should_src_be_skipped(frame_time_t *ps_frame_time, 336 UWORD32 u4_delta_time_stamp, 337 UWORD32 *pu4_frm_not_skipped_for_dts) 338 { 339 UWORD8 skip_src = 0; 340 341 if (ps_frame_time->u4_tgt_frm_time > ps_frame_time->u4_src_frm_time && 342 ps_frame_time->u4_tgt_frm_time >= (ps_frame_time->u4_src_frm_time + 343 ps_frame_time->u4_src_frm_time_incr)) 344 { 345 skip_src = 1; 346 } 347 348 /* source time gets updated every frame */ 349 ps_frame_time->u4_src_frm_time += ps_frame_time->u4_src_frm_time_incr; 350 351 /* target time gets updated only when the source is coded */ 352 if (!skip_src) 353 { 354 ps_frame_time->u4_tgt_frm_time += ps_frame_time->u4_tgt_frm_time_incr; 355 } 356 357 /* If the source and target frame times get incremented properly 358 both should be equal to the common time base at the same time. If 359 that happens we reset the time to zero*/ 360 if (( ps_frame_time->common_time_base ==(WORD32)ps_frame_time->u4_src_frm_time) 361 && (ps_frame_time->common_time_base ==(WORD32) ps_frame_time->u4_tgt_frm_time )) 362 { 363 ps_frame_time->u4_src_frm_time = 0; 364 ps_frame_time->u4_tgt_frm_time = 0; 365 } 366 367 /* This keeps a count of how many frames need not be skipped in order 368 to take care of the delta time stamp */ 369 ps_frame_time->u4_num_frms_dont_skip += (u4_delta_time_stamp - 1); 370 371 /** If this frame is to be skipped in order to maintain the tgt_frm_rate 372 check if already a frame has been skipped by the application. 373 In that case, do not skip this frame **/ 374 if (ps_frame_time->u4_num_frms_dont_skip && skip_src) 375 { 376 skip_src = 0; 377 *pu4_frm_not_skipped_for_dts = 1; 378 ps_frame_time->u4_num_frms_dont_skip -= 1; 379 } 380 else 381 { 382 pu4_frm_not_skipped_for_dts[0] = 0; 383 } 384 385 return (skip_src); 386 } 387 388 /** 389 ******************************************************************************* 390 * 391 * @brief 392 * Function to inititialize time stamp memtabs 393 * 394 * @par Description 395 * Function to initialize time stamp memtabs 396 * 397 * @param[in] pps_time_stamp 398 * Pointer to time stamp context 399 * 400 * @param[in] ps_memtab 401 * Pointer to memtab 402 * 403 * @param[in] e_func_type 404 * Funcion type (Get memtab/ init memtab) 405 * 406 * @returns 407 * number of memtabs used 408 * 409 * @remarks 410 * 411 ******************************************************************************* 412 */ 413 WORD32 ih264e_time_stamp_get_init_free_memtab(time_stamp_handle *pps_time_stamp, 414 itt_memtab_t *ps_memtab, 415 ITT_FUNC_TYPE_E e_func_type) 416 { 417 WORD32 i4_mem_tab_idx = 0; 418 time_stamp_t s_temp_time_stamp_t; 419 420 /* Hack for al alloc, during which we dont have any state memory. 421 Dereferencing can cause issues */ 422 if (e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) 423 (*pps_time_stamp) = &s_temp_time_stamp_t; 424 425 /* for src rate control state structure */ 426 if (e_func_type != GET_NUM_MEMTAB) 427 { 428 fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(time_stamp_t), 429 ALIGN_128_BYTE, PERSISTENT, DDR); 430 use_or_fill_base(&ps_memtab[0], (void**) pps_time_stamp, e_func_type); 431 } 432 i4_mem_tab_idx++; 433 434 return (i4_mem_tab_idx); 435 } 436 437 /** 438 ******************************************************************************* 439 * 440 * @brief 441 * Function to initialize time stamp context 442 * 443 * @par Description 444 * Time stamp structure stores the time stamp data that 445 * needs to be sent in to the header of MPEG4. Based on the 446 * max target frame rate the vop_time increment resolution is set 447 * so as to support all the frame rates below max frame rate. 448 * A support till the third decimal point is assumed. 449 * 450 * @param[in] ps_time_stamp 451 * Pointer to time stamp structure 452 * 453 * @param[in] u4_max_frm_rate 454 * Maximum frame rate 455 * 456 * @param[in] u4_src_frm_rate 457 * Source frame rate 458 * 459 * @returns 460 * none 461 * 462 * @remarks 463 * 464 ******************************************************************************* 465 */ 466 void ih264e_init_time_stamp(time_stamp_t *ps_time_stamp, 467 UWORD32 u4_max_frm_rate, 468 UWORD32 u4_src_frm_rate) 469 { 470 /* We expect the max frame rate to be less than 60000, 471 * if not we divide it by zero and work with it */ 472 if (u4_max_frm_rate > 60000) 473 { 474 u4_max_frm_rate >>= 1; 475 ps_time_stamp->is_max_frame_rate_scaled = 1; 476 } 477 else 478 { 479 ps_time_stamp->is_max_frame_rate_scaled = 0; 480 } 481 482 ps_time_stamp->u4_vop_time_incr_res = u4_max_frm_rate; 483 ps_time_stamp->u4_vop_time_incr_range = ih264e_get_range(u4_max_frm_rate, 32); 484 ps_time_stamp->u4_vop_time_incr = (ps_time_stamp->u4_vop_time_incr_res * 1000) / u4_src_frm_rate;/* Since frm rate is in millisec */ 485 ps_time_stamp->u4_vop_time = 0; 486 ps_time_stamp->u4_cur_tgt_vop_time = 0; 487 ps_time_stamp->u4_prev_tgt_vop_time = 0; 488 } 489 490 /** 491 ******************************************************************************* 492 * 493 * @brief Function to update time stamp context 494 * 495 * @par Description 496 * Vop time is incremented by increment value. When vop time goes 497 * more than the vop time resolution set the modulo time base to 498 * 1 and reduce the vop time by vop time resolution so that the 499 * excess value is present in vop time and get accumulated over time 500 * so that the corresponding frame rate is achieved at a average of 501 * 1000 seconds 502 * 503 * @param[in] ps_time_stamp 504 * Pointer to time stamp structure 505 * 506 * @returns 507 * none 508 * 509 * @remarks 510 * 511 ******************************************************************************* 512 */ 513 void ih264e_update_time_stamp(time_stamp_t *ps_time_stamp) 514 { 515 /* Since get time stamp is called after the update 516 A copy of the vop time and the modulo time is stored */ 517 ps_time_stamp->u4_cur_tgt_vop_time = ps_time_stamp->u4_vop_time; 518 519 ps_time_stamp->u4_vop_time += ps_time_stamp->u4_vop_time_incr; 520 if (ps_time_stamp->u4_vop_time >= ps_time_stamp->u4_vop_time_incr_res) 521 { 522 ps_time_stamp->u4_vop_time -= ps_time_stamp->u4_vop_time_incr_res; 523 } 524 } 525 526 /**************************************************************************** 527 Run-Time Modifying functions 528 ****************************************************************************/ 529 530 /** 531 ******************************************************************************* 532 * 533 * @brief Function to get source frame rate 534 * 535 * @par Description 536 * Function to get source frame rate 537 * 538 * @param[in] ps_frame_time 539 * Pointer to frame time context 540 * 541 * @returns 542 * source frame rate 543 * 544 * @remarks 545 * 546 ******************************************************************************* 547 */ 548 WORD32 ih264e_frame_time_get_src_frame_rate(frame_time_t *ps_frame_time) 549 { 550 return (ps_frame_time->common_time_base / ps_frame_time->u4_src_frm_time_incr); 551 } 552 553 /** 554 ******************************************************************************* 555 * 556 * @brief Function to get target frame rate 557 * 558 * @par Description 559 * Function to get target frame rate 560 * 561 * @param[in] ps_frame_time 562 * Pointer to frame time context 563 * 564 * @returns 565 * target frame rate 566 * 567 * @remarks 568 * 569 ******************************************************************************* 570 */ 571 WORD32 ih264e_frame_time_get_tgt_frame_rate(frame_time_t *ps_frame_time) 572 { 573 return (ps_frame_time->common_time_base / ps_frame_time->u4_tgt_frm_time_incr); 574 } 575 576 /** 577 ******************************************************************************* 578 * 579 * @brief Function to get source time increment 580 * 581 * @par Description 582 * Function to get source time increment 583 * 584 * @param[in] ps_frame_time 585 * Pointer to frame time context 586 * 587 * @returns 588 * source time increment 589 * 590 * @remarks 591 * 592 ******************************************************************************* 593 */ 594 WORD32 ih264e_frame_time_get_src_ticks(frame_time_t *ps_frame_time) 595 { 596 return (ps_frame_time->u4_src_frm_time_incr); 597 } 598 599 /** 600 ******************************************************************************* 601 * 602 * @brief Function to get target time increment 603 * 604 * @par Description 605 * Function to get target time increment 606 * 607 * @param[in] ps_frame_time 608 * Pointer to frame time context 609 * 610 * @returns 611 * target time increment 612 * 613 * @remarks 614 * 615 ******************************************************************************* 616 */ 617 WORD32 ih264e_frame_time_get_tgt_ticks(frame_time_t *ps_frame_time) 618 { 619 return (ps_frame_time->u4_tgt_frm_time_incr); 620 } 621 622 /** 623 ******************************************************************************* 624 * 625 * @brief Function to get src frame time 626 * 627 * @par Description 628 * Function to get src frame time 629 * 630 * @param[in] ps_frame_time 631 * Pointer to frame time context 632 * 633 * @returns 634 * src frame time 635 * 636 * @remarks 637 * 638 ******************************************************************************* 639 */ 640 WORD32 ih264e_frame_time_get_src_time(frame_time_t *frame_time) 641 { 642 return (frame_time->u4_src_frm_time); 643 } 644 645 /** 646 ******************************************************************************* 647 * 648 * @brief Function to get tgt frame time 649 * 650 * @par Description 651 * Function to get tgt frame time 652 * 653 * @param[in] ps_frame_time 654 * Pointer to frame time context 655 * 656 * @returns 657 * tgt frame time 658 * 659 * @remarks 660 * 661 ******************************************************************************* 662 */ 663 WORD32 ih264e_frame_time_get_tgt_time(frame_time_t *frame_time) 664 { 665 return (frame_time->u4_tgt_frm_time); 666 } 667 668 /** 669 ******************************************************************************* 670 * 671 * @brief Function to update source frame time with a new source frame rate 672 * 673 * @par Description 674 * Function to update source frame time with a new source frame rate 675 * 676 * @param[in] ps_frame_time 677 * Pointer to frame time context 678 * 679 * @param[in] src_frm_rate 680 * source frame rate 681 * 682 * @returns 683 * None 684 * 685 * @remarks 686 * 687 ******************************************************************************* 688 */ 689 void ih264e_frame_time_update_src_frame_rate(frame_time_t *ps_frame_time, 690 WORD32 src_frm_rate) 691 { 692 /* Since tgt frame rate does not change deriving the tgt_frm rate from 693 * common_time_base */ 694 WORD32 tgt_frm_rate = ps_frame_time->common_time_base / ps_frame_time->u4_tgt_frm_time_incr; 695 696 /* Re-initialise frame_time based on the new src_frame_rate and 697 * old tgt_frame_rate */ 698 ih264e_init_frame_time(ps_frame_time, src_frm_rate, tgt_frm_rate); 699 } 700 701 /** 702 ******************************************************************************* 703 * 704 * @brief Function to update target frame time with a new source frame rate 705 * 706 * @par Description 707 * Function to update target frame time with a new source frame rate 708 * 709 * @param[in] ps_frame_time 710 * Pointer to frame time context 711 * 712 * @param[in] tgt_frm_rate 713 * target frame rate 714 * 715 * @returns 716 * None 717 * 718 * @remarks 719 * 720 ******************************************************************************* 721 */ 722 void ih264e_frame_time_update_tgt_frame_rate(frame_time_t *ps_frame_time, 723 WORD32 tgt_frm_rate) 724 { 725 /* Since src frame rate does not change deriving the src_frm rate from 726 * common_time_base */ 727 WORD32 src_frm_rate = ps_frame_time->common_time_base / ps_frame_time->u4_src_frm_time_incr; 728 729 /* Re-initialise frame_time based on the new tgt_frame_rate and 730 * old src_frame_rate */ 731 ih264e_init_frame_time(ps_frame_time, src_frm_rate, tgt_frm_rate); 732 } 733 734 /** 735 ******************************************************************************* 736 * 737 * @brief Function to update target frame time with a new source frame rate 738 * 739 * @par Description 740 * When the frame rate changes the time increment is modified by appropriate ticks 741 * 742 * @param[in] ps_time_stamp 743 * Pointer to time stamp structure 744 * 745 * @param[in] src_frm_rate 746 * source frame rate 747 * 748 * @returns 749 * None 750 * 751 * @remarks 752 * 753 ******************************************************************************* 754 */ 755 void ih264_time_stamp_update_frame_rate(time_stamp_t *ps_time_stamp, 756 UWORD32 src_frm_rate) 757 { 758 ps_time_stamp->u4_vop_time_incr = (ps_time_stamp->u4_vop_time_incr_res * 1000) / src_frm_rate;/* Since frm rate is in millisec */ 759 } 760