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_modify_frm_rate.c
25 *
26 * @brief
27 *  Functions used to modify frame rate
28 *
29 * @author
30 *  ittiam
31 *
32 * @par List of Functions:
33 *  - ih264e_pd_frm_rate_get_init_free_memtab()
34 *  - ih264e_init_pd_frm_rate()
35 *  - ih264e_update_pd_frm_rate()
36 *  - ih264e_get_pd_avg_frm_rate()
37 *
38 * @remarks
39 *  None
40 *
41 *******************************************************************************
42 */
43 
44 /*****************************************************************************/
45 /* File Includes                                                             */
46 /*****************************************************************************/
47 
48 /* User include files */
49 #include "irc_datatypes.h"
50 #include "iv2.h"
51 #include "ive2.h"
52 #include "ih264_defs.h"
53 #include "ih264_structs.h"
54 #include "ih264_trans_quant_itrans_iquant.h"
55 #include "ih264_inter_pred_filters.h"
56 #include "ih264_mem_fns.h"
57 #include "ih264_padding.h"
58 #include "ih264_intra_pred_filters.h"
59 #include "ih264_deblk_edge_filters.h"
60 #include "ih264_cabac_tables.h"
61 #include "ih264e_error.h"
62 #include "ih264e_bitstream.h"
63 #include "ih264e_defs.h"
64 #include "ime_distortion_metrics.h"
65 #include "ime_defs.h"
66 #include "ime_structs.h"
67 #include "irc_cntrl_param.h"
68 #include "irc_frame_info_collector.h"
69 #include "ih264e_rate_control.h"
70 #include "ih264e_cabac_structs.h"
71 #include "ih264e_structs.h"
72 #include "ih264e_rc_mem_interface.h"
73 #include "ih264e_time_stamp.h"
74 #include "ih264e_modify_frm_rate.h"
75 
76 
77 /*****************************************************************************/
78 /* Function Definitions                                                      */
79 /*****************************************************************************/
80 
81 /**
82 *******************************************************************************
83 *
84 * @brief Function to init pd frame rate memtab
85 *
86 * @par Description
87 *  Function to init pull down frame rate memtab
88 *
89 * @param[in] pps_pd_frm_rate
90 *  pull down frame rate context
91 *
92 * @param[in] ps_memtab
93 *  Handle to memtab
94 *
95 * @param[in] e_func_type
96 *  Function type (get memtab/ update memtab)
97 *
98 * @returns  Number of memtabs used
99 *
100 * @remarks  None
101 *
102 *******************************************************************************
103 */
ih264e_pd_frm_rate_get_init_free_memtab(pd_frm_rate_handle * pps_pd_frm_rate,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)104 WORD32 ih264e_pd_frm_rate_get_init_free_memtab(pd_frm_rate_handle *pps_pd_frm_rate,
105                                                itt_memtab_t *ps_memtab,
106                                                ITT_FUNC_TYPE_E e_func_type)
107 {
108     WORD32 i4_mem_tab_idx = 0;
109     pd_frm_rate_t s_temp_pd_frm_rate_t;
110 
111     /* Hack for al alloc, during which we dont have any state memory.
112      Dereferencing can cause issues */
113     if (e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
114         (*pps_pd_frm_rate) = &s_temp_pd_frm_rate_t;
115 
116     /* for src rate control state structure */
117     if (e_func_type != GET_NUM_MEMTAB)
118     {
119         fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(pd_frm_rate_t),
120                     ALIGN_128_BYTE, PERSISTENT, DDR);
121         use_or_fill_base(&ps_memtab[0], (void**) pps_pd_frm_rate, e_func_type);
122     }
123     i4_mem_tab_idx++;
124 
125     return (i4_mem_tab_idx);
126 }
127 
128 /**
129 *******************************************************************************
130 *
131 * @brief Initializes the pull down frame rate state structure based on input
132 *  frame rate
133 *
134 * @par Description
135 *  Initializes the pull down frame rate state structure based on input frame rate
136 *
137 * @param[in] ps_pd_frm_rate
138 *  Pull down frame rate context
139 *
140 * @param[in] u4_input_frm_rate
141 *  Input frame rate in frame per 1000sec
142 *
143 * @returns none
144 *
145 * @remarks
146 *
147 *******************************************************************************
148 */
ih264e_init_pd_frm_rate(pd_frm_rate_t * ps_pd_frm_rate,UWORD32 u4_input_frm_rate)149 void ih264e_init_pd_frm_rate(pd_frm_rate_t *ps_pd_frm_rate,
150                              UWORD32 u4_input_frm_rate)
151 {
152     WORD32 i;
153 
154     ps_pd_frm_rate->u4_input_frm_rate = u4_input_frm_rate;
155 
156     for (i = 0; i < (WORD32) (u4_input_frm_rate / 1000); i++)
157     {
158         ps_pd_frm_rate->u4_cur_frm_rate[i] = u4_input_frm_rate;
159     }
160 
161     ps_pd_frm_rate->u4_frm_num = 0;
162 
163     ps_pd_frm_rate->u4_tot_frm_encoded = 0;
164 }
165 
166 /**
167 *******************************************************************************
168 *
169 * @brief Function to update pull down frame rate
170 *
171 * @par   Description
172 *  For each frame a run time frame rate value is sent based on whether a frame
173 *  is skipped or not. If it is skipped for pull down then the current frame
174 *  rate for the pull down period is signaled as 4/5th of the original frame
175 *  rate. Thus when this is averaged the frame rate gradually switches from the
176 *  input frame rate to 4/5th of input frame rate as and when more 3:2 pull
177 *  down patterns are detected
178 *
179 * @param[in] ps_pd_frm_rate
180 *  Pull down frame rate context
181 *
182 * @param[in] u4_input_frm_rate
183 *  Input frame rate in frame per 1000sec
184 *
185 * @returns none
186 *
187 * @remarks
188 *
189 *******************************************************************************
190 */
ih264e_update_pd_frm_rate(pd_frm_rate_t * ps_pd_frm_rate,UWORD32 u4_cur_frm_rate)191 void ih264e_update_pd_frm_rate(pd_frm_rate_t *ps_pd_frm_rate,
192                                UWORD32 u4_cur_frm_rate)
193 {
194     ps_pd_frm_rate->u4_cur_frm_rate[ps_pd_frm_rate->u4_frm_num] = u4_cur_frm_rate;
195 
196     ps_pd_frm_rate->u4_frm_num++;
197 
198     /* Increment the frame number */
199     if (ps_pd_frm_rate->u4_tot_frm_encoded < (ps_pd_frm_rate->u4_input_frm_rate / 1000))
200     {
201         ps_pd_frm_rate->u4_tot_frm_encoded++;
202     }
203 
204     /* Reset frm_num to zero  */
205     if (ps_pd_frm_rate->u4_frm_num >= (ps_pd_frm_rate->u4_input_frm_rate / 1000))
206     {
207         ps_pd_frm_rate->u4_frm_num = 0;
208     }
209 }
210 
211 /**
212 *******************************************************************************
213 *
214 * @brief returns average frame rate in 1 sec duration
215 *
216 * @par Description
217 *  Averages the last N frame in period(1 sec) and then gives that
218 *  as the current frames frame rate. Thus this averages out the sudden
219 *  variation in frame rate
220 *
221 * @param[in] ps_pd_frm_rate
222 *  Handle to pull down frame rate context
223 *
224 * @returns average frame rate
225 *
226 * @remarks
227 *
228 *******************************************************************************
229 */
ih264e_get_pd_avg_frm_rate(pd_frm_rate_t * ps_pd_frm_rate)230 UWORD32 ih264e_get_pd_avg_frm_rate(pd_frm_rate_t *ps_pd_frm_rate)
231 {
232     WORD32 i;
233     WORD32 i4_avg_frm_rate = 0;
234 
235     for (i = 0; i < (WORD32) ps_pd_frm_rate->u4_tot_frm_encoded; i++)
236     {
237         i4_avg_frm_rate += ps_pd_frm_rate->u4_cur_frm_rate[i];
238     }
239 
240     i4_avg_frm_rate = i4_avg_frm_rate / ps_pd_frm_rate->u4_tot_frm_encoded;
241 
242     return i4_avg_frm_rate;
243 }
244