• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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