/src/libhevc/encoder/fixed_point_error_bits.c
Line | Count | Source (jump to first uncovered line) |
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 |
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 | 229k | { |
66 | 229k | WORD32 i4_mem_tab_idx = 0; |
67 | 229k | 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 | 229k | if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) |
72 | 197k | (*pps_error_bits) = &s_error_bits_temp; |
73 | | |
74 | | /*for src rate control state structure*/ |
75 | 229k | if(e_func_type != GET_NUM_MEMTAB) |
76 | 98.5k | { |
77 | 98.5k | fill_memtab( |
78 | 98.5k | &ps_memtab[i4_mem_tab_idx], sizeof(error_bits_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR); |
79 | 98.5k | use_or_fill_base(&ps_memtab[0], (void **)pps_error_bits, e_func_type); |
80 | 98.5k | } |
81 | 229k | i4_mem_tab_idx++; |
82 | | |
83 | 229k | return (i4_mem_tab_idx); |
84 | 229k | } |
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 | | /* ******************************************************************************/ |
95 | | void init_error_bits(error_bits_t *ps_error_bits, WORD32 i4_tgt_frm_rate, WORD32 i4_bitrate) |
96 | 21.0k | { |
97 | | /* This value is incremented every at the end of every VOP by i4_tgt_frm_rate_incr*/ |
98 | | /* Initializing the parameters*/ |
99 | 21.0k | ps_error_bits->i4_accum_frm_rate = 0; |
100 | 21.0k | 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 | 21.0k | 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 | 21.0k | ps_error_bits->u1_compute_error_bits = 0; |
107 | 21.0k | ps_error_bits->i4_tgt_frm_rate = i4_tgt_frm_rate; |
108 | 21.0k | ps_error_bits->i4_accum_bitrate = 0; |
109 | 21.0k | ps_error_bits->i4_bitrate = i4_bitrate; |
110 | 21.0k | } |
111 | | |
112 | | #endif /* #if NON_STEADSTATE_CODE */ |
113 | | |
114 | | /* ******************************************************************************/ |
115 | | /** |
116 | | * @brief Updates the error state |
117 | | * |
118 | | * @param ps_error_bits |
119 | | */ |
120 | | /* ******************************************************************************/ |
121 | | void update_error_bits(error_bits_t *ps_error_bits) |
122 | 402k | { |
123 | 402k | WORD32 i4_bits_per_frame; |
124 | | |
125 | 402k | X_PROD_Y_DIV_Z( |
126 | 402k | ps_error_bits->i4_bitrate, 1000, ps_error_bits->i4_tgt_frm_rate, i4_bits_per_frame); |
127 | | |
128 | 402k | if(ps_error_bits->u1_compute_error_bits == 1) |
129 | 9.17k | { |
130 | 9.17k | ps_error_bits->i4_accum_bitrate = 0; |
131 | | //ps_error_bits->i4_accum_frm_rate -= ps_error_bits->i4_tgt_frm_rate; |
132 | 9.17k | ps_error_bits->i4_accum_frm_rate = 0; |
133 | 9.17k | } |
134 | | /* This value is incremented every at the end of every VOP by |
135 | | i4_tgt_frm_rate_incr*/ |
136 | 402k | ps_error_bits->i4_accum_frm_rate += ps_error_bits->i4_tgt_frm_rate_incr; |
137 | 402k | 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 | 402k | if(ps_error_bits->i4_accum_frm_rate >= ps_error_bits->i4_tgt_frm_rate) |
142 | 9.27k | { |
143 | | /* ps_error_bits->i4_accum_frm_rate -= ps_error_bits->i4_tgt_frm_rate; */ |
144 | 9.27k | ps_error_bits->u1_compute_error_bits = 1; |
145 | 9.27k | } |
146 | 392k | else |
147 | 392k | { |
148 | 392k | ps_error_bits->u1_compute_error_bits = 0; |
149 | 392k | } |
150 | 402k | } |
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 | | /* ******************************************************************************/ |
161 | | WORD32 get_error_bits(error_bits_t *ps_error_bits) |
162 | 604k | { |
163 | 604k | WORD32 i4_error_bits = 0; |
164 | | /*If 1s is up calcualte error for the last 1s worth fo frames*/ |
165 | 604k | if(ps_error_bits->u1_compute_error_bits == 1) |
166 | 12.1k | { |
167 | 12.1k | WORD32 i4_cur_bitrate; |
168 | 12.1k | 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 | 12.1k | X_PROD_Y_DIV_Z( |
174 | 12.1k | ps_error_bits->i4_bitrate, |
175 | 12.1k | i4_cur_frame_rate, |
176 | 12.1k | ps_error_bits->i4_tgt_frm_rate, |
177 | 12.1k | i4_cur_bitrate); |
178 | | /*Error = Actual bitrate - bits_per_frame * num of frames*/ |
179 | 12.1k | i4_error_bits = i4_cur_bitrate - ps_error_bits->i4_accum_bitrate; |
180 | 12.1k | } |
181 | 604k | return (i4_error_bits); |
182 | 604k | } |
183 | | /* ******************************************************************************/ |
184 | | /** |
185 | | * @brief Change the bitrate value for error bits module |
186 | | * |
187 | | * @param ps_error_bits |
188 | | * @param i4_bitrate |
189 | | */ |
190 | | /* ******************************************************************************/ |
191 | | void change_bitrate_in_error_bits(error_bits_t *ps_error_bits, WORD32 i4_bitrate) |
192 | 15.4k | { |
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 | 15.4k | WORD32 i4_old_bits_per_frame; |
199 | 15.4k | WORD32 i4_new_bits_per_frame; |
200 | 15.4k | WORD32 i4_frame_count; |
201 | 15.4k | X_PROD_Y_DIV_Z( |
202 | 15.4k | ps_error_bits->i4_bitrate, 1000, ps_error_bits->i4_tgt_frm_rate, i4_old_bits_per_frame); |
203 | 15.4k | i4_frame_count = ps_error_bits->i4_accum_bitrate / i4_old_bits_per_frame; |
204 | 15.4k | X_PROD_Y_DIV_Z(i4_bitrate, 1000, ps_error_bits->i4_tgt_frm_rate, i4_new_bits_per_frame); |
205 | 15.4k | ps_error_bits->i4_accum_bitrate = i4_frame_count * i4_new_bits_per_frame; |
206 | | |
207 | | /*#endif*/ |
208 | | /*change bit rate*/ |
209 | 15.4k | ps_error_bits->i4_bitrate = i4_bitrate; |
210 | | /* ps_error_bits->i4_accum_bitrate=i4_bitrate;*/ |
211 | 15.4k | } |
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 | | |
222 | | void change_frm_rate_in_error_bits(error_bits_t *ps_error_bits, WORD32 i4_tgt_frm_rate) |
223 | 5.16k | { |
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 | 5.16k | if(ps_error_bits->i4_tgt_frm_rate != i4_tgt_frm_rate) |
234 | 0 | X_PROD_Y_DIV_Z( |
235 | 5.16k | ps_error_bits->i4_accum_frm_rate, |
236 | 5.16k | i4_tgt_frm_rate, |
237 | 5.16k | ps_error_bits->i4_tgt_frm_rate, |
238 | 5.16k | ps_error_bits->i4_accum_frm_rate); |
239 | | |
240 | | /*round off the accum value to multiple of 1000*/ |
241 | 5.16k | ps_error_bits->i4_accum_frm_rate = ps_error_bits->i4_accum_frm_rate / 1000; |
242 | 5.16k | 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 | 5.16k | ps_error_bits->i4_tgt_frm_rate = i4_tgt_frm_rate; |
248 | 5.16k | } |