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 */
gcd(WORD32 i4_x,WORD32 i4_y)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 */
ih264e_get_range(UWORD32 u4_value,UWORD8 u1_no_of_bits)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 */
ih264e_frame_time_get_init_free_memtab(frame_time_handle * pps_frame_time,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)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 */
ih264e_init_frame_time(frame_time_t * ps_frame_time,UWORD32 u4_src_frm_rate,UWORD32 u4_tgt_frm_rate)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 */
ih264e_should_src_be_skipped(frame_time_t * ps_frame_time,UWORD32 u4_delta_time_stamp,UWORD32 * pu4_frm_not_skipped_for_dts)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 */
ih264e_time_stamp_get_init_free_memtab(time_stamp_handle * pps_time_stamp,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)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 */
ih264e_init_time_stamp(time_stamp_t * ps_time_stamp,UWORD32 u4_max_frm_rate,UWORD32 u4_src_frm_rate)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 */
ih264e_update_time_stamp(time_stamp_t * ps_time_stamp)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 */
ih264e_frame_time_get_src_frame_rate(frame_time_t * ps_frame_time)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 */
ih264e_frame_time_get_tgt_frame_rate(frame_time_t * ps_frame_time)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 */
ih264e_frame_time_get_src_ticks(frame_time_t * ps_frame_time)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 */
ih264e_frame_time_get_tgt_ticks(frame_time_t * ps_frame_time)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 */
ih264e_frame_time_get_src_time(frame_time_t * frame_time)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 */
ih264e_frame_time_get_tgt_time(frame_time_t * frame_time)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 */
ih264e_frame_time_update_src_frame_rate(frame_time_t * ps_frame_time,WORD32 src_frm_rate)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 */
ih264e_frame_time_update_tgt_frame_rate(frame_time_t * ps_frame_time,WORD32 tgt_frm_rate)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 */
ih264_time_stamp_update_frame_rate(time_stamp_t * ps_time_stamp,UWORD32 src_frm_rate)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