• 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 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