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 Name : rc_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 : 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 ittiam Initial Version */
36 /****************************************************************************/
37
38 /*****************************************************************************/
39 /* File Includes */
40 /*****************************************************************************/
41 /* System include files */
42 #include <stdarg.h>
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <math.h>
46
47 /* System include files */
48 #include "ittiam_datatypes.h"
49 #include "rc_common.h"
50 #include "var_q_operator.h"
51 #include "mem_req_and_acq.h"
52 #include "rc_rd_model.h"
53 #include "rc_rd_model_struct.h"
54
55 #if !(RC_FIXED_POINT)
56
57 #if NON_STEADSTATE_CODE
rc_rd_model_num_fill_use_free_memtab(rc_rd_model_t ** pps_rc_rd_model,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)58 WORD32 rc_rd_model_num_fill_use_free_memtab(
59 rc_rd_model_t **pps_rc_rd_model, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
60 {
61 WORD32 i4_mem_tab_idx = 0;
62 static rc_rd_model_t s_rc_rd_model_temp;
63
64 /* Hack for al alloc, during which we dont have any state memory.
65 Dereferencing can cause issues */
66 if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
67 (*pps_rc_rd_model) = &s_rc_rd_model_temp;
68
69 /*for src rate control state structure*/
70 if(e_func_type != GET_NUM_MEMTAB)
71 {
72 fill_memtab(
73 &ps_memtab[i4_mem_tab_idx], sizeof(rc_rd_model_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR);
74 use_or_fill_base(&ps_memtab[0], (void **)pps_rc_rd_model, e_func_type);
75 }
76 i4_mem_tab_idx++;
77
78 return (i4_mem_tab_idx);
79 }
80
init_frm_rc_rd_model(rc_rd_model_t * ps_rd_model,UWORD8 u1_max_frames_modelled)81 void init_frm_rc_rd_model(rc_rd_model_t *ps_rd_model, UWORD8 u1_max_frames_modelled)
82 {
83 /*ps_rd_model = ps_rd_model + u1_pic_type;*/
84
85 ps_rd_model->u1_num_frms_in_model = 0;
86 ps_rd_model->u1_curr_frm_counter = 0;
87 ps_rd_model->u1_max_frms_to_model = u1_max_frames_modelled;
88 /*
89 ps_rd_model->u1_min_frames_for_quad_model = u1_min_frames_for_quad_model;
90 ps_rd_model->u1_min_frames_for_lin_model = u1_min_frames_for_lin_model;
91 */
92
93 ps_rd_model->model_coeff_a_quad = 0;
94 ps_rd_model->model_coeff_b_quad = 0;
95 ps_rd_model->model_coeff_c_quad = 0;
96
97 ps_rd_model->model_coeff_a_lin = 0;
98 ps_rd_model->model_coeff_b_lin = 0;
99 ps_rd_model->model_coeff_c_lin = 0;
100
101 ps_rd_model->model_coeff_a_lin_wo_int = 0;
102 ps_rd_model->model_coeff_b_lin_wo_int = 0;
103 ps_rd_model->model_coeff_c_lin_wo_int = 0;
104 }
105
reset_frm_rc_rd_model(rc_rd_model_t * ps_rd_model)106 void reset_frm_rc_rd_model(rc_rd_model_t *ps_rd_model)
107 {
108 /*ps_rd_model = ps_rd_model + u1_pic_type;*/
109
110 ps_rd_model->u1_num_frms_in_model = 0;
111 ps_rd_model->u1_curr_frm_counter = 0;
112 ps_rd_model->model_coeff_a_quad = 0;
113 ps_rd_model->model_coeff_b_quad = 0;
114 ps_rd_model->model_coeff_c_quad = 0;
115
116 ps_rd_model->model_coeff_a_lin = 0;
117 ps_rd_model->model_coeff_b_lin = 0;
118 ps_rd_model->model_coeff_c_lin = 0;
119
120 ps_rd_model->model_coeff_a_lin_wo_int = 0;
121 ps_rd_model->model_coeff_b_lin_wo_int = 0;
122 ps_rd_model->model_coeff_c_lin_wo_int = 0;
123 }
124 #endif /* #if NON_STEADSTATE_CODE */
125
126 #if ENABLE_QUAD_MODEL
find_model_coeffs(UWORD32 * pi4_res_bits,UWORD32 * pi4_sad_h264,UWORD8 * pu1_num_skips,UWORD8 * pui_avg_mpeg2_qp,UWORD8 u1_num_frms,UWORD8 u1_model_used,WORD8 * pi1_frame_index,model_coeff * pmc_model_coeff,model_coeff * pmc_model_coeff_lin,model_coeff * pmc_model_coeff_lin_wo_int,rc_rd_model_t * ps_rd_model)127 static UWORD8 find_model_coeffs(
128 UWORD32 *pi4_res_bits,
129 UWORD32 *pi4_sad_h264,
130 UWORD8 *pu1_num_skips,
131 UWORD8 *pui_avg_mpeg2_qp,
132 UWORD8 u1_num_frms,
133 UWORD8 u1_model_used,
134 WORD8 *pi1_frame_index,
135 model_coeff *pmc_model_coeff,
136 model_coeff *pmc_model_coeff_lin,
137 model_coeff *pmc_model_coeff_lin_wo_int,
138 rc_rd_model_t *ps_rd_model)
139 {
140 UWORD32 i;
141 UWORD8 u1_num_frms_used = 0;
142 UWORD8 u1_frm_indx;
143
144 float sum_y = 0;
145 float sum_x_y = 0;
146 float sum_x2_y = 0;
147 float sum_x = 0;
148 float sum_x2 = 0;
149 float sum_x3 = 0;
150 float sum_x4 = 0;
151 float var_x2_y = 0;
152 float var_x_y = 0;
153 float var_x2_x = 0;
154 float var_x2_x2 = 0;
155 float var_x_x = 0;
156 float x0, y0;
157 float model_coeff_a, model_coeff_b, model_coeff_c, model_coeff_den;
158
159 for(i = 0; i < u1_num_frms; i++)
160 {
161 if(-1 == pi1_frame_index[i])
162 continue;
163
164 u1_frm_indx = (UWORD8)pi1_frame_index[i];
165
166 y0 = (float)(pi4_res_bits[u1_frm_indx]);
167 x0 = (float)(pi4_sad_h264[u1_frm_indx] / (float)pui_avg_mpeg2_qp[u1_frm_indx]);
168
169 sum_y += y0;
170 sum_x_y += x0 * y0;
171 sum_x2_y += x0 * x0 * y0;
172 sum_x += x0;
173 sum_x2 += x0 * x0;
174 sum_x3 += x0 * x0 * x0;
175 sum_x4 += x0 * x0 * x0 * x0;
176 u1_num_frms_used++;
177 }
178
179 sum_y /= u1_num_frms_used;
180 sum_x_y /= u1_num_frms_used;
181 sum_x2_y /= u1_num_frms_used;
182 sum_x /= u1_num_frms_used;
183 sum_x2 /= u1_num_frms_used;
184 sum_x3 /= u1_num_frms_used;
185 sum_x4 /= u1_num_frms_used;
186
187 #if !QUAD
188 u1_model_used = LIN_MODEL;
189 #endif
190
191 if((QUAD_MODEL == u1_model_used) && (u1_num_frms_used <= MIN_FRAMES_FOR_QUAD_MODEL))
192 {
193 u1_model_used = LIN_MODEL;
194 }
195
196 if(QUAD_MODEL == u1_model_used)
197 {
198 var_x2_y = sum_x2_y - sum_x2 * sum_y;
199 var_x_y = sum_x_y - sum_x * sum_y;
200 var_x2_x = sum_x3 - sum_x2 * sum_x;
201 var_x2_x2 = sum_x4 - sum_x2 * sum_x2;
202 var_x_x = sum_x2 - sum_x * sum_x;
203
204 model_coeff_den = (var_x2_x * var_x2_x - var_x2_x2 * var_x_x);
205
206 if(0 != model_coeff_den)
207 {
208 model_coeff_b = (var_x_y * var_x2_x - var_x2_y * var_x_x);
209 model_coeff_b /= model_coeff_den;
210
211 model_coeff_a = (var_x2_y * var_x2_x - var_x_y * var_x2_x2);
212 model_coeff_a /= model_coeff_den;
213
214 model_coeff_c = sum_y - (model_coeff_a * sum_x) - (model_coeff_b * sum_x2);
215 }
216
217 pmc_model_coeff[0] = model_coeff_b;
218 pmc_model_coeff[1] = model_coeff_a;
219 pmc_model_coeff[2] = model_coeff_c;
220 }
221
222 if(NULL != pmc_model_coeff_lin)
223 {
224 var_x_y = sum_x_y - sum_x * sum_y;
225 var_x_x = sum_x2 - sum_x * sum_x;
226
227 if(0 != var_x_x)
228 {
229 model_coeff_a = (var_x_y / var_x_x);
230 model_coeff_c = sum_y - (model_coeff_a * sum_x);
231 /*model_coeff_b = 0;*/
232 model_coeff_b = model_coeff_a;
233
234 pmc_model_coeff_lin[0] = model_coeff_b;
235 pmc_model_coeff_lin[1] = model_coeff_a;
236 pmc_model_coeff_lin[2] = model_coeff_c;
237 }
238 }
239
240 if(NULL != pmc_model_coeff_lin_wo_int)
241 {
242 UWORD8 u1_curr_frame_index;
243 UWORD8 u1_avgqp_prvfrm;
244 UWORD32 u4_prevfrm_bits, u4_prevfrm_sad;
245
246 u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter;
247 if(0 == u1_curr_frame_index)
248 u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1);
249 else
250 u1_curr_frame_index--;
251
252 u1_avgqp_prvfrm = ps_rd_model->pu1_avg_qp[u1_curr_frame_index];
253 u4_prevfrm_bits = ps_rd_model->pi4_res_bits[u1_curr_frame_index];
254 u4_prevfrm_sad = ps_rd_model->pi4_sad[u1_curr_frame_index];
255
256 if(0 != u4_prevfrm_sad)
257 model_coeff_a = (float)(u4_prevfrm_bits * u1_avgqp_prvfrm) / u4_prevfrm_sad;
258 else
259 model_coeff_a = 0;
260
261 model_coeff_b = 0;
262 model_coeff_c = 0;
263
264 pmc_model_coeff_lin_wo_int[0] = model_coeff_b;
265 pmc_model_coeff_lin_wo_int[1] = model_coeff_a;
266 pmc_model_coeff_lin_wo_int[2] = model_coeff_c;
267 }
268
269 return u1_model_used;
270 }
271
refine_set_of_points(UWORD32 * pi4_res_bits,UWORD32 * pi4_sad_h264,UWORD8 * pu1_num_skips,UWORD8 * pui_avg_mpeg2_qp,UWORD8 u1_num_frms,WORD8 * pi1_frame_index,model_coeff * pmc_model_coeff,float * pfl_avg_deviation)272 static WORD8 refine_set_of_points(
273 UWORD32 *pi4_res_bits,
274 UWORD32 *pi4_sad_h264,
275 UWORD8 *pu1_num_skips,
276 UWORD8 *pui_avg_mpeg2_qp,
277 UWORD8 u1_num_frms,
278 WORD8 *pi1_frame_index,
279 model_coeff *pmc_model_coeff,
280 float *pfl_avg_deviation)
281 {
282 float fl_avg_deviation, fl_estimated_bits, fl_deviation, x_val;
283 UWORD8 u1_return_value = 1;
284 UWORD32 i;
285 UWORD8 u1_num_frms_used, u1_frm_indx;
286
287 u1_num_frms_used = 0;
288 fl_avg_deviation = 0;
289 for(i = 0; i < u1_num_frms; i++)
290 {
291 if(-1 == pi1_frame_index[i])
292 continue;
293
294 u1_frm_indx = (UWORD8)pi1_frame_index[i];
295 x_val = pi4_sad_h264[u1_frm_indx] / (float)pui_avg_mpeg2_qp[u1_frm_indx];
296
297 fl_estimated_bits = (pmc_model_coeff[0] * x_val * x_val) + (pmc_model_coeff[1] * x_val) +
298 (pmc_model_coeff[2]);
299
300 fl_deviation =
301 fabs(pi4_res_bits[u1_frm_indx] - fl_estimated_bits) / (float)pi4_res_bits[u1_frm_indx];
302 fl_deviation = fl_deviation * fl_deviation;
303 fl_avg_deviation += fl_deviation;
304 u1_num_frms_used++;
305 }
306
307 fl_avg_deviation /= u1_num_frms_used;
308 /*fl_avg_deviation = sqrt(fl_avg_deviation);*/
309 fl_avg_deviation = (fl_avg_deviation);
310
311 for(i = 0; i < u1_num_frms; i++)
312 {
313 if((-1 == pi1_frame_index[i]) && (i != 0))
314 continue;
315
316 u1_frm_indx = (UWORD8)pi1_frame_index[i];
317
318 x_val = pi4_sad_h264[u1_frm_indx] / (float)pui_avg_mpeg2_qp[u1_frm_indx];
319
320 fl_estimated_bits = (pmc_model_coeff[0] * x_val * x_val) + (pmc_model_coeff[1] * x_val) +
321 (pmc_model_coeff[2]);
322
323 fl_deviation =
324 fabs(pi4_res_bits[u1_frm_indx] - fl_estimated_bits) / (float)pi4_res_bits[u1_frm_indx];
325
326 fl_deviation = fl_deviation * fl_deviation;
327
328 if(fl_deviation > (fl_avg_deviation))
329 {
330 pi1_frame_index[i] = -1;
331 }
332 }
333
334 if(fl_avg_deviation > 0.0625)
335 u1_return_value = 0;
336 if(fl_avg_deviation < 0.0225)
337 u1_return_value = 2;
338
339 *pfl_avg_deviation = fl_avg_deviation;
340
341 return (u1_return_value);
342 }
calc_avg_sqr_dev_for_model(UWORD32 * pi4_res_bits,UWORD32 * pi4_sad_h264,UWORD8 * pu1_num_skips,UWORD8 * pui_avg_mpeg2_qp,UWORD8 u1_num_frms,WORD8 * pi1_frame_index,model_coeff * pmc_model_coeff,float * pfl_avg_deviation)343 static void calc_avg_sqr_dev_for_model(
344 UWORD32 *pi4_res_bits,
345 UWORD32 *pi4_sad_h264,
346 UWORD8 *pu1_num_skips,
347 UWORD8 *pui_avg_mpeg2_qp,
348 UWORD8 u1_num_frms,
349 WORD8 *pi1_frame_index,
350 model_coeff *pmc_model_coeff,
351 float *pfl_avg_deviation)
352 {
353 float fl_avg_deviation, fl_estimated_bits, fl_deviation, x_val;
354 UWORD8 u1_return_value = 1;
355 UWORD32 i;
356 UWORD8 u1_num_frms_used, u1_frm_indx;
357
358 u1_num_frms_used = 0;
359 fl_avg_deviation = 0;
360 for(i = 0; i < u1_num_frms; i++)
361 {
362 if(-1 == pi1_frame_index[i])
363 continue;
364
365 u1_frm_indx = (UWORD8)pi1_frame_index[i];
366
367 u1_frm_indx = (UWORD8)i;
368 x_val = pi4_sad_h264[u1_frm_indx] / (float)pui_avg_mpeg2_qp[u1_frm_indx];
369
370 fl_estimated_bits = (pmc_model_coeff[1] * x_val) + (pmc_model_coeff[2]);
371
372 fl_deviation =
373 fabs(pi4_res_bits[u1_frm_indx] - fl_estimated_bits) / (float)pi4_res_bits[u1_frm_indx];
374 fl_deviation = fl_deviation * fl_deviation;
375 fl_avg_deviation += fl_deviation;
376 u1_num_frms_used++;
377 }
378
379 fl_avg_deviation /= u1_num_frms_used;
380 /*fl_avg_deviation = sqrt(fl_avg_deviation);*/
381 fl_avg_deviation = (fl_avg_deviation);
382
383 *pfl_avg_deviation = fl_avg_deviation;
384 /*return (u1_return_value);*/
385 }
update_frame_rd_model(rc_rd_model_t * ps_rd_model)386 static void update_frame_rd_model(rc_rd_model_t *ps_rd_model)
387 {
388 WORD8 pi1_frame_index[MAX_FRAMES_MODELLED], pi1_frame_index_initial[MAX_FRAMES_MODELLED];
389
390 UWORD8 u1_num_skips_temp;
391 UWORD8 u1_avg_mpeg2_qp_temp, u1_min_mpeg2_qp, u1_max_mpeg2_qp;
392 UWORD8 u1_num_frms_input, u1_num_active_frames, u1_reject_frame;
393 UWORD32 u4_num_skips;
394
395 UWORD8 u1_min2_mpeg2_qp, u1_max2_mpeg2_qp;
396 UWORD8 u1_min_qp_frame_indx, u1_max_qp_frame_indx;
397 UWORD8 pu1_num_frames[MPEG2_QP_ELEM];
398 model_coeff model_coeff_array[3], model_coeff_array_lin[3], model_coeff_array_lin_wo_int[3];
399 UWORD32 i;
400 UWORD8 u1_curr_frame_index;
401 UWORD8 u1_quad_model_valid, u1_lin_model_valid;
402
403 float fl_quad_avg_dev, fl_lin_avg_dev;
404
405 UWORD8 u1_check_model;
406
407 /*ps_rd_model += u1_pic_type;*/
408
409 u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter;
410
411 ps_rd_model->u1_model_used = QUAD_MODEL;
412
413 if(0 == u1_curr_frame_index)
414 u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1);
415 else
416 u1_curr_frame_index--;
417
418 /************************************************************************/
419 /* Rearrange data to be fed into a Linear Regression Module */
420 /* Module finds a,b,c such that */
421 /* y = ax + bx^2 + c */
422 /************************************************************************/
423 u4_num_skips = 0;
424 u1_num_frms_input = 0;
425 memset(pu1_num_frames, 0, MPEG2_QP_ELEM);
426 memset(pi1_frame_index, -1, MAX_FRAMES_MODELLED);
427 u1_min_mpeg2_qp = MAX_MPEG2_QP;
428 u1_max_mpeg2_qp = 0;
429
430 u1_num_active_frames = ps_rd_model->u1_num_frms_in_model;
431 if(u1_num_active_frames > MAX_ACTIVE_FRAMES)
432 u1_num_active_frames = MAX_ACTIVE_FRAMES;
433
434 /************************************************************************/
435 /* Choose the set of Points to be used for MSE fit of Quadratic model */
436 /* Points chosen are spread across the Qp range. Max of 2 points are */
437 /* chosen for a Qp. */
438 /************************************************************************/
439 for(i = 0; i < u1_num_active_frames; i++)
440 {
441 u1_reject_frame = 0;
442 u1_num_skips_temp = ps_rd_model->pu1_num_skips[u1_curr_frame_index];
443 u1_avg_mpeg2_qp_temp = ps_rd_model->pu1_avg_qp[u1_curr_frame_index];
444
445 if((0 == u4_num_skips) && (0 != u1_num_skips_temp))
446 u1_reject_frame = 1;
447 if((1 == u4_num_skips) && (u1_num_skips_temp > 1))
448 u1_reject_frame = 1;
449 if(pu1_num_frames[u1_avg_mpeg2_qp_temp] >= 2)
450 u1_reject_frame = 1;
451
452 if(0 == i)
453 u1_reject_frame = 0;
454
455 if(0 == u1_reject_frame)
456 {
457 pi1_frame_index[u1_num_frms_input] = (WORD8)u1_curr_frame_index;
458 pu1_num_frames[u1_avg_mpeg2_qp_temp] += 1;
459
460 if(u1_min_mpeg2_qp > u1_avg_mpeg2_qp_temp)
461 u1_min_mpeg2_qp = u1_avg_mpeg2_qp_temp;
462 if(u1_max_mpeg2_qp < u1_avg_mpeg2_qp_temp)
463 u1_max_mpeg2_qp = u1_avg_mpeg2_qp_temp;
464
465 u1_num_frms_input++;
466 }
467
468 if(0 == u1_curr_frame_index)
469 u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1);
470 else
471 u1_curr_frame_index--;
472 }
473
474 /************************************************************************/
475 /* Add Pivot Points to the Data set to be used for finding Quadratic */
476 /* Model Coeffs. These will help in constraining the shape of Quadratic*/
477 /* to adapt too much to the Local deviations. */
478 /************************************************************************/
479 u1_min2_mpeg2_qp = u1_min_mpeg2_qp;
480 u1_max2_mpeg2_qp = u1_max_mpeg2_qp;
481 u1_min_qp_frame_indx = INVALID_FRAME_INDEX;
482 u1_max_qp_frame_indx = INVALID_FRAME_INDEX;
483
484 /* Loop runnning over the Stored Frame Level Data
485 to find frames of MinQp and MaxQp */
486 for(; i < ps_rd_model->u1_num_frms_in_model; i++)
487 {
488 u1_num_skips_temp = ps_rd_model->pu1_num_skips[u1_curr_frame_index];
489 u1_avg_mpeg2_qp_temp = ps_rd_model->pu1_avg_qp[u1_curr_frame_index];
490
491 if(((0 == u4_num_skips) && (0 != u1_num_skips_temp)) ||
492 ((1 == u4_num_skips) && (u1_num_skips_temp > 1)))
493 continue;
494
495 if(u1_min2_mpeg2_qp > u1_avg_mpeg2_qp_temp)
496 {
497 u1_min2_mpeg2_qp = u1_avg_mpeg2_qp_temp;
498 u1_min_qp_frame_indx = u1_curr_frame_index;
499 }
500 if(u1_max2_mpeg2_qp < u1_avg_mpeg2_qp_temp)
501 {
502 u1_max2_mpeg2_qp = u1_avg_mpeg2_qp_temp;
503 u1_max_qp_frame_indx = u1_curr_frame_index;
504 }
505 if(0 == u1_curr_frame_index)
506 u1_curr_frame_index = (MAX_FRAMES_MODELLED - 1);
507 else
508 u1_curr_frame_index--;
509 }
510
511 /* Add the Chosen Points to the regression data set */
512 if(INVALID_FRAME_INDEX != u1_min_qp_frame_indx)
513 {
514 pi1_frame_index[u1_num_frms_input] = (WORD8)u1_min_qp_frame_indx;
515 u1_num_frms_input++;
516 }
517 if(INVALID_FRAME_INDEX != u1_max_qp_frame_indx)
518 {
519 pi1_frame_index[u1_num_frms_input] = (WORD8)u1_max_qp_frame_indx;
520 u1_num_frms_input++;
521 }
522 memcpy(pi1_frame_index_initial, pi1_frame_index, MAX_FRAMES_MODELLED);
523
524 if(QUAD_MODEL == ps_rd_model->u1_model_used)
525 {
526 if(u1_num_frms_input < (MIN_FRAMES_FOR_QUAD_MODEL))
527 ps_rd_model->u1_model_used = LIN_MODEL;
528 if((WORD32)u1_max_mpeg2_qp < ((WORD32)(21 * u1_min_mpeg2_qp) >> 4))
529 ps_rd_model->u1_model_used = LIN_MODEL;
530 }
531
532 if(LIN_MODEL == ps_rd_model->u1_model_used)
533 {
534 if(u1_num_frms_input < MIN_FRAMES_FOR_LIN_MODEL)
535 ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
536 if((WORD32)u1_max_mpeg2_qp < ((WORD32)(19 * u1_min_mpeg2_qp) >> 4))
537 ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
538 }
539
540 /***** Call the Module to Return the Coeffs for the Fed Data *****/
541 ps_rd_model->u1_model_used = find_model_coeffs(
542 ps_rd_model->pi4_res_bits,
543 ps_rd_model->pi4_sad,
544 ps_rd_model->pu1_num_skips,
545 ps_rd_model->pu1_avg_qp,
546 u1_num_frms_input,
547 ps_rd_model->u1_model_used,
548 pi1_frame_index,
549 model_coeff_array,
550 model_coeff_array_lin,
551 model_coeff_array_lin_wo_int,
552 ps_rd_model);
553
554 if((model_coeff_array_lin[2] > 0) || (model_coeff_array_lin[0] < 0))
555 u1_lin_model_valid = 0;
556 else
557 {
558 u1_lin_model_valid = 1;
559 /* lin deviation calculation */
560 calc_avg_sqr_dev_for_model(
561 ps_rd_model->pi4_res_bits,
562 ps_rd_model->pi4_sad,
563 ps_rd_model->pu1_num_skips,
564 ps_rd_model->pu1_avg_qp,
565 u1_num_frms_input,
566 pi1_frame_index_initial,
567 model_coeff_array_lin,
568 &fl_lin_avg_dev);
569 }
570
571 if(QUAD_MODEL == ps_rd_model->u1_model_used)
572 {
573 u1_check_model = refine_set_of_points(
574 ps_rd_model->pi4_res_bits,
575 ps_rd_model->pi4_sad,
576 ps_rd_model->pu1_num_skips,
577 ps_rd_model->pu1_avg_qp,
578 u1_num_frms_input,
579 pi1_frame_index,
580 model_coeff_array,
581 &fl_quad_avg_dev);
582
583 if(2 == u1_check_model)
584 {
585 ps_rd_model->u1_model_used = QUAD_MODEL;
586 }
587 else
588 {
589 /*******************************************************************/
590 /* Make sure that some of the Pivot Points are used in the Refined */
591 /* data set. 1. Previous Frame */
592 /*******************************************************************/
593 /*pi1_frame_index[0] = ps_rd_model->u1_curr_frm_counter;*/
594
595 ps_rd_model->u1_model_used = find_model_coeffs(
596 ps_rd_model->pi4_res_bits,
597 ps_rd_model->pi4_sad,
598 ps_rd_model->pu1_num_skips,
599 ps_rd_model->pu1_avg_qp,
600 u1_num_frms_input,
601 ps_rd_model->u1_model_used,
602 pi1_frame_index,
603 model_coeff_array,
604 NULL,
605 NULL,
606 ps_rd_model);
607
608 u1_check_model = refine_set_of_points(
609 ps_rd_model->pi4_res_bits,
610 ps_rd_model->pi4_sad,
611 ps_rd_model->pu1_num_skips,
612 ps_rd_model->pu1_avg_qp,
613 u1_num_frms_input,
614 pi1_frame_index,
615 model_coeff_array,
616 &fl_quad_avg_dev);
617
618 if((0 == u1_check_model))
619 {
620 #if RC_MODEL_USED_BUG_FIX
621 if((fl_lin_avg_dev < fl_quad_avg_dev) && (1 == u1_lin_model_valid))
622 #endif
623 ps_rd_model->u1_model_used = LIN_MODEL;
624 }
625 }
626 }
627
628 if(QUAD_MODEL == ps_rd_model->u1_model_used)
629 {
630 /*min_res_bits = model_coeff_c -
631 ((model_coeff_a * model_coeff_a) / (4 * model_coeff_b));*/
632
633 if(model_coeff_array[0] < 0)
634 ps_rd_model->u1_model_used = LIN_MODEL;
635
636 /*if ((model_coeff_a * model_coeff_b) > 0)
637 u1_model_used = LIN_MODEL;*/
638 }
639 if(LIN_MODEL == ps_rd_model->u1_model_used)
640 {
641 if((model_coeff_array_lin[2] > 0) || (model_coeff_array_lin[0] < 0))
642 ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
643 }
644
645 #if RC_MODEL_USED_BUG_FIX
646 /* Another threshold of .25 on deviation i.e. deviation greater than 25% */
647 if((QUAD_MODEL == ps_rd_model->u1_model_used) && (fl_quad_avg_dev > .25))
648 ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
649
650 if((LIN_MODEL == ps_rd_model->u1_model_used) && (fl_lin_avg_dev > .25))
651 ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
652 #endif /* #if RC_MODEL_USED_BUG_FIX */
653
654 ps_rd_model->model_coeff_b_quad = model_coeff_array[0];
655 ps_rd_model->model_coeff_a_quad = model_coeff_array[1];
656 ps_rd_model->model_coeff_c_quad = model_coeff_array[2];
657
658 ps_rd_model->model_coeff_b_lin = model_coeff_array_lin[0];
659 ps_rd_model->model_coeff_a_lin = model_coeff_array_lin[1];
660 ps_rd_model->model_coeff_c_lin = model_coeff_array_lin[2];
661
662 ps_rd_model->model_coeff_b_lin_wo_int = model_coeff_array_lin_wo_int[0];
663 ps_rd_model->model_coeff_a_lin_wo_int = model_coeff_array_lin_wo_int[1];
664 ps_rd_model->model_coeff_c_lin_wo_int = model_coeff_array_lin_wo_int[2];
665
666 /*ps_rd_model->u1_model_used = PREV_FRAME_MODEL;*/
667 }
668 #endif /* ENABLE_QUAD_MODEL */
669
estimate_bits_for_qp(rc_rd_model_t * ps_rd_model,UWORD32 u4_estimated_sad,UWORD8 u1_avg_qp)670 UWORD32 estimate_bits_for_qp(rc_rd_model_t *ps_rd_model, UWORD32 u4_estimated_sad, UWORD8 u1_avg_qp)
671 {
672 float fl_num_bits;
673 /*ps_rd_model += u1_curr_pic_type;*/
674
675 {
676 fl_num_bits =
677 ps_rd_model->model_coeff_a_lin_wo_int * ((float)(u4_estimated_sad / u1_avg_qp));
678 }
679
680 return ((UWORD32)fl_num_bits);
681 }
682
find_qp_for_target_bits(rc_rd_model_t * ps_rd_model,UWORD32 u4_target_res_bits,UWORD32 u4_estimated_sad,UWORD8 u1_min_qp,UWORD8 u1_max_qp)683 UWORD8 find_qp_for_target_bits(
684 rc_rd_model_t *ps_rd_model,
685 UWORD32 u4_target_res_bits,
686 UWORD32 u4_estimated_sad,
687 UWORD8 u1_min_qp,
688 UWORD8 u1_max_qp)
689 {
690 UWORD8 u1_qp;
691 float x_value, f_qp;
692 /*ps_rd_model += u1_curr_pic_type;*/
693 #if ENABLE_QUAD_MODEL
694 if(QUAD_MODEL == ps_rd_model->u1_model_used)
695 {
696 float det;
697 det = (ps_rd_model->model_coeff_a_quad * ps_rd_model->model_coeff_a_quad) -
698 (4 * (ps_rd_model->model_coeff_b_quad) *
699 (ps_rd_model->model_coeff_c_quad - u4_target_res_bits));
700
701 if(det > 0)
702 {
703 x_value = sqrt(det);
704
705 x_value =
706 (x_value - ps_rd_model->model_coeff_a_quad) / (2 * ps_rd_model->model_coeff_b_quad);
707 }
708 else
709 ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
710 }
711
712 if(LIN_MODEL == ps_rd_model->u1_model_used)
713 {
714 x_value = ((float)u4_target_res_bits - ps_rd_model->model_coeff_c_lin) /
715 (ps_rd_model->model_coeff_b_lin);
716 }
717 #else
718 ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
719 #endif
720
721 if(PREV_FRAME_MODEL == ps_rd_model->u1_model_used)
722 {
723 x_value = (float)u4_target_res_bits / ps_rd_model->model_coeff_a_lin_wo_int;
724 }
725
726 if(0 != x_value)
727 f_qp = u4_estimated_sad / x_value;
728 else
729 f_qp = 255;
730
731 if(f_qp > 255)
732 f_qp = 255;
733
734 /* Truncating the QP to the Max and Min Qp values possible */
735 if(f_qp < u1_min_qp)
736 f_qp = u1_min_qp;
737 if(f_qp > u1_max_qp)
738 f_qp = u1_max_qp;
739
740 u1_qp = (UWORD8)(f_qp + 0.5);
741
742 return u1_qp;
743 }
744
add_frame_to_rd_model(rc_rd_model_t * ps_rd_model,UWORD32 i4_res_bits,UWORD8 u1_avg_mp2qp,UWORD32 i4_sad_h264,UWORD8 u1_num_skips)745 void add_frame_to_rd_model(
746 rc_rd_model_t *ps_rd_model,
747 UWORD32 i4_res_bits,
748 UWORD8 u1_avg_mp2qp,
749 UWORD32 i4_sad_h264,
750 UWORD8 u1_num_skips)
751 {
752 UWORD8 u1_curr_frame_index;
753 /*ps_rd_model += u1_curr_pic_type;*/
754 u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter;
755 /*** Insert the Present Frame Data into the RD Model State Memory ***/
756 ps_rd_model->pi4_res_bits[u1_curr_frame_index] = i4_res_bits;
757 ps_rd_model->pi4_sad[u1_curr_frame_index] = i4_sad_h264;
758 ps_rd_model->pu1_num_skips[u1_curr_frame_index] = u1_num_skips;
759 ps_rd_model->pu1_avg_qp[u1_curr_frame_index] = u1_avg_mp2qp;
760
761 ps_rd_model->u1_curr_frm_counter++;
762 if(MAX_FRAMES_MODELLED == ps_rd_model->u1_curr_frm_counter)
763 ps_rd_model->u1_curr_frm_counter = 0;
764
765 if(ps_rd_model->u1_num_frms_in_model < ps_rd_model->u1_max_frms_to_model)
766 {
767 ps_rd_model->u1_num_frms_in_model++;
768 }
769 update_frame_rd_model(ps_rd_model);
770 }
771
calc_per_frm_bits(rc_rd_model_t * ps_rd_model,UWORD16 * pu2_num_pics_of_a_pic_type,UWORD8 * pu1_update_pic_type_model,UWORD8 u1_num_pic_types,UWORD32 * pu4_num_skip_of_a_pic_type,UWORD8 u1_base_pic_type,float * pfl_gamma,float * pfl_eta,UWORD8 u1_curr_pic_type,UWORD32 u4_bits_for_sub_gop,UWORD32 u4_curr_estimated_sad,UWORD8 * pu1_curr_pic_type_qp)772 WORD32 calc_per_frm_bits(
773 rc_rd_model_t *ps_rd_model, /* array of model structs */
774 UWORD16 *pu2_num_pics_of_a_pic_type, /* N1, N2,...Nk */
775 UWORD8 *
776 pu1_update_pic_type_model, /* flag which tells whether or not to update model coefficients of a particular pic-type */
777 UWORD8 u1_num_pic_types, /* value of k */
778 UWORD32 *
779 pu4_num_skip_of_a_pic_type, /* the number of skips of that pic-type. It "may" be used to update the model coefficients at a later point. Right now it is not being used at all. */
780 UWORD8 u1_base_pic_type, /* base pic type index wrt which alpha & beta are calculated */
781 float *pfl_gamma, /* gamma_i = beta_i / alpha_i */
782 float *pfl_eta,
783 UWORD8
784 u1_curr_pic_type, /* the current pic-type for which the targetted bits need to be computed */
785 UWORD32
786 u4_bits_for_sub_gop, /* the number of bits to be consumed for the remaining part of sub-gop */
787 UWORD32 u4_curr_estimated_sad,
788 UWORD8 *pu1_curr_pic_type_qp) /* output of this function */
789 {
790 WORD32 i4_per_frm_bits_Ti;
791 UWORD8 u1_i;
792 rc_rd_model_t *ps_rd_model_of_pic_type;
793
794 /* first part of this function updates all the model coefficients */
795 /*for all the pic-types */
796 {
797 for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++)
798 {
799 if((0 != pu2_num_pics_of_a_pic_type[u1_i]) && (1 == pu1_update_pic_type_model[u1_i]))
800 {
801 /* ps_rd_model_of_pic_type = ps_rd_model + u1_i; */
802
803 update_frame_rd_model(&ps_rd_model[u1_i]);
804 }
805 }
806 }
807
808 /* The second part of this function deals with solving the
809 equation using all the pic-types models */
810
811 {
812 UWORD8 u1_combined_model_used;
813
814 /* first choose the model to be used */
815 u1_combined_model_used = QUAD_MODEL;
816
817 for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++)
818 {
819 ps_rd_model_of_pic_type = ps_rd_model + u1_i;
820
821 if((0 != pu2_num_pics_of_a_pic_type[u1_i]) &&
822 (QUAD_MODEL != ps_rd_model_of_pic_type->u1_model_used))
823 {
824 u1_combined_model_used = LIN_MODEL;
825 break;
826 }
827 }
828
829 if(u1_combined_model_used == LIN_MODEL)
830 {
831 for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++)
832 {
833 ps_rd_model_of_pic_type = ps_rd_model + u1_i;
834
835 if((0 != pu2_num_pics_of_a_pic_type[u1_i]) &&
836 (QUAD_MODEL != ps_rd_model_of_pic_type->u1_model_used) &&
837 (LIN_MODEL != ps_rd_model_of_pic_type->u1_model_used))
838 {
839 u1_combined_model_used = PREV_FRAME_MODEL;
840 break;
841 }
842 }
843 }
844
845 /* solve the equation for the */
846 {
847 model_coeff eff_A;
848 model_coeff eff_B;
849 model_coeff eff_C;
850 float fl_determinant;
851 float fl_sad_by_qp_base;
852 float fl_sad_by_qp_curr_frm;
853 float fl_qp_curr_frm;
854 float fl_bits_for_curr_frm;
855
856 /* If the combined chosen model is quad model */
857 if(QUAD_MODEL == u1_combined_model_used)
858 {
859 eff_A = 0.0;
860 eff_B = 0.0;
861 eff_C = 0.0;
862 for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++)
863 {
864 ps_rd_model_of_pic_type = ps_rd_model + u1_i;
865
866 eff_A +=
867 ((pfl_eta[u1_i] + pu2_num_pics_of_a_pic_type[u1_i] - 1) *
868 ps_rd_model_of_pic_type->model_coeff_a_quad * pfl_gamma[u1_i]);
869 eff_B +=
870 ((pfl_eta[u1_i] * pfl_eta[u1_i] + pu2_num_pics_of_a_pic_type[u1_i] - 1) *
871 ps_rd_model_of_pic_type->model_coeff_b_quad * pfl_gamma[u1_i] *
872 pfl_gamma[u1_i]);
873 eff_C +=
874 (pu2_num_pics_of_a_pic_type[u1_i] *
875 ps_rd_model_of_pic_type->model_coeff_c_quad);
876 }
877 eff_C -= u4_bits_for_sub_gop;
878
879 fl_determinant = eff_A * eff_A - 4 * eff_B * eff_C;
880
881 if(fl_determinant < 0)
882 {
883 u1_combined_model_used =
884 PREV_FRAME_MODEL; /* TO BE replaced by LIN_MODEL later */
885 }
886 else
887 {
888 fl_determinant = sqrt(fl_determinant);
889
890 fl_sad_by_qp_base = fl_determinant - eff_A;
891 fl_sad_by_qp_base = fl_sad_by_qp_base / (2 * eff_B);
892
893 fl_sad_by_qp_curr_frm =
894 fl_sad_by_qp_base * pfl_gamma[u1_curr_pic_type] * pfl_eta[u1_curr_pic_type];
895
896 ps_rd_model_of_pic_type = ps_rd_model + u1_curr_pic_type;
897
898 fl_bits_for_curr_frm =
899 ps_rd_model_of_pic_type->model_coeff_a_quad * fl_sad_by_qp_curr_frm +
900 ps_rd_model_of_pic_type->model_coeff_b_quad * fl_sad_by_qp_curr_frm *
901 fl_sad_by_qp_curr_frm +
902 ps_rd_model_of_pic_type->model_coeff_c_quad;
903 }
904 }
905
906 /* If the combined chosen model is linear model with an intercept */
907 if(LIN_MODEL == u1_combined_model_used)
908 {
909 eff_A = 0.0;
910 eff_B = 0.0;
911 eff_C = 0.0;
912 for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++)
913 {
914 ps_rd_model_of_pic_type = ps_rd_model + u1_i;
915
916 eff_A +=
917 ((pfl_eta[u1_i] + pu2_num_pics_of_a_pic_type[u1_i] - 1) *
918 ps_rd_model_of_pic_type->model_coeff_a_lin * pfl_gamma[u1_i]);
919
920 eff_C +=
921 (pu2_num_pics_of_a_pic_type[u1_i] *
922 ps_rd_model_of_pic_type->model_coeff_c_lin);
923 }
924 eff_C -= u4_bits_for_sub_gop;
925
926 fl_determinant = (-(eff_C / eff_A));
927
928 if((fl_determinant) <= 0)
929 {
930 u1_combined_model_used = PREV_FRAME_MODEL;
931 }
932 else
933 {
934 fl_sad_by_qp_base = fl_determinant;
935
936 fl_sad_by_qp_curr_frm =
937 fl_sad_by_qp_base * pfl_gamma[u1_curr_pic_type] * pfl_eta[u1_curr_pic_type];
938
939 ps_rd_model_of_pic_type = ps_rd_model + u1_curr_pic_type;
940
941 fl_bits_for_curr_frm =
942 ps_rd_model_of_pic_type->model_coeff_a_lin * fl_sad_by_qp_curr_frm +
943 ps_rd_model_of_pic_type->model_coeff_c_lin;
944 }
945 }
946
947 /* If the combined chosen model is linear model without an intercept */
948 if(PREV_FRAME_MODEL == u1_combined_model_used)
949 {
950 eff_A = 0.0;
951 eff_B = 0.0;
952 eff_C = 0.0;
953 for(u1_i = 0; u1_i < u1_num_pic_types; u1_i++)
954 {
955 ps_rd_model_of_pic_type = ps_rd_model + u1_i;
956
957 eff_A +=
958 ((pfl_eta[u1_i] + pu2_num_pics_of_a_pic_type[u1_i] - 1) *
959 ps_rd_model_of_pic_type->model_coeff_a_lin_wo_int * pfl_gamma[u1_i]);
960 }
961
962 fl_sad_by_qp_base = u4_bits_for_sub_gop / eff_A;
963
964 fl_sad_by_qp_curr_frm =
965 fl_sad_by_qp_base * pfl_gamma[u1_curr_pic_type] * pfl_eta[u1_curr_pic_type];
966
967 ps_rd_model_of_pic_type = ps_rd_model + u1_curr_pic_type;
968
969 fl_bits_for_curr_frm =
970 ps_rd_model_of_pic_type->model_coeff_a_lin_wo_int * fl_sad_by_qp_curr_frm;
971 }
972
973 /* store the model that was finally used to calculate Qp.
974 This is so that the same model is used in further calculations for this picture. */
975 ps_rd_model_of_pic_type = ps_rd_model + u1_curr_pic_type;
976 ps_rd_model_of_pic_type->u1_model_used = u1_combined_model_used;
977
978 i4_per_frm_bits_Ti = (WORD32)(fl_bits_for_curr_frm + 0.5);
979
980 if(fl_sad_by_qp_curr_frm > 0)
981 fl_qp_curr_frm = (float)u4_curr_estimated_sad / fl_sad_by_qp_curr_frm;
982 else
983 fl_qp_curr_frm = 255;
984
985 if(fl_qp_curr_frm > 255)
986 fl_qp_curr_frm = 255;
987
988 *pu1_curr_pic_type_qp = (fl_qp_curr_frm + 0.5);
989 }
990 }
991 return (i4_per_frm_bits_Ti);
992 }
993
get_linear_coefficient(rc_rd_model_t * ps_rd_model)994 model_coeff get_linear_coefficient(rc_rd_model_t *ps_rd_model)
995 {
996 /*UWORD32 linear_coeff:
997 linear_coeff = ps_rd_model->model_coeff_a_lin_wo_int;*/
998 return (ps_rd_model->model_coeff_a_lin_wo_int);
999 }
1000 #endif /* !(RC_FIXED_POINT) */
rc_rd_model_dummy_for_avoiding_warnings(rc_rd_model_t ** pps_rc_rd_model,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)1001 WORD32 rc_rd_model_dummy_for_avoiding_warnings(
1002 rc_rd_model_t **pps_rc_rd_model, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
1003 {
1004 WORD32 i4_mem_tab_idx = 0;
1005 static rc_rd_model_t s_rc_rd_model_temp;
1006
1007 /* Hack for al alloc, during which we dont have any state memory.
1008 Dereferencing can cause issues */
1009 if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
1010 (*pps_rc_rd_model) = &s_rc_rd_model_temp;
1011
1012 /*for src rate control state structure*/
1013 if(e_func_type != GET_NUM_MEMTAB)
1014 {
1015 fill_memtab(
1016 &ps_memtab[i4_mem_tab_idx], sizeof(rc_rd_model_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR);
1017 use_or_fill_base(&ps_memtab[0], (void **)pps_rc_rd_model, e_func_type);
1018 }
1019 i4_mem_tab_idx++;
1020
1021 return (i4_mem_tab_idx);
1022 }
1023