ih264e_time_stamp.c revision bb1543bd8596700ab12a5968e73a9794e26fd4de
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*/
116static 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*/
159static 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*/
223WORD32 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*/
274void 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*/
335UWORD8 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*/
413WORD32 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*/
466void 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*/
513void 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*/
548WORD32 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*/
571WORD32 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*/
594WORD32 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*/
617WORD32 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*/
640WORD32 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*/
663WORD32 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*/
689void 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*/
722void 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*/
755void 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