1 /******************************************************************************
2 *
3 * Copyright (C) 2018 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 * \file fixed_point_error_bits.c
23 *
24 * \brief
25 * This file contain error bits processing functions
26 *
27 * \date
28 * 15/02/2012
29 *
30 * \author
31 * ittiam
32 *
33 ******************************************************************************
34 */
35 /*****************************************************************************/
36 /* File Includes */
37 /*****************************************************************************/
38
39 /* System include files */
40 #include <stdio.h>
41
42 /* User include files */
43 #include "ittiam_datatypes.h"
44 #include "rc_common.h"
45 #include "rc_cntrl_param.h"
46 #include "var_q_operator.h"
47 #include "mem_req_and_acq.h"
48 #include "fixed_point_error_bits.h"
49
50 /*i4_max_tgt_frm_rate and i4_tgt_frm_rate hold same value so removing one*/
51 typedef struct error_bits_t
52 {
53 /* WORD32 i4_max_tgt_frm_rate; */ /*Max tgt frm rate so that dynamic change infrm rate can be handled */
54 WORD32 i4_accum_frm_rate; /* Cur frm rate */
55 WORD32 i4_tgt_frm_rate; /* tgt frame rate*/
56 WORD32 i4_tgt_frm_rate_incr; /* tgt frm rate increment */
57 UWORD8 u1_compute_error_bits; /* flag to indicate 1 second is up*/
58 WORD32 i4_accum_bitrate; /* Bitrate/frame rate value added over a period*/
59 WORD32 i4_bitrate; /* bitrate */
60 } error_bits_t;
61
62 #if NON_STEADSTATE_CODE
error_bits_num_fill_use_free_memtab(error_bits_t ** pps_error_bits,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)63 WORD32 error_bits_num_fill_use_free_memtab(
64 error_bits_t **pps_error_bits, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
65 {
66 WORD32 i4_mem_tab_idx = 0;
67 static error_bits_t s_error_bits_temp;
68
69 /* Hack for al alloc, during which we dont have any state memory.
70 Dereferencing can cause issues */
71 if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
72 (*pps_error_bits) = &s_error_bits_temp;
73
74 /*for src rate control state structure*/
75 if(e_func_type != GET_NUM_MEMTAB)
76 {
77 fill_memtab(
78 &ps_memtab[i4_mem_tab_idx], sizeof(error_bits_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR);
79 use_or_fill_base(&ps_memtab[0], (void **)pps_error_bits, e_func_type);
80 }
81 i4_mem_tab_idx++;
82
83 return (i4_mem_tab_idx);
84 }
85
86 /* ******************************************************************************/
87 /**
88 * @brief Calculates the error bits due to fixed point divisions
89 *
90 * @param ps_error_bits
91 * @param i4_tgt_frm_rate
92 * @param i4_bitrate
93 */
94 /* ******************************************************************************/
init_error_bits(error_bits_t * ps_error_bits,WORD32 i4_tgt_frm_rate,WORD32 i4_bitrate)95 void init_error_bits(error_bits_t *ps_error_bits, WORD32 i4_tgt_frm_rate, WORD32 i4_bitrate)
96 {
97 /* This value is incremented every at the end of every VOP by i4_tgt_frm_rate_incr*/
98 /* Initializing the parameters*/
99 ps_error_bits->i4_accum_frm_rate = 0;
100 ps_error_bits->i4_tgt_frm_rate = i4_tgt_frm_rate;
101
102 /* Value by which i4_accum_frm_rate is incremented every VOP*/
103 ps_error_bits->i4_tgt_frm_rate_incr = 1000;
104
105 /*Compute error bits is set to 1 at the end of 1 second*/
106 ps_error_bits->u1_compute_error_bits = 0;
107 ps_error_bits->i4_tgt_frm_rate = i4_tgt_frm_rate;
108 ps_error_bits->i4_accum_bitrate = 0;
109 ps_error_bits->i4_bitrate = i4_bitrate;
110 }
111
112 #endif /* #if NON_STEADSTATE_CODE */
113
114 /* ******************************************************************************/
115 /**
116 * @brief Updates the error state
117 *
118 * @param ps_error_bits
119 */
120 /* ******************************************************************************/
update_error_bits(error_bits_t * ps_error_bits)121 void update_error_bits(error_bits_t *ps_error_bits)
122 {
123 WORD32 i4_bits_per_frame;
124
125 X_PROD_Y_DIV_Z(
126 ps_error_bits->i4_bitrate, 1000, ps_error_bits->i4_tgt_frm_rate, i4_bits_per_frame);
127
128 if(ps_error_bits->u1_compute_error_bits == 1)
129 {
130 ps_error_bits->i4_accum_bitrate = 0;
131 //ps_error_bits->i4_accum_frm_rate -= ps_error_bits->i4_tgt_frm_rate;
132 ps_error_bits->i4_accum_frm_rate = 0;
133 }
134 /* This value is incremented every at the end of every VOP by
135 i4_tgt_frm_rate_incr*/
136 ps_error_bits->i4_accum_frm_rate += ps_error_bits->i4_tgt_frm_rate_incr;
137 ps_error_bits->i4_accum_bitrate += i4_bits_per_frame;
138
139 /* When current tgt frm rate is equal or greater than max tgt fram rate
140 1 second is up , compute the error bits */
141 if(ps_error_bits->i4_accum_frm_rate >= ps_error_bits->i4_tgt_frm_rate)
142 {
143 /* ps_error_bits->i4_accum_frm_rate -= ps_error_bits->i4_tgt_frm_rate; */
144 ps_error_bits->u1_compute_error_bits = 1;
145 }
146 else
147 {
148 ps_error_bits->u1_compute_error_bits = 0;
149 }
150 }
151
152 /* ******************************************************************************/
153 /**
154 * @brief Returns the error bits for the current frame if there are any
155 *
156 * @param ps_error_bits
157 *
158 * @return
159 */
160 /* ******************************************************************************/
get_error_bits(error_bits_t * ps_error_bits)161 WORD32 get_error_bits(error_bits_t *ps_error_bits)
162 {
163 WORD32 i4_error_bits = 0;
164 /*If 1s is up calcualte error for the last 1s worth fo frames*/
165 if(ps_error_bits->u1_compute_error_bits == 1)
166 {
167 WORD32 i4_cur_bitrate;
168 WORD32 i4_cur_frame_rate = ps_error_bits->i4_accum_frm_rate;
169 /* For frame rates like 29.970, the current frame rate would be a multiple of
170 1000 and every 100 seconds 3 frames would be dropped. So the error should be
171 calculated based on actual frame rate. So for e.g. the iteration, there would be
172 30 frames and so the bits allocated would be (30/29.970)*bitrate */
173 X_PROD_Y_DIV_Z(
174 ps_error_bits->i4_bitrate,
175 i4_cur_frame_rate,
176 ps_error_bits->i4_tgt_frm_rate,
177 i4_cur_bitrate);
178 /*Error = Actual bitrate - bits_per_frame * num of frames*/
179 i4_error_bits = i4_cur_bitrate - ps_error_bits->i4_accum_bitrate;
180 }
181 return (i4_error_bits);
182 }
183 /* ******************************************************************************/
184 /**
185 * @brief Change the bitrate value for error bits module
186 *
187 * @param ps_error_bits
188 * @param i4_bitrate
189 */
190 /* ******************************************************************************/
change_bitrate_in_error_bits(error_bits_t * ps_error_bits,WORD32 i4_bitrate)191 void change_bitrate_in_error_bits(error_bits_t *ps_error_bits, WORD32 i4_bitrate)
192 {
193 /*here accum_bitrate would have accumulated the value based on old bit rate. after one second is elapsed
194 * the error is calcluated based on new bit rate which would result in huge error value. to avoid this
195 * accum_bitrate value is recalculated assuming new bitrate.
196 */
197 /*#ifdef DYNAMIC_RC*/
198 WORD32 i4_old_bits_per_frame;
199 WORD32 i4_new_bits_per_frame;
200 WORD32 i4_frame_count;
201 X_PROD_Y_DIV_Z(
202 ps_error_bits->i4_bitrate, 1000, ps_error_bits->i4_tgt_frm_rate, i4_old_bits_per_frame);
203 i4_frame_count = ps_error_bits->i4_accum_bitrate / i4_old_bits_per_frame;
204 X_PROD_Y_DIV_Z(i4_bitrate, 1000, ps_error_bits->i4_tgt_frm_rate, i4_new_bits_per_frame);
205 ps_error_bits->i4_accum_bitrate = i4_frame_count * i4_new_bits_per_frame;
206
207 /*#endif*/
208 /*change bit rate*/
209 ps_error_bits->i4_bitrate = i4_bitrate;
210 /* ps_error_bits->i4_accum_bitrate=i4_bitrate;*/
211 }
212 /* ******************************************************************************/
213 /**
214 * @brief Change the frame rate parameter for the error bits state
215 *
216 * @param ps_error_bits
217 * @param i4_tgt_frm_rate
218 */
219 /* ******************************************************************************/
220 /*IMPLEMENTATION NOT TESTED*/
221
change_frm_rate_in_error_bits(error_bits_t * ps_error_bits,WORD32 i4_tgt_frm_rate)222 void change_frm_rate_in_error_bits(error_bits_t *ps_error_bits, WORD32 i4_tgt_frm_rate)
223 {
224 /* Value by which i4_accum_frm_rate is incremented every VOP*/
225 /*accum_frm_rate is used to mark one second mark so a change in frame rate could alter this mark leading
226 * to very high accum bitrate value. To avoid this accum_frame_rate is recalculated
227 * according to new value
228 */
229 /* WORD32 i4_frame_count;*/
230
231 /* ps_error_bits->i4_accum_frm_rate=(ps_error_bits->i4_accum_frm_rate*i4_tgt_frm_rate)/ps_error_bits->i4_tgt_frm_rate);*/
232
233 if(ps_error_bits->i4_tgt_frm_rate != i4_tgt_frm_rate)
234 X_PROD_Y_DIV_Z(
235 ps_error_bits->i4_accum_frm_rate,
236 i4_tgt_frm_rate,
237 ps_error_bits->i4_tgt_frm_rate,
238 ps_error_bits->i4_accum_frm_rate);
239
240 /*round off the accum value to multiple of 1000*/
241 ps_error_bits->i4_accum_frm_rate = ps_error_bits->i4_accum_frm_rate / 1000;
242 ps_error_bits->i4_accum_frm_rate = ps_error_bits->i4_accum_frm_rate * 1000;
243
244 /* ps_error_bits->i4_tgt_frm_rate_incr = (ps_error_bits->i4_tgt_frm_rate
245 * 1000)/ i4_tgt_frm_rate;
246 */
247 ps_error_bits->i4_tgt_frm_rate = i4_tgt_frm_rate;
248 }
249