/src/libavc/encoder/irc_rd_model.c
Line | Count | Source |
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 | | /* File Name : irc_rd_model.c */ |
23 | | /* */ |
24 | | /* Description : Implall the Functions to Model the */ |
25 | | /* Rate Distortion Behaviour of the Codec over the Last */ |
26 | | /* Few Frames. */ |
27 | | /* */ |
28 | | /* List of Functions : irc_update_frame_rd_model */ |
29 | | /* estimate_mpeg2_qp_for_resbits */ |
30 | | /* */ |
31 | | /* Issues / Problems : None */ |
32 | | /* */ |
33 | | /* Revision History : */ |
34 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
35 | | /* 21 06 2006 Sarat Initial Version */ |
36 | | /****************************************************************************/ |
37 | | |
38 | | /* System include files */ |
39 | | #include <stdarg.h> |
40 | | #include <stdlib.h> |
41 | | #include <stdio.h> |
42 | | #include <string.h> |
43 | | #include "math.h" |
44 | | |
45 | | /* User include files */ |
46 | | #include "irc_datatypes.h" |
47 | | #include "irc_common.h" |
48 | | #include "irc_mem_req_and_acq.h" |
49 | | #include "irc_rd_model.h" |
50 | | #include "irc_rd_model_struct.h" |
51 | | |
52 | | |
53 | | WORD32 irc_rd_model_num_fill_use_free_memtab(rc_rd_model_t **pps_rc_rd_model, |
54 | | itt_memtab_t *ps_memtab, |
55 | | ITT_FUNC_TYPE_E e_func_type) |
56 | 368k | { |
57 | 368k | WORD32 i4_mem_tab_idx = 0; |
58 | 368k | rc_rd_model_t s_rc_rd_model_temp; |
59 | | |
60 | | /* |
61 | | * Hack for al alloc, during which we don't have any state memory. |
62 | | * Dereferencing can cause issues |
63 | | */ |
64 | 368k | if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) |
65 | 307k | (*pps_rc_rd_model) = &s_rc_rd_model_temp; |
66 | | |
67 | | /*for src rate control state structure*/ |
68 | 368k | if(e_func_type != GET_NUM_MEMTAB) |
69 | 184k | { |
70 | 184k | fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(rc_rd_model_t), |
71 | 184k | ALIGN_128_BYTE, PERSISTENT, DDR); |
72 | 184k | use_or_fill_base(&ps_memtab[0], (void**)pps_rc_rd_model, e_func_type); |
73 | 184k | } |
74 | 368k | i4_mem_tab_idx++; |
75 | | |
76 | 368k | return (i4_mem_tab_idx); |
77 | 368k | } |
78 | | |
79 | | void irc_init_frm_rc_rd_model(rc_rd_model_t *ps_rd_model, |
80 | | UWORD8 u1_max_frames_modelled) |
81 | 122k | { |
82 | | |
83 | 122k | ps_rd_model->u1_num_frms_in_model = 0; |
84 | 122k | ps_rd_model->u1_curr_frm_counter = 0; |
85 | 122k | ps_rd_model->u1_max_frms_to_model = u1_max_frames_modelled; |
86 | | |
87 | 122k | ps_rd_model->model_coeff_a_lin_wo_int = 0; |
88 | 122k | ps_rd_model->model_coeff_b_lin_wo_int = 0; |
89 | 122k | ps_rd_model->model_coeff_c_lin_wo_int = 0; |
90 | 122k | } |
91 | | |
92 | | void irc_reset_frm_rc_rd_model(rc_rd_model_t *ps_rd_model) |
93 | 8.31k | { |
94 | 8.31k | ps_rd_model->u1_num_frms_in_model = 0; |
95 | 8.31k | ps_rd_model->u1_curr_frm_counter = 0; |
96 | | |
97 | 8.31k | ps_rd_model->model_coeff_a_lin_wo_int = 0; |
98 | 8.31k | ps_rd_model->model_coeff_b_lin_wo_int = 0; |
99 | 8.31k | ps_rd_model->model_coeff_c_lin_wo_int = 0; |
100 | 8.31k | } |
101 | | |
102 | | static UWORD8 find_model_coeffs(UWORD32 *pi4_res_bits, |
103 | | UWORD32 *pi4_sad_h264, |
104 | | UWORD8 *pu1_num_skips, |
105 | | UWORD8 *pui_avg_mpeg2_qp, |
106 | | UWORD8 u1_num_frms, |
107 | | UWORD8 u1_model_used, |
108 | | WORD8 *pi1_frame_index, |
109 | | model_coeff *pmc_model_coeff, |
110 | | model_coeff *pmc_model_coeff_lin, |
111 | | model_coeff *pmc_model_coeff_lin_wo_int, |
112 | | rc_rd_model_t *ps_rd_model) |
113 | 46.2k | { |
114 | 46.2k | UWORD32 i; |
115 | 46.2k | UWORD8 u1_num_frms_used = 0; |
116 | 46.2k | UWORD8 u1_frm_indx; |
117 | | |
118 | 46.2k | float sum_y = 0; |
119 | 46.2k | float sum_x_y = 0; |
120 | 46.2k | float sum_x2_y = 0; |
121 | 46.2k | float sum_x = 0; |
122 | 46.2k | float sum_x2 = 0; |
123 | 46.2k | float sum_x3 = 0; |
124 | 46.2k | float sum_x4 = 0; |
125 | | |
126 | 46.2k | float x0, y0; |
127 | 46.2k | float model_coeff_a = 0.0, model_coeff_b = 0.0, model_coeff_c = 0.0; |
128 | | |
129 | 46.2k | UNUSED(pu1_num_skips); |
130 | 46.2k | UNUSED(pmc_model_coeff); |
131 | 46.2k | UNUSED(pmc_model_coeff_lin); |
132 | | |
133 | 184k | for(i = 0; i < u1_num_frms; i++) |
134 | 137k | { |
135 | 137k | if(-1 == pi1_frame_index[i]) |
136 | 0 | continue; |
137 | | |
138 | 137k | u1_frm_indx = (UWORD8)pi1_frame_index[i]; |
139 | | |
140 | 137k | y0 = (float)(pi4_res_bits[u1_frm_indx]); |
141 | 137k | x0 = (float)(pi4_sad_h264[u1_frm_indx] |
142 | 137k | / (float)pui_avg_mpeg2_qp[u1_frm_indx]); |
143 | | |
144 | 137k | sum_y += y0; |
145 | 137k | sum_x_y += x0 * y0; |
146 | 137k | sum_x2_y += x0 * x0 * y0; |
147 | 137k | sum_x += x0; |
148 | 137k | sum_x2 += x0 * x0; |
149 | 137k | sum_x3 += x0 * x0 * x0; |
150 | 137k | sum_x4 += x0 * x0 * x0 * x0; |
151 | 137k | u1_num_frms_used++; |
152 | 137k | } |
153 | | |
154 | 46.2k | sum_y /= u1_num_frms_used; |
155 | 46.2k | sum_x_y /= u1_num_frms_used; |
156 | 46.2k | sum_x2_y /= u1_num_frms_used; |
157 | 46.2k | sum_x /= u1_num_frms_used; |
158 | 46.2k | sum_x2 /= u1_num_frms_used; |
159 | 46.2k | sum_x3 /= u1_num_frms_used; |
160 | 46.2k | sum_x4 /= u1_num_frms_used; |
161 | | |
162 | 46.2k | { |
163 | 46.2k | UWORD8 u1_curr_frame_index; |
164 | 46.2k | UWORD8 u1_avgqp_prvfrm; |
165 | 46.2k | UWORD32 u4_prevfrm_bits, u4_prevfrm_sad; |
166 | | |
167 | 46.2k | u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter; |
168 | 46.2k | if(0 == u1_curr_frame_index) |
169 | 917 | u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1); |
170 | 45.3k | else |
171 | 45.3k | u1_curr_frame_index--; |
172 | | |
173 | 46.2k | u1_avgqp_prvfrm = ps_rd_model->pu1_avg_qp[u1_curr_frame_index]; |
174 | 46.2k | u4_prevfrm_bits = ps_rd_model->pi4_res_bits[u1_curr_frame_index]; |
175 | 46.2k | u4_prevfrm_sad = ps_rd_model->pi4_sad[u1_curr_frame_index]; |
176 | | |
177 | 46.2k | if(0 != u4_prevfrm_sad) |
178 | 46.2k | model_coeff_a = (float)(u4_prevfrm_bits * u1_avgqp_prvfrm) |
179 | 46.2k | / u4_prevfrm_sad; |
180 | 0 | else |
181 | 0 | model_coeff_a = 0; |
182 | | |
183 | 46.2k | model_coeff_b = 0; |
184 | 46.2k | model_coeff_c = 0; |
185 | | |
186 | 46.2k | pmc_model_coeff_lin_wo_int[0] = model_coeff_b; |
187 | 46.2k | pmc_model_coeff_lin_wo_int[1] = model_coeff_a; |
188 | 46.2k | pmc_model_coeff_lin_wo_int[2] = model_coeff_c; |
189 | 46.2k | } |
190 | | |
191 | 46.2k | return u1_model_used; |
192 | 46.2k | } |
193 | | |
194 | | static void irc_update_frame_rd_model(rc_rd_model_t *ps_rd_model) |
195 | 46.2k | { |
196 | 46.2k | WORD8 pi1_frame_index[MAX_FRAMES_MODELLED], |
197 | 46.2k | pi1_frame_index_initial[MAX_FRAMES_MODELLED]; |
198 | | |
199 | 46.2k | UWORD8 u1_num_skips_temp; |
200 | 46.2k | UWORD8 u1_avg_mpeg2_qp_temp, u1_min_mpeg2_qp, u1_max_mpeg2_qp; |
201 | 46.2k | UWORD8 u1_num_frms_input, u1_num_active_frames, u1_reject_frame; |
202 | 46.2k | UWORD32 u4_num_skips; |
203 | | |
204 | 46.2k | UWORD8 u1_min2_mpeg2_qp, u1_max2_mpeg2_qp; |
205 | 46.2k | UWORD8 u1_min_qp_frame_indx, u1_max_qp_frame_indx; |
206 | 46.2k | UWORD8 pu1_num_frames[MPEG2_QP_ELEM]; |
207 | 46.2k | model_coeff model_coeff_array[3], model_coeff_array_lin[3], |
208 | 46.2k | model_coeff_array_lin_wo_int[3]; |
209 | 46.2k | UWORD32 i; |
210 | 46.2k | UWORD8 u1_curr_frame_index; |
211 | | |
212 | 46.2k | u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter; |
213 | | |
214 | 46.2k | ps_rd_model->u1_model_used = PREV_FRAME_MODEL; |
215 | | |
216 | 46.2k | if(0 == u1_curr_frame_index) |
217 | 917 | u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1); |
218 | 45.3k | else |
219 | 45.3k | u1_curr_frame_index--; |
220 | | |
221 | | /************************************************************************/ |
222 | | /* Rearrange data to be fed into a Linear Regression Module */ |
223 | | /* Module finds a,b,c such that */ |
224 | | /* y = ax + bx^2 + c */ |
225 | | /************************************************************************/ |
226 | 46.2k | u4_num_skips = 0; |
227 | 46.2k | u1_num_frms_input = 0; |
228 | 46.2k | memset(pu1_num_frames, 0, MPEG2_QP_ELEM); |
229 | 46.2k | memset(pi1_frame_index, -1, MAX_FRAMES_MODELLED); |
230 | 46.2k | u1_min_mpeg2_qp = MAX_MPEG2_QP; |
231 | 46.2k | u1_max_mpeg2_qp = 0; |
232 | | |
233 | 46.2k | u1_num_active_frames = ps_rd_model->u1_num_frms_in_model; |
234 | 46.2k | if(u1_num_active_frames > MAX_ACTIVE_FRAMES) |
235 | 0 | { |
236 | 0 | u1_num_active_frames = MAX_ACTIVE_FRAMES; |
237 | 0 | } |
238 | | |
239 | | /************************************************************************/ |
240 | | /* Choose the set of Points to be used for MSE fit of Quadratic model */ |
241 | | /* Points chosen are spread across the Qp range. Max of 2 points are */ |
242 | | /* chosen for a Qp. */ |
243 | | /************************************************************************/ |
244 | 331k | for(i = 0; i < u1_num_active_frames; i++) |
245 | 284k | { |
246 | 284k | u1_reject_frame = 0; |
247 | 284k | u1_num_skips_temp = ps_rd_model->pu1_num_skips[u1_curr_frame_index]; |
248 | 284k | u1_avg_mpeg2_qp_temp = ps_rd_model->pu1_avg_qp[u1_curr_frame_index]; |
249 | | |
250 | 284k | if((0 == u4_num_skips) && (0 != u1_num_skips_temp)) |
251 | 0 | u1_reject_frame = 1; |
252 | 284k | if((1 == u4_num_skips) && (u1_num_skips_temp > 1)) |
253 | 0 | u1_reject_frame = 1; |
254 | 284k | if(pu1_num_frames[u1_avg_mpeg2_qp_temp] >= 2) |
255 | 146k | u1_reject_frame = 1; |
256 | | |
257 | 284k | if(0 == i) |
258 | 46.2k | u1_reject_frame = 0; |
259 | | |
260 | 284k | if(0 == u1_reject_frame) |
261 | 137k | { |
262 | 137k | pi1_frame_index[u1_num_frms_input] = (WORD8)u1_curr_frame_index; |
263 | 137k | pu1_num_frames[u1_avg_mpeg2_qp_temp] += 1; |
264 | | |
265 | 137k | if(u1_min_mpeg2_qp > u1_avg_mpeg2_qp_temp) |
266 | 69.2k | u1_min_mpeg2_qp = u1_avg_mpeg2_qp_temp; |
267 | 137k | if(u1_max_mpeg2_qp < u1_avg_mpeg2_qp_temp) |
268 | 79.9k | u1_max_mpeg2_qp = u1_avg_mpeg2_qp_temp; |
269 | | |
270 | 137k | u1_num_frms_input++; |
271 | 137k | } |
272 | | |
273 | 284k | if(0 == u1_curr_frame_index) |
274 | 46.2k | u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1); |
275 | 238k | else |
276 | 238k | u1_curr_frame_index--; |
277 | 284k | } |
278 | | |
279 | | /************************************************************************/ |
280 | | /* Add Pivot Points to the Data set to be used for finding Quadratic */ |
281 | | /* Model Coeffs. These will help in constraining the shape of Quadratic*/ |
282 | | /* to adapt too much to the Local deviations. */ |
283 | | /************************************************************************/ |
284 | 46.2k | u1_min2_mpeg2_qp = u1_min_mpeg2_qp; |
285 | 46.2k | u1_max2_mpeg2_qp = u1_max_mpeg2_qp; |
286 | 46.2k | u1_min_qp_frame_indx = INVALID_FRAME_INDEX; |
287 | 46.2k | u1_max_qp_frame_indx = INVALID_FRAME_INDEX; |
288 | | |
289 | | /* Loop runnning over the Stored Frame Level Data |
290 | | to find frames of MinQp and MaxQp */ |
291 | 46.2k | for(; i < ps_rd_model->u1_num_frms_in_model; i++) |
292 | 0 | { |
293 | 0 | u1_num_skips_temp = ps_rd_model->pu1_num_skips[u1_curr_frame_index]; |
294 | 0 | u1_avg_mpeg2_qp_temp = ps_rd_model->pu1_avg_qp[u1_curr_frame_index]; |
295 | |
|
296 | 0 | if(((0 == u4_num_skips) && (0 != u1_num_skips_temp)) |
297 | 0 | || ((1 == u4_num_skips) && (u1_num_skips_temp > 1))) |
298 | 0 | continue; |
299 | | |
300 | 0 | if(u1_min2_mpeg2_qp > u1_avg_mpeg2_qp_temp) |
301 | 0 | { |
302 | 0 | u1_min2_mpeg2_qp = u1_avg_mpeg2_qp_temp; |
303 | 0 | u1_min_qp_frame_indx = u1_curr_frame_index; |
304 | 0 | } |
305 | 0 | if(u1_max2_mpeg2_qp < u1_avg_mpeg2_qp_temp) |
306 | 0 | { |
307 | 0 | u1_max2_mpeg2_qp = u1_avg_mpeg2_qp_temp; |
308 | 0 | u1_max_qp_frame_indx = u1_curr_frame_index; |
309 | 0 | } |
310 | 0 | if(0 == u1_curr_frame_index) |
311 | 0 | u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1); |
312 | 0 | else |
313 | 0 | u1_curr_frame_index--; |
314 | 0 | } |
315 | | |
316 | | /* Add the Chosen Points to the regression data set */ |
317 | 46.2k | if(INVALID_FRAME_INDEX != u1_min_qp_frame_indx) |
318 | 0 | { |
319 | 0 | pi1_frame_index[u1_num_frms_input] = (WORD8)u1_min_qp_frame_indx; |
320 | 0 | u1_num_frms_input++; |
321 | 0 | } |
322 | 46.2k | if(INVALID_FRAME_INDEX != u1_max_qp_frame_indx) |
323 | 0 | { |
324 | 0 | pi1_frame_index[u1_num_frms_input] = (WORD8)u1_max_qp_frame_indx; |
325 | 0 | u1_num_frms_input++; |
326 | 0 | } |
327 | 46.2k | memcpy(pi1_frame_index_initial, pi1_frame_index, MAX_FRAMES_MODELLED); |
328 | | |
329 | | /***** Call the Module to Return the Coeffs for the Fed Data *****/ |
330 | 46.2k | ps_rd_model->u1_model_used = find_model_coeffs(ps_rd_model->pi4_res_bits, |
331 | 46.2k | ps_rd_model->pi4_sad, |
332 | 46.2k | ps_rd_model->pu1_num_skips, |
333 | 46.2k | ps_rd_model->pu1_avg_qp, |
334 | 46.2k | u1_num_frms_input, |
335 | 46.2k | ps_rd_model->u1_model_used, |
336 | 46.2k | pi1_frame_index, |
337 | 46.2k | model_coeff_array, |
338 | 46.2k | model_coeff_array_lin, |
339 | 46.2k | model_coeff_array_lin_wo_int, |
340 | 46.2k | ps_rd_model); |
341 | | |
342 | 46.2k | ps_rd_model->model_coeff_b_lin_wo_int = model_coeff_array_lin_wo_int[0]; |
343 | 46.2k | ps_rd_model->model_coeff_a_lin_wo_int = model_coeff_array_lin_wo_int[1]; |
344 | 46.2k | ps_rd_model->model_coeff_c_lin_wo_int = model_coeff_array_lin_wo_int[2]; |
345 | 46.2k | } |
346 | | |
347 | | UWORD32 irc_estimate_bits_for_qp(rc_rd_model_t *ps_rd_model, |
348 | | UWORD32 u4_estimated_sad, |
349 | | UWORD8 u1_avg_qp) |
350 | 0 | { |
351 | 0 | float fl_num_bits = 0; |
352 | |
|
353 | 0 | fl_num_bits = ps_rd_model->model_coeff_a_lin_wo_int |
354 | 0 | * ((float)(u4_estimated_sad / u1_avg_qp)); |
355 | |
|
356 | 0 | return ((UWORD32)fl_num_bits); |
357 | 0 | } |
358 | | |
359 | | UWORD8 irc_find_qp_for_target_bits(rc_rd_model_t *ps_rd_model, |
360 | | UWORD32 u4_target_res_bits, |
361 | | UWORD32 u4_estimated_sad, |
362 | | UWORD8 u1_min_qp, |
363 | | UWORD8 u1_max_qp) |
364 | 31.9k | { |
365 | 31.9k | UWORD8 u1_qp; |
366 | 31.9k | float x_value = 1.0, f_qp; |
367 | | |
368 | 31.9k | ps_rd_model->u1_model_used = PREV_FRAME_MODEL; |
369 | | |
370 | 31.9k | { |
371 | 31.9k | x_value = (float)u4_target_res_bits |
372 | 31.9k | / ps_rd_model->model_coeff_a_lin_wo_int; |
373 | 31.9k | } |
374 | | |
375 | 31.9k | if(0 != x_value) |
376 | 31.9k | f_qp = u4_estimated_sad / x_value; |
377 | 0 | else |
378 | 0 | f_qp = 255; |
379 | | |
380 | 31.9k | if(f_qp > 255) |
381 | 1.39k | f_qp = 255; |
382 | | |
383 | | /* Truncating the QP to the Max and Min Qp values possible */ |
384 | 31.9k | if(f_qp < u1_min_qp) |
385 | 23.5k | f_qp = u1_min_qp; |
386 | 31.9k | if(f_qp > u1_max_qp) |
387 | 1.96k | f_qp = u1_max_qp; |
388 | | |
389 | 31.9k | u1_qp = (UWORD8)(f_qp + 0.5); |
390 | | |
391 | 31.9k | return u1_qp; |
392 | 31.9k | } |
393 | | |
394 | | void irc_add_frame_to_rd_model(rc_rd_model_t *ps_rd_model, |
395 | | UWORD32 i4_res_bits, |
396 | | UWORD8 u1_avg_mp2qp, |
397 | | UWORD32 i4_sad_h264, |
398 | | UWORD8 u1_num_skips) |
399 | 46.2k | { |
400 | 46.2k | UWORD8 u1_curr_frame_index; |
401 | 46.2k | u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter; |
402 | | |
403 | | /*Insert the Present Frame Data into the RD Model State Memory*/ |
404 | 46.2k | ps_rd_model->pi4_res_bits[u1_curr_frame_index] = i4_res_bits; |
405 | 46.2k | ps_rd_model->pi4_sad[u1_curr_frame_index] = i4_sad_h264; |
406 | 46.2k | ps_rd_model->pu1_num_skips[u1_curr_frame_index] = u1_num_skips; |
407 | 46.2k | ps_rd_model->pu1_avg_qp[u1_curr_frame_index] = u1_avg_mp2qp; |
408 | | |
409 | 46.2k | ps_rd_model->u1_curr_frm_counter++; |
410 | 46.2k | if(MAX_FRAMES_MODELLED == ps_rd_model->u1_curr_frm_counter) |
411 | 917 | ps_rd_model->u1_curr_frm_counter = 0; |
412 | | |
413 | 46.2k | if(ps_rd_model->u1_num_frms_in_model < ps_rd_model->u1_max_frms_to_model) |
414 | 37.4k | { |
415 | 37.4k | ps_rd_model->u1_num_frms_in_model++; |
416 | 37.4k | } |
417 | 46.2k | irc_update_frame_rd_model(ps_rd_model); |
418 | 46.2k | } |
419 | | |
420 | | /***************************************************************************** |
421 | | *Function Name : irc_calc_per_frm_bits |
422 | | *Description : |
423 | | *Inputs : pu2_num_pics_of_a_pic_type |
424 | | * - pointer to RC api pointer |
425 | | * pu2_num_pics_of_a_pic_type |
426 | | * - N1, N2,...Nk |
427 | | * pu1_update_pic_type_model |
428 | | * - flag which tells whether or not to update model |
429 | | * coefficients of a particular pic-type |
430 | | * u1_num_pic_types |
431 | | * - value of k |
432 | | * pu4_num_skip_of_a_pic_type |
433 | | * - the number of skips of that pic-type. It "may" be used to |
434 | | * update the model coefficients at a later point. Right now |
435 | | * it is not being used at all. |
436 | | * u1_base_pic_type |
437 | | * - base pic type index wrt which alpha & beta are calculated |
438 | | * pfl_gamma |
439 | | * - gamma_i = beta_i / alpha_i |
440 | | * pfl_eta |
441 | | * - |
442 | | * u1_curr_pic_type |
443 | | * - the current pic-type for which the targetted bits need to |
444 | | * be computed |
445 | | * u4_bits_for_sub_gop |
446 | | * - the number of bits to be consumed for the remaining part of |
447 | | * sub-gop |
448 | | * u4_curr_estimated_sad |
449 | | * - |
450 | | * pu1_curr_pic_type_qp |
451 | | * - output of this function |
452 | | *****************************************************************************/ |
453 | | |
454 | | WORD32 irc_calc_per_frm_bits(rc_rd_model_t *ps_rd_model, |
455 | | UWORD16 *pu2_num_pics_of_a_pic_type, |
456 | | UWORD8 *pu1_update_pic_type_model, |
457 | | UWORD8 u1_num_pic_types, |
458 | | UWORD32 *pu4_num_skip_of_a_pic_type, |
459 | | UWORD8 u1_base_pic_type, |
460 | | float *pfl_gamma, |
461 | | float *pfl_eta, |
462 | | UWORD8 u1_curr_pic_type, |
463 | | UWORD32 u4_bits_for_sub_gop, |
464 | | UWORD32 u4_curr_estimated_sad, |
465 | | UWORD8 *pu1_curr_pic_type_qp) |
466 | 0 | { |
467 | 0 | WORD32 i4_per_frm_bits_Ti; |
468 | 0 | UWORD8 u1_i; |
469 | 0 | rc_rd_model_t *ps_rd_model_of_pic_type; |
470 | |
|
471 | 0 | UNUSED(pu4_num_skip_of_a_pic_type); |
472 | 0 | UNUSED(u1_base_pic_type); |
473 | | |
474 | | /* First part of this function updates all the model coefficients */ |
475 | | /*for all the pic-types */ |
476 | 0 | { |
477 | 0 | for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++) |
478 | 0 | { |
479 | 0 | if((0 != pu2_num_pics_of_a_pic_type[u1_i]) |
480 | 0 | && (1 == pu1_update_pic_type_model[u1_i])) |
481 | 0 | { |
482 | 0 | irc_update_frame_rd_model(&ps_rd_model[u1_i]); |
483 | 0 | } |
484 | 0 | } |
485 | 0 | } |
486 | | |
487 | | /* |
488 | | * The second part of this function deals with solving the |
489 | | * equation using all the pic-types models |
490 | | */ |
491 | 0 | { |
492 | 0 | UWORD8 u1_combined_model_used; |
493 | | |
494 | | /* solve the equation */ |
495 | 0 | { |
496 | 0 | model_coeff eff_A; |
497 | 0 | float fl_sad_by_qp_base; |
498 | 0 | float fl_sad_by_qp_curr_frm = 1.0; |
499 | 0 | float fl_qp_curr_frm; |
500 | 0 | float fl_bits_for_curr_frm = 0; |
501 | | |
502 | | |
503 | | |
504 | | /* If the combined chosen model is linear model without an intercept */ |
505 | |
|
506 | 0 | u1_combined_model_used = PREV_FRAME_MODEL; |
507 | 0 | { |
508 | 0 | eff_A = 0.0; |
509 | |
|
510 | 0 | for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++) |
511 | 0 | { |
512 | 0 | ps_rd_model_of_pic_type = ps_rd_model + u1_i; |
513 | |
|
514 | 0 | eff_A += ((pfl_eta[u1_i] |
515 | 0 | + pu2_num_pics_of_a_pic_type[u1_i]- 1) |
516 | 0 | * ps_rd_model_of_pic_type->model_coeff_a_lin_wo_int |
517 | 0 | * pfl_gamma[u1_i]); |
518 | 0 | } |
519 | |
|
520 | 0 | fl_sad_by_qp_base = u4_bits_for_sub_gop / eff_A; |
521 | |
|
522 | 0 | fl_sad_by_qp_curr_frm = fl_sad_by_qp_base |
523 | 0 | * pfl_gamma[u1_curr_pic_type] |
524 | 0 | * pfl_eta[u1_curr_pic_type]; |
525 | |
|
526 | 0 | ps_rd_model_of_pic_type = ps_rd_model + u1_curr_pic_type; |
527 | |
|
528 | 0 | fl_bits_for_curr_frm = |
529 | 0 | ps_rd_model_of_pic_type->model_coeff_a_lin_wo_int |
530 | 0 | * fl_sad_by_qp_curr_frm; |
531 | 0 | } |
532 | | |
533 | | /* |
534 | | * Store the model that was finally used to calculate Qp. |
535 | | * This is so that the same model is used in further calculations |
536 | | * for this picture. |
537 | | */ |
538 | 0 | ps_rd_model_of_pic_type = ps_rd_model + u1_curr_pic_type; |
539 | 0 | ps_rd_model_of_pic_type->u1_model_used = u1_combined_model_used; |
540 | |
|
541 | 0 | i4_per_frm_bits_Ti = (WORD32)(fl_bits_for_curr_frm + 0.5); |
542 | |
|
543 | 0 | if(fl_sad_by_qp_curr_frm > 0) |
544 | 0 | fl_qp_curr_frm = (float)u4_curr_estimated_sad |
545 | 0 | / fl_sad_by_qp_curr_frm; |
546 | 0 | else |
547 | 0 | fl_qp_curr_frm = 255; |
548 | |
|
549 | 0 | if(fl_qp_curr_frm > 255) |
550 | 0 | fl_qp_curr_frm = 255; |
551 | |
|
552 | 0 | *pu1_curr_pic_type_qp = (fl_qp_curr_frm + 0.5); |
553 | |
|
554 | 0 | } |
555 | 0 | } |
556 | 0 | return (i4_per_frm_bits_Ti); |
557 | 0 | } |
558 | | |
559 | | model_coeff irc_get_linear_coefficient(rc_rd_model_t *ps_rd_model) |
560 | 123k | { |
561 | 123k | return (ps_rd_model->model_coeff_a_lin_wo_int); |
562 | 123k | } |
563 | | |
564 | | |