summaryrefslogtreecommitdiffstats
path: root/encoder/ih264e_time_stamp.c
diff options
context:
space:
mode:
Diffstat (limited to 'encoder/ih264e_time_stamp.c')
-rwxr-xr-xencoder/ih264e_time_stamp.c748
1 files changed, 748 insertions, 0 deletions
diff --git a/encoder/ih264e_time_stamp.c b/encoder/ih264e_time_stamp.c
new file mode 100755
index 0000000..a6a7f3c
--- /dev/null
+++ b/encoder/ih264e_time_stamp.c
@@ -0,0 +1,748 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+*/
+
+/**
+*******************************************************************************
+* @file
+* ih264e_time_stamp.c
+*
+* @brief
+* This file contains functions used for source and target time stamp management
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - gcd()
+* - ih264e_get_range()
+* - ih264e_frame_time_get_init_free_memtab()
+* - ih264e_init_frame_time()
+* - ih264e_should_src_be_skipped()
+* - ih264e_time_stamp_get_init_free_memtab()
+* - ih264e_init_time_stamp()
+* - ih264e_update_time_stamp()
+* - ih264e_frame_time_get_src_frame_rate()
+* - ih264e_frame_time_get_tgt_frame_rate()
+* - ih264e_frame_time_get_src_ticks()
+* - ih264e_frame_time_get_tgt_ticks()
+* - ih264e_frame_time_get_src_time()
+* - ih264e_frame_time_get_tgt_time()
+* - ih264e_frame_time_update_src_frame_rate()
+* - ih264e_frame_time_update_tgt_frame_rate()
+* - ih264_time_stamp_update_frame_rate()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* user include files */
+#include "irc_datatypes.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ih264_defs.h"
+#include "ih264e_defs.h"
+#include "ime_distortion_metrics.h"
+#include "ime_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "ih264e_rate_control.h"
+#include "ih264_structs.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264e_structs.h"
+#include "ih264e_rc_mem_interface.h"
+#include "ih264e_time_stamp.h"
+#include "irc_rate_control_api.h"
+
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief Function to compute gcd of two numbers
+*
+* @par Description
+* Function to compute gcd of two numbers
+*
+* @param[in] i4_x
+* value 1
+*
+* @param[in] i4_y
+* value 2
+*
+* @returns
+* GCD(value 1, value 2)
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 gcd(WORD32 i4_x, WORD32 i4_y)
+{
+ if (i4_x > i4_y)
+ {
+ i4_x = i4_y + i4_x;
+ i4_y = i4_x - i4_y;
+ i4_x = i4_x - i4_y;
+ }
+ while (i4_y != 0)
+ {
+ WORD32 temp;
+ i4_x = i4_x % i4_y;
+ temp = i4_x;
+ i4_x = i4_y;
+ i4_y = temp;
+ }
+ return (i4_x);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to determine number of bits required to represent a given
+* value
+*
+* @par Description
+* This function determines the number of bits required to represent the given
+* value. It is used to find out number of bits to read when the data size is
+* not fixed (e.g. vop_time_increment_resolution).
+*
+* @param[in] u4_value
+* Value for which the number of bits required to represent is to be determined
+*
+* @param[in] u1_no_of_bits
+* Represents the value's word type = 8/16/32
+*
+* @returns
+* The number of bits required to represent the given number
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static UWORD8 ih264e_get_range(UWORD32 u4_value, UWORD8 u1_no_of_bits)
+{
+ UWORD8 count;
+ UWORD32 temp;
+
+ if (u4_value > (UWORD32) ((1 << (u1_no_of_bits >> 1)) - 1))
+ {
+ temp = (1 << (u1_no_of_bits - 1));
+ for (count = 0; count < (u1_no_of_bits >> 1); count++)
+ {
+ if ((temp & u4_value) != 0)
+ {
+ return (UWORD8) (u1_no_of_bits - count);
+ }
+ else
+ {
+ temp >>= 1;
+ }
+ }
+ return 0;
+ }
+ else
+ {
+ temp = (1 << ((u1_no_of_bits >> 1) - 1));
+ for (count = 0; count < ((u1_no_of_bits >> 1) - 1); count++)
+ {
+ if ((temp & u4_value) != 0)
+ {
+ return (UWORD8) ((u1_no_of_bits >> 1) - count);
+ }
+ else
+ {
+ temp >>= 1;
+ }
+ }
+ return 1;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to init frame time memtabs
+*
+* @par Description
+* Function to init frame time memtabs
+*
+* @param[in] pps_frame_time
+* Pointer to frame time contexts
+*
+* @param[in] ps_memtab
+* Pointer to memtab
+*
+* @param[in] e_func_type
+* Function type (get memtabs/init memtabs)
+*
+* @returns
+* none
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 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)
+{
+ WORD32 i4_mem_tab_idx = 0;
+ static frame_time_t s_temp_frame_time_t;
+
+ /* Hack for al alloc, during which we dont have any state memory.
+ Dereferencing can cause issues */
+ if (e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
+ (*pps_frame_time) = &s_temp_frame_time_t;
+
+ /* for src rate control state structure */
+ if (e_func_type != GET_NUM_MEMTAB)
+ {
+ fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(frame_time_t),
+ ALIGN_128_BYTE, PERSISTENT, DDR);
+ use_or_fill_base(&ps_memtab[0], (void**) pps_frame_time, e_func_type);
+ }
+ i4_mem_tab_idx++;
+
+ return (i4_mem_tab_idx);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to init frame time context
+*
+* @par Description
+* Frame time structure stores the time of the source and the target frames to
+* be encoded. Based on the time we decide whether or not to encode the source
+* frame
+*
+* @param[in] ps_frame_time
+* Pointer Frame time context
+*
+* @param[in] u4_src_frm_rate
+* Source frame rate
+*
+* @param[in] u4_tgt_frm_rate
+* Target frame rate
+*
+* @returns
+* none
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void ih264e_init_frame_time(frame_time_t *ps_frame_time,
+ UWORD32 u4_src_frm_rate,
+ UWORD32 u4_tgt_frm_rate)
+{
+ /* Initialise the common time base based on which the source and target
+ * frame times increase */
+ WORD32 i4_gcd = gcd(u4_src_frm_rate, u4_tgt_frm_rate);
+
+ ps_frame_time->common_time_base = (u4_src_frm_rate * u4_tgt_frm_rate)
+ / i4_gcd;
+
+ /* The source and target increment per vop is initialized */
+ ps_frame_time->u4_src_frm_time_incr = ps_frame_time->common_time_base
+ / u4_src_frm_rate;
+ ps_frame_time->u4_tgt_frm_time_incr = ps_frame_time->common_time_base
+ / u4_tgt_frm_rate;
+
+ /* Initialise the source and target times to 0 (RESET) */
+ ps_frame_time->u4_src_frm_time = 0;
+ ps_frame_time->u4_tgt_frm_time = 0;
+
+ /* Initialize the number of frms not to be skipped to 0 */
+ ps_frame_time->u4_num_frms_dont_skip = 0;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to check if frame can be skipped
+*
+* @par Description
+* Based on the source and target frame time and the delta time stamp
+* we decide whether to code the source or not.
+* This is based on the assumption
+* that the source frame rate is greater that target frame rate.
+* Updates the time_stamp structure
+*
+* @param[in] ps_frame_time
+* Handle to frame time context
+*
+* @param[in] u4_delta_time_stamp
+* Time stamp difference between frames
+*
+* @param[out] pu4_frm_not_skipped_for_dts
+* Flag to indicate if frame is already skipped by application
+*
+* @returns
+* Flag to skip frame
+*
+* @remarks
+*
+*******************************************************************************
+*/
+UWORD8 ih264e_should_src_be_skipped(frame_time_t *ps_frame_time,
+ UWORD32 u4_delta_time_stamp,
+ UWORD32 *pu4_frm_not_skipped_for_dts)
+{
+ UWORD8 skip_src = 0;
+
+ if (ps_frame_time->u4_tgt_frm_time > ps_frame_time->u4_src_frm_time &&
+ ps_frame_time->u4_tgt_frm_time >= (ps_frame_time->u4_src_frm_time +
+ ps_frame_time->u4_src_frm_time_incr))
+ {
+ skip_src = 1;
+ }
+
+ /* source time gets updated every frame */
+ ps_frame_time->u4_src_frm_time += ps_frame_time->u4_src_frm_time_incr;
+
+ /* target time gets updated only when the source is coded */
+ if (!skip_src)
+ {
+ ps_frame_time->u4_tgt_frm_time += ps_frame_time->u4_tgt_frm_time_incr;
+ }
+
+ /* If the source and target frame times get incremented properly
+ both should be equal to the common time base at the same time. If
+ that happens we reset the time to zero*/
+ if (( ps_frame_time->common_time_base ==(WORD32)ps_frame_time->u4_src_frm_time)
+ && (ps_frame_time->common_time_base ==(WORD32) ps_frame_time->u4_tgt_frm_time ))
+ {
+ ps_frame_time->u4_src_frm_time = 0;
+ ps_frame_time->u4_tgt_frm_time = 0;
+ }
+
+ /* This keeps a count of how many frames need not be skipped in order
+ to take care of the delta time stamp */
+ ps_frame_time->u4_num_frms_dont_skip += (u4_delta_time_stamp - 1);
+
+ /** If this frame is to be skipped in order to maintain the tgt_frm_rate
+ check if already a frame has been skipped by the application.
+ In that case, do not skip this frame **/
+ if (ps_frame_time->u4_num_frms_dont_skip && skip_src)
+ {
+ skip_src = 0;
+ *pu4_frm_not_skipped_for_dts = 1;
+ ps_frame_time->u4_num_frms_dont_skip -= 1;
+ }
+ else
+ {
+ pu4_frm_not_skipped_for_dts[0] = 0;
+ }
+
+ return (skip_src);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to inititialize time stamp memtabs
+*
+* @par Description
+* Function to initialize time stamp memtabs
+*
+* @param[in] pps_time_stamp
+* Pointer to time stamp context
+*
+* @param[in] ps_memtab
+* Pointer to memtab
+*
+* @param[in] e_func_type
+* Funcion type (Get memtab/ init memtab)
+*
+* @returns
+* number of memtabs used
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 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)
+{
+ WORD32 i4_mem_tab_idx = 0;
+ static time_stamp_t s_temp_time_stamp_t;
+
+ /* Hack for al alloc, during which we dont have any state memory.
+ Dereferencing can cause issues */
+ if (e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
+ (*pps_time_stamp) = &s_temp_time_stamp_t;
+
+ /* for src rate control state structure */
+ if (e_func_type != GET_NUM_MEMTAB)
+ {
+ fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(time_stamp_t),
+ ALIGN_128_BYTE, PERSISTENT, DDR);
+ use_or_fill_base(&ps_memtab[0], (void**) pps_time_stamp, e_func_type);
+ }
+ i4_mem_tab_idx++;
+
+ return (i4_mem_tab_idx);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize time stamp context
+*
+* @par Description
+* Time stamp structure stores the time stamp data that
+* needs to be sent in to the header of MPEG4. Based on the
+* max target frame rate the vop_time increment resolution is set
+* so as to support all the frame rates below max frame rate.
+* A support till the third decimal point is assumed.
+*
+* @param[in] ps_time_stamp
+* Pointer to time stamp structure
+*
+* @param[in] u4_max_frm_rate
+* Maximum frame rate
+*
+* @param[in] u4_src_frm_rate
+* Source frame rate
+*
+* @returns
+* none
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void ih264e_init_time_stamp(time_stamp_t *ps_time_stamp,
+ UWORD32 u4_max_frm_rate,
+ UWORD32 u4_src_frm_rate)
+{
+ /* We expect the max frame rate to be less than 60000,
+ * if not we divide it by zero and work with it */
+ if (u4_max_frm_rate > 60000)
+ {
+ u4_max_frm_rate >>= 1;
+ ps_time_stamp->is_max_frame_rate_scaled = 1;
+ }
+ else
+ {
+ ps_time_stamp->is_max_frame_rate_scaled = 0;
+ }
+
+ ps_time_stamp->u4_vop_time_incr_res = u4_max_frm_rate;
+ ps_time_stamp->u4_vop_time_incr_range = ih264e_get_range(u4_max_frm_rate, 32);
+ 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 */
+ ps_time_stamp->u4_vop_time = 0;
+ ps_time_stamp->u4_cur_tgt_vop_time = 0;
+ ps_time_stamp->u4_prev_tgt_vop_time = 0;
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to update time stamp context
+*
+* @par Description
+* Vop time is incremented by increment value. When vop time goes
+* more than the vop time resolution set the modulo time base to
+* 1 and reduce the vop time by vop time resolution so that the
+* excess value is present in vop time and get accumulated over time
+* so that the corresponding frame rate is achieved at a average of
+* 1000 seconds
+*
+* @param[in] ps_time_stamp
+* Pointer to time stamp structure
+*
+* @returns
+* none
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void ih264e_update_time_stamp(time_stamp_t *ps_time_stamp)
+{
+ /* Since get time stamp is called after the update
+ A copy of the vop time and the modulo time is stored */
+ ps_time_stamp->u4_cur_tgt_vop_time = ps_time_stamp->u4_vop_time;
+
+ ps_time_stamp->u4_vop_time += ps_time_stamp->u4_vop_time_incr;
+ if (ps_time_stamp->u4_vop_time >= ps_time_stamp->u4_vop_time_incr_res)
+ {
+ ps_time_stamp->u4_vop_time -= ps_time_stamp->u4_vop_time_incr_res;
+ }
+}
+
+/****************************************************************************
+ Run-Time Modifying functions
+****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief Function to get source frame rate
+*
+* @par Description
+* Function to get source frame rate
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @returns
+* source frame rate
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 ih264e_frame_time_get_src_frame_rate(frame_time_t *ps_frame_time)
+{
+ return (ps_frame_time->common_time_base / ps_frame_time->u4_src_frm_time_incr);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get target frame rate
+*
+* @par Description
+* Function to get target frame rate
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @returns
+* target frame rate
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 ih264e_frame_time_get_tgt_frame_rate(frame_time_t *ps_frame_time)
+{
+ return (ps_frame_time->common_time_base / ps_frame_time->u4_tgt_frm_time_incr);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get source time increment
+*
+* @par Description
+* Function to get source time increment
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @returns
+* source time increment
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 ih264e_frame_time_get_src_ticks(frame_time_t *ps_frame_time)
+{
+ return (ps_frame_time->u4_src_frm_time_incr);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get target time increment
+*
+* @par Description
+* Function to get target time increment
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @returns
+* target time increment
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 ih264e_frame_time_get_tgt_ticks(frame_time_t *ps_frame_time)
+{
+ return (ps_frame_time->u4_tgt_frm_time_incr);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get src frame time
+*
+* @par Description
+* Function to get src frame time
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @returns
+* src frame time
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 ih264e_frame_time_get_src_time(frame_time_t *frame_time)
+{
+ return (frame_time->u4_src_frm_time);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get tgt frame time
+*
+* @par Description
+* Function to get tgt frame time
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @returns
+* tgt frame time
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 ih264e_frame_time_get_tgt_time(frame_time_t *frame_time)
+{
+ return (frame_time->u4_tgt_frm_time);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to update source frame time with a new source frame rate
+*
+* @par Description
+* Function to update source frame time with a new source frame rate
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @param[in] src_frm_rate
+* source frame rate
+*
+* @returns
+* None
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void ih264e_frame_time_update_src_frame_rate(frame_time_t *ps_frame_time,
+ WORD32 src_frm_rate)
+{
+ /* Since tgt frame rate does not change deriving the tgt_frm rate from
+ * common_time_base */
+ WORD32 tgt_frm_rate = ps_frame_time->common_time_base / ps_frame_time->u4_tgt_frm_time_incr;
+
+ /* Re-initialise frame_time based on the new src_frame_rate and
+ * old tgt_frame_rate */
+ ih264e_init_frame_time(ps_frame_time, src_frm_rate, tgt_frm_rate);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to update target frame time with a new source frame rate
+*
+* @par Description
+* Function to update target frame time with a new source frame rate
+*
+* @param[in] ps_frame_time
+* Pointer to frame time context
+*
+* @param[in] tgt_frm_rate
+* target frame rate
+*
+* @returns
+* None
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void ih264e_frame_time_update_tgt_frame_rate(frame_time_t *ps_frame_time,
+ WORD32 tgt_frm_rate)
+{
+ /* Since src frame rate does not change deriving the src_frm rate from
+ * common_time_base */
+ WORD32 src_frm_rate = ps_frame_time->common_time_base / ps_frame_time->u4_src_frm_time_incr;
+
+ /* Re-initialise frame_time based on the new tgt_frame_rate and
+ * old src_frame_rate */
+ ih264e_init_frame_time(ps_frame_time, src_frm_rate, tgt_frm_rate);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to update target frame time with a new source frame rate
+*
+* @par Description
+* When the frame rate changes the time increment is modified by appropriate ticks
+*
+* @param[in] ps_time_stamp
+* Pointer to time stamp structure
+*
+* @param[in] src_frm_rate
+* source frame rate
+*
+* @returns
+* None
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void ih264_time_stamp_update_frame_rate(time_stamp_t *ps_time_stamp,
+ UWORD32 src_frm_rate)
+{
+ 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 */
+}