• 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 /* File Includes                                                             */
39 /*****************************************************************************/
40 /* System include files */
41 #include <stdarg.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <math.h>
46 
47 /* User include files */
48 #include "ittiam_datatypes.h"
49 #include "var_q_operator.h"
50 #include "rc_common.h"
51 #include "rc_cntrl_param.h"
52 #include "mem_req_and_acq.h"
53 #include "rc_rd_model.h"
54 #include "rc_rd_model_struct.h"
55 
56 #if RC_FIXED_POINT
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)57 WORD32 rc_rd_model_num_fill_use_free_memtab(
58     rc_rd_model_t **pps_rc_rd_model, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
59 {
60     WORD32 i4_mem_tab_idx = 0;
61     static rc_rd_model_t s_rc_rd_model_temp;
62 
63     /* Hack for al alloc, during which we dont have any state memory.
64       Dereferencing can cause issues */
65     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
66         (*pps_rc_rd_model) = &s_rc_rd_model_temp;
67 
68     /*for src rate control state structure*/
69     if(e_func_type != GET_NUM_MEMTAB)
70     {
71         fill_memtab(
72             &ps_memtab[i4_mem_tab_idx], sizeof(rc_rd_model_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR);
73         use_or_fill_base(&ps_memtab[0], (void **)pps_rc_rd_model, e_func_type);
74     }
75     i4_mem_tab_idx++;
76 
77     return (i4_mem_tab_idx);
78 }
79 /******************************************************************************
80   Function Name   : init_frm_rc_rd_model
81   Description     :
82   Arguments       : ps_rd_model
83   Return Values   : void
84   Revision History:
85                     Creation
86 *****************************************************************************/
init_frm_rc_rd_model(rc_rd_model_t * ps_rd_model,UWORD8 u1_max_frames_modelled)87 void init_frm_rc_rd_model(rc_rd_model_t *ps_rd_model, UWORD8 u1_max_frames_modelled)
88 {
89     /* ps_rd_model = ps_rd_model + u1_pic_type; */
90 
91     ps_rd_model->u1_num_frms_in_model = 0;
92     ps_rd_model->u1_curr_frm_counter = 0;
93     ps_rd_model->u1_max_frms_to_model = u1_max_frames_modelled;
94 
95     ps_rd_model->model_coeff_a_quad.sm = 0;
96     ps_rd_model->model_coeff_b_quad.sm = 0;
97     ps_rd_model->model_coeff_c_quad.sm = 0;
98 
99     ps_rd_model->model_coeff_a_lin.sm = 0;
100     ps_rd_model->model_coeff_b_lin.sm = 0;
101     ps_rd_model->model_coeff_c_lin.sm = 0;
102 
103     ps_rd_model->model_coeff_a_lin_wo_int.sm = 0;
104     ps_rd_model->model_coeff_b_lin_wo_int.sm = 0;
105     ps_rd_model->model_coeff_c_lin_wo_int.sm = 0;
106 
107     ps_rd_model->model_coeff_a_quad.e = 0;
108     ps_rd_model->model_coeff_b_quad.e = 0;
109     ps_rd_model->model_coeff_c_quad.e = 0;
110 
111     ps_rd_model->model_coeff_a_lin.e = 0;
112     ps_rd_model->model_coeff_b_lin.e = 0;
113     ps_rd_model->model_coeff_c_lin.e = 0;
114 
115     ps_rd_model->model_coeff_a_lin_wo_int.e = 0;
116     ps_rd_model->model_coeff_b_lin_wo_int.e = 0;
117     ps_rd_model->model_coeff_c_lin_wo_int.e = 0;
118 }
119 /******************************************************************************
120   Function Name   : reset_frm_rc_rd_model
121   Description     :
122   Arguments       : ps_rd_model
123   Return Values   : void
124   Revision History:
125                     Creation
126 *****************************************************************************/
reset_frm_rc_rd_model(rc_rd_model_t * ps_rd_model)127 void reset_frm_rc_rd_model(rc_rd_model_t *ps_rd_model)
128 {
129     ps_rd_model->u1_num_frms_in_model = 0;
130     ps_rd_model->u1_curr_frm_counter = 0;
131 
132     ps_rd_model->model_coeff_a_quad.sm = 0;
133     ps_rd_model->model_coeff_b_quad.sm = 0;
134     ps_rd_model->model_coeff_c_quad.sm = 0;
135 
136     ps_rd_model->model_coeff_a_lin.sm = 0;
137     ps_rd_model->model_coeff_b_lin.sm = 0;
138     ps_rd_model->model_coeff_c_lin.sm = 0;
139 
140     ps_rd_model->model_coeff_a_lin_wo_int.sm = 0;
141     ps_rd_model->model_coeff_b_lin_wo_int.sm = 0;
142     ps_rd_model->model_coeff_c_lin_wo_int.sm = 0;
143 
144     ps_rd_model->model_coeff_a_quad.e = 0;
145     ps_rd_model->model_coeff_b_quad.e = 0;
146     ps_rd_model->model_coeff_c_quad.e = 0;
147 
148     ps_rd_model->model_coeff_a_lin.e = 0;
149     ps_rd_model->model_coeff_b_lin.e = 0;
150     ps_rd_model->model_coeff_c_lin.e = 0;
151 
152     ps_rd_model->model_coeff_a_lin_wo_int.e = 0;
153     ps_rd_model->model_coeff_b_lin_wo_int.e = 0;
154     ps_rd_model->model_coeff_c_lin_wo_int.e = 0;
155 }
156 
157 #if ENABLE_QUAD_MODEL
158 /******************************************************************************
159   Function Name   : find_model_coeffs
160   Description     :
161   Arguments       :
162   Return Values   : void
163   Revision History:
164                     Creation
165 *****************************************************************************/
find_model_coeffs(UWORD32 * pi4_res_bits,LWORD64 * pi8_sad_h264,WORD32 * pi4_avg_mpeg2_qp_q6,UWORD8 u1_num_frms,UWORD8 u1_model_used,WORD8 * pi1_frame_index,number_t * pmc_model_coeff,number_t * pmc_model_coeff_lin,number_t * pmc_model_coeff_lin_wo_int,rc_rd_model_t * ps_rd_model)166 static UWORD8 find_model_coeffs(
167     UWORD32 *pi4_res_bits,
168     LWORD64 *pi8_sad_h264,
169     WORD32 *pi4_avg_mpeg2_qp_q6,
170     UWORD8 u1_num_frms,
171     UWORD8 u1_model_used,
172     WORD8 *pi1_frame_index,
173     number_t *pmc_model_coeff,
174     number_t *pmc_model_coeff_lin,
175     number_t *pmc_model_coeff_lin_wo_int,
176     rc_rd_model_t *ps_rd_model)
177 {
178     UWORD32 i;
179     UWORD8 u1_num_frms_used = 0;
180     UWORD8 u1_frm_indx;
181 
182     number_t sum_y;
183     number_t sum_x_y;
184     number_t sum_x2_y;
185     number_t sum_x;
186     number_t sum_x2;
187     number_t sum_x3;
188     number_t sum_x4;
189     number_t var_x2_y;
190     number_t var_x_y;
191     number_t var_x2_x;
192     number_t var_x2_x2;
193     number_t var_x_x;
194     number_t x0, y0;
195     number_t s_res_bits, s_sad_h264, s_avg_mpeg2_qp;
196     number_t temp, temp1;
197 
198     number_t model_coeff_a, model_coeff_b, model_coeff_c, model_coeff_den;
199 
200     number_t s_num_frms_used;
201 
202     /* initilising */
203     model_coeff_a.sm = 0;
204     model_coeff_a.e = 0;
205     model_coeff_b.sm = 0;
206     model_coeff_b.e = 0;
207     model_coeff_c.sm = 0;
208     model_coeff_c.e = 0;
209 
210     sum_y.sm = 0;
211     sum_x_y.sm = 0;
212     sum_x2_y.sm = 0;
213     sum_x.sm = 0;
214     sum_x2.sm = 0;
215     sum_x3.sm = 0;
216     sum_x4.sm = 0;
217     var_x2_y.sm = 0;
218     var_x_y.sm = 0;
219     var_x2_x.sm = 0;
220     var_x2_x2.sm = 0;
221     var_x_x.sm = 0;
222 
223     sum_y.e = 0;
224     sum_x_y.e = 0;
225     sum_x2_y.e = 0;
226     sum_x.e = 0;
227     sum_x2.e = 0;
228     sum_x3.e = 0;
229     sum_x4.e = 0;
230     var_x2_y.e = 0;
231     var_x_y.e = 0;
232     var_x2_x.e = 0;
233     var_x2_x2.e = 0;
234     var_x_x.e = 0;
235 
236     for(i = 0; i < u1_num_frms; i++)
237     {
238         LWORD64 i8_local_sad_sm = 0;
239         WORD32 i4_local_e = 0;
240         if(-1 == pi1_frame_index[i])
241             continue;
242 
243         u1_frm_indx = (UWORD8)pi1_frame_index[i];
244 
245         s_res_bits.sm = pi4_res_bits[u1_frm_indx];
246         s_res_bits.e = 0;
247 
248         /*s_sad_h264.sm = pi8_sad_h264[u1_frm_indx];
249         s_sad_h264.e  = 0;*/
250         i8_local_sad_sm = pi8_sad_h264[u1_frm_indx];
251 
252         while(i8_local_sad_sm > 0x7FFFFFFF)
253         {
254             i8_local_sad_sm = i8_local_sad_sm / 2;
255             i4_local_e++;
256         }
257         SET_VARQ_FRM_FIXQ(((WORD32)i8_local_sad_sm), s_sad_h264, -i4_local_e);
258 
259         /*fract_quant*/
260         SET_VARQ_FRM_FIXQ(pi4_avg_mpeg2_qp_q6[u1_frm_indx], s_avg_mpeg2_qp, QSCALE_Q_FAC);
261 
262         y0 = s_res_bits;
263         /*x0 = (float) (pi4_sad_h264[u1_frm_indx] /
264                      (float)pui_avg_mpeg2_qp[u1_frm_indx]); */
265         div32_var_q(s_sad_h264, s_avg_mpeg2_qp, &x0);
266 
267         /*
268         sum_y    += y0;
269         sum_x_y  += x0 * y0;
270         sum_x2_y += x0 * x0 * y0;
271         sum_x    += x0;
272         sum_x2   += x0 * x0;
273         sum_x3   += x0 * x0 * x0;
274         sum_x4   += x0 * x0 * x0 * x0;
275         */
276         /* sum_y    += y0; */
277         add32_var_q(sum_y, y0, &sum_y);
278         /* sum_x_y  += x0 * y0; */
279         mult32_var_q(x0, y0, &temp);
280         add32_var_q(sum_x_y, temp, &sum_x_y);
281 
282         /* sum_x2_y += x0 * x0 * y0; */
283         mult32_var_q(x0, temp, &temp);
284         add32_var_q(sum_x2_y, temp, &sum_x2_y);
285 
286         /* sum_x    += x0; */
287         add32_var_q(x0, sum_x, &sum_x);
288 
289         /* sum_x2   += x0 * x0; */
290         mult32_var_q(x0, x0, &temp);
291         add32_var_q(temp, sum_x2, &sum_x2);
292 
293         /* sum_x3   += x0 * x0 * x0; */
294         mult32_var_q(x0, temp, &temp);
295         add32_var_q(temp, sum_x3, &sum_x3);
296 
297         /* sum_x4   += x0 * x0 * x0 * x0; */
298         mult32_var_q(x0, temp, &temp);
299         add32_var_q(temp, sum_x4, &sum_x4);
300 
301         u1_num_frms_used++;
302     }
303 
304     s_num_frms_used.sm = u1_num_frms_used;
305     s_num_frms_used.e = 0;
306 
307     /* sum_y    /= u1_num_frms_used; */
308     div32_var_q(sum_y, s_num_frms_used, &sum_y);
309     /* sum_x_y  /= u1_num_frms_used; */
310     div32_var_q(sum_x_y, s_num_frms_used, &sum_x_y);
311     /* sum_x2_y /= u1_num_frms_used; */
312     div32_var_q(sum_x2_y, s_num_frms_used, &sum_x2_y);
313 
314     /* sum_x    /= u1_num_frms_used; */
315     div32_var_q(sum_x, s_num_frms_used, &sum_x);
316 
317     /* sum_x2   /= u1_num_frms_used; */
318     div32_var_q(sum_x2, s_num_frms_used, &sum_x2);
319 
320     /* sum_x3   /= u1_num_frms_used; */
321     div32_var_q(sum_x3, s_num_frms_used, &sum_x3);
322 
323     /* sum_x4   /= u1_num_frms_used; */
324     div32_var_q(sum_x4, s_num_frms_used, &sum_x4);
325 
326 #if !QUAD
327     u1_model_used = LIN_MODEL;
328 #endif
329 
330     if((QUAD_MODEL == u1_model_used) && (u1_num_frms_used <= MIN_FRAMES_FOR_QUAD_MODEL))
331     {
332         u1_model_used = LIN_MODEL;
333     }
334 
335     if(QUAD_MODEL == u1_model_used)
336     {
337         /* var_x2_y  = sum_x2_y - sum_x2 * sum_y; */
338         mult32_var_q(sum_x2, sum_y, &temp);
339         sub32_var_q(sum_x2_y, temp, &var_x2_y);
340 
341         /* var_x_y   = sum_x_y  - sum_x  * sum_y; */
342         mult32_var_q(sum_x, sum_y, &temp);
343         sub32_var_q(sum_x_y, temp, &var_x_y);
344 
345         /* var_x2_x  = sum_x3   - sum_x2 * sum_x; */
346         mult32_var_q(sum_x2, sum_x, &temp);
347         sub32_var_q(sum_x3, temp, &var_x2_x);
348 
349         /* var_x2_x2 = sum_x4   - sum_x2 * sum_x2; */
350         mult32_var_q(sum_x2, sum_x2, &temp);
351         sub32_var_q(sum_x4, temp, &var_x2_x2);
352 
353         /* var_x_x   = sum_x2   - sum_x  * sum_x; */
354         mult32_var_q(sum_x, sum_x, &temp);
355         sub32_var_q(sum_x2, temp, &var_x_x);
356 
357         /* model_coeff_den = (var_x2_x * var_x2_x - var_x2_x2 * var_x_x); */
358         mult32_var_q(var_x2_x, var_x2_x, &temp);
359         mult32_var_q(var_x2_x2, var_x_x, &temp1);
360         sub32_var_q(temp, temp1, &model_coeff_den);
361 
362         if(0 != model_coeff_den.sm)
363         {
364             /* model_coeff_b   = (var_x_y * var_x2_x - var_x2_y * var_x_x); */
365             mult32_var_q(var_x_y, var_x2_x, &temp);
366             mult32_var_q(var_x2_y, var_x_x, &temp1);
367             sub32_var_q(temp, temp1, &model_coeff_b);
368 
369             /* model_coeff_b   /= model_coeff_den; */
370             div32_var_q(model_coeff_b, model_coeff_den, &model_coeff_b);
371 
372             /* model_coeff_a   = (var_x2_y * var_x2_x - var_x_y * var_x2_x2); */
373             mult32_var_q(var_x2_y, var_x2_x, &temp);
374             mult32_var_q(var_x_y, var_x2_x2, &temp1);
375             sub32_var_q(temp, temp1, &model_coeff_a);
376 
377             /* model_coeff_a   /= model_coeff_den; */
378             div32_var_q(model_coeff_a, model_coeff_den, &model_coeff_a);
379 
380             /*model_coeff_c   = sum_y - (model_coeff_a * sum_x) -
381                               (model_coeff_b * sum_x2); */
382             mult32_var_q(model_coeff_a, sum_x, &temp);
383             mult32_var_q(model_coeff_b, sum_x2, &temp1);
384             sub32_var_q(sum_y, temp, &model_coeff_c);
385             sub32_var_q(model_coeff_c, temp1, &model_coeff_c);
386             /* till here */
387         }
388 
389         pmc_model_coeff[0] = model_coeff_b;
390         /* pmc_model_coeff[0] = (float)(model_coeff_b.sm /pow(2,model_coeff_b.e)); */
391         pmc_model_coeff[1] = model_coeff_a;
392         /* pmc_model_coeff[1] = (float)(model_coeff_a.sm /pow(2,model_coeff_a.e)); */
393         pmc_model_coeff[2] = model_coeff_c;
394         /* pmc_model_coeff[2] = (float)(model_coeff_c.sm /pow(2,model_coeff_c.e)); */
395     }
396 
397     if(NULL != pmc_model_coeff_lin)
398     {
399         /* var_x_y   = sum_x_y  - sum_x  * sum_y; */
400         mult32_var_q(sum_x, sum_y, &temp);
401         sub32_var_q(sum_x_y, temp, &var_x_y);
402 
403         /* var_x_x   = sum_x2   - sum_x  * sum_x; */
404         mult32_var_q(sum_x, sum_x, &temp);
405         sub32_var_q(sum_x2, temp, &var_x_x);
406 
407         if((0 != var_x_x.sm) && (u1_num_frms > 1))
408         {
409             /* model_coeff_b = (var_x_y / var_x_x); */
410             div32_var_q(var_x_y, var_x_x, &model_coeff_b);
411 
412             /* model_coeff_c = sum_y - (model_coeff_b * sum_x); */
413             mult32_var_q(model_coeff_b, sum_x, &temp);
414             sub32_var_q(sum_y, temp, &model_coeff_c);
415 
416             model_coeff_a = model_coeff_b;
417 
418             pmc_model_coeff_lin[0] = model_coeff_b;
419             /* pmc_model_coeff_lin[0] = (float)(model_coeff_b.sm /pow(2,model_coeff_b.e)); */
420 
421             pmc_model_coeff_lin[1] = model_coeff_a;
422             /* pmc_model_coeff_lin[1] = (float)(model_coeff_a.sm /pow(2,model_coeff_a.e)); */
423 
424             pmc_model_coeff_lin[2] = model_coeff_c;
425             /* pmc_model_coeff_lin[2] = (float)(model_coeff_c.sm /pow(2,model_coeff_c.e)); */
426         }
427     }
428 
429     /*  TO DO : FLOAT_TO_FIX */
430     if(NULL != pmc_model_coeff_lin_wo_int)
431     {
432         UWORD8 u1_curr_frame_index;
433         /* UWORD8 u1_avgqp_prvfrm; */
434         number_t s_avgqp_prvfrm;
435         /* UWORD32 u4_prevfrm_bits, u4_prevfrm_sad; */
436         number_t s_prevfrm_bits, s_prevfrm_sad;
437         WORD32 i4_local_e = 0;
438         LWORD64 i8_local_sad_sm = 0;
439         u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter;
440         if(0 == u1_curr_frame_index)
441             u1_curr_frame_index = (UWORD8)(ps_rd_model->u1_max_frms_to_model - 1);
442         else
443             u1_curr_frame_index--;
444 
445         /* u1_avgqp_prvfrm = ps_rd_model->pu1_avg_mp2qp[u1_curr_frame_index]; */
446         /*fract_quant*/
447         SET_VARQ_FRM_FIXQ(
448             ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index], s_avgqp_prvfrm, QSCALE_Q_FAC);
449 
450         /* u4_prevfrm_bits = ps_rd_model->pi4_res_bits[u1_curr_frame_index]; */
451         s_prevfrm_bits.sm = ps_rd_model->pi4_res_bits[u1_curr_frame_index];
452         s_prevfrm_bits.e = 0;
453 
454         /* u4_prevfrm_sad  = ps_rd_model->pi4_sad_h264[u1_curr_frame_index]; */
455         /*s_prevfrm_sad.sm = ps_rd_model->pi8_sad[u1_curr_frame_index];
456         s_prevfrm_sad.e  = 0;*/
457         i8_local_sad_sm = ps_rd_model->pi8_sad[u1_curr_frame_index];
458         while(i8_local_sad_sm > 0x7FFFFFFF)
459         {
460             i8_local_sad_sm = i8_local_sad_sm / 2;
461             i4_local_e++;
462         }
463         SET_VARQ_FRM_FIXQ(((WORD32)i8_local_sad_sm), s_prevfrm_sad, -i4_local_e);
464 
465         if(0 != s_prevfrm_sad.sm)
466         {
467             /* model_coeff_a = (float)(u4_prevfrm_bits * u1_avgqp_prvfrm) / u4_prevfrm_sad; */
468             mult32_var_q(s_prevfrm_bits, s_avgqp_prvfrm, &model_coeff_a);
469             div32_var_q(model_coeff_a, s_prevfrm_sad, &model_coeff_a);
470         }
471         else
472         {
473             model_coeff_a.sm = 0;
474             model_coeff_a.e = 0;
475         }
476 
477         model_coeff_b.sm = 0;
478         model_coeff_b.e = 0;
479         model_coeff_c.sm = 0;
480         model_coeff_c.e = 0;
481 
482         pmc_model_coeff_lin_wo_int[0] = model_coeff_b;
483         pmc_model_coeff_lin_wo_int[1] = model_coeff_a;
484         pmc_model_coeff_lin_wo_int[2] = model_coeff_c;
485     }
486     /* end of "TO DO : FLOAT_TO_FIX" */
487 
488     return u1_model_used;
489 }
490 
491 /******************************************************************************
492   Function Name   : refine_set_of_points
493   Description     :
494   Arguments       :
495   Return Values   : void
496   Revision History:
497                     Creation
498 *****************************************************************************/
refine_set_of_points(UWORD32 * pi4_res_bits,LWORD64 * pi8_sad_h264,WORD32 * pi4_avg_mpeg2_qp_q6,UWORD8 u1_num_frms,WORD8 * pi1_frame_index,number_t * ps_model_coeff,number_t * ps_avg_deviation)499 static WORD8 refine_set_of_points(
500     UWORD32 *pi4_res_bits,
501     LWORD64 *pi8_sad_h264,
502     WORD32 *pi4_avg_mpeg2_qp_q6,
503     UWORD8 u1_num_frms,
504     WORD8 *pi1_frame_index,
505     number_t *ps_model_coeff,
506     number_t *ps_avg_deviation)
507 {
508     /* float  fl_avg_deviation, fl_estimated_bits, fl_deviation, x_val; */
509     number_t s_avg_deviation, s_estimated_bits, s_deviation, x_val;
510     /* number_t  ps_model_coeff[3]; */
511     number_t s_sad_h264, s_avg_mpeg2_qp, s_res_bits;
512     number_t temp, temp1;
513     UWORD8 u1_return_value = 1;
514     UWORD32 i;
515     UWORD8 u1_num_frms_used, u1_frm_indx;
516     number_t s_num_frms_used;
517 
518     /*
519     convert_float_to_fix(pmc_model_coeff[0],&ps_model_coeff[0]);
520     convert_float_to_fix(pmc_model_coeff[1],&ps_model_coeff[1]);
521     convert_float_to_fix(pmc_model_coeff[2],&ps_model_coeff[2]);
522     */
523 
524     u1_num_frms_used = 0;
525     /* fl_avg_deviation = 0; */
526     s_avg_deviation.sm = 0;
527     s_avg_deviation.e = 0;
528 
529     for(i = 0; i < u1_num_frms; i++)
530     {
531         LWORD64 i8_local_sad_sm = 0;
532         WORD32 i4_local_e = 0;
533         if(-1 == pi1_frame_index[i])
534             continue;
535 
536         u1_frm_indx = (UWORD8)pi1_frame_index[i];
537         /*x_val = pi4_sad_h264[u1_frm_indx] /
538                 (float) pui_avg_mpeg2_qp[u1_frm_indx]; */
539         /* s_sad_h264.sm = pi8_sad_h264[u1_frm_indx];
540         s_sad_h264.e  = 0;*/
541 
542         i8_local_sad_sm = pi8_sad_h264[u1_frm_indx];
543         while(i8_local_sad_sm > 0x7FFFFFFF)
544         {
545             i8_local_sad_sm = i8_local_sad_sm / 2;
546             i4_local_e++;
547         }
548         SET_VARQ_FRM_FIXQ(((WORD32)i8_local_sad_sm), s_sad_h264, -i4_local_e);
549 
550         /*fract_quant*/
551         SET_VARQ_FRM_FIXQ(pi4_avg_mpeg2_qp_q6[u1_frm_indx], s_avg_mpeg2_qp, QSCALE_Q_FAC);
552 
553         div32_var_q(s_sad_h264, s_avg_mpeg2_qp, &x_val);
554 
555         /*
556         fl_estimated_bits = (pmc_model_coeff[0] * x_val * x_val ) +
557                             (pmc_model_coeff[1] * x_val) +
558                             (pmc_model_coeff[2]);
559                             */
560         mult32_var_q(x_val, x_val, &temp);
561         mult32_var_q(temp, ps_model_coeff[0], &temp);
562         mult32_var_q(x_val, ps_model_coeff[1], &temp1);
563         add32_var_q(temp, temp1, &s_estimated_bits);
564         add32_var_q(s_estimated_bits, ps_model_coeff[2], &s_estimated_bits);
565 
566         /*
567         fl_deviation        = fabs(pi4_res_bits[u1_frm_indx] - fl_estimated_bits) /
568                               (float) pi4_res_bits[u1_frm_indx];
569                               */
570         s_res_bits.sm = pi4_res_bits[u1_frm_indx];
571         s_res_bits.e = 0;
572         sub32_var_q(s_res_bits, s_estimated_bits, &temp);
573         temp.sm = (temp.sm > 0) ? temp.sm : (-temp.sm);
574         div32_var_q(temp, s_res_bits, &s_deviation);
575 
576         /* fl_deviation        = fl_deviation * fl_deviation; */
577         mult32_var_q(s_deviation, s_deviation, &s_deviation);
578 
579         /* fl_avg_deviation    += fl_deviation;*/
580         add32_var_q(s_avg_deviation, s_deviation, &s_avg_deviation);
581 
582         u1_num_frms_used++;
583     }
584 
585     /* fl_avg_deviation /= u1_num_frms_used; */
586     s_num_frms_used.sm = u1_num_frms_used;
587     s_num_frms_used.e = 0;
588     div32_var_q(s_avg_deviation, s_num_frms_used, &s_avg_deviation);
589 
590     /* fl_avg_deviation = sqrt(fl_avg_deviation); */
591     /* fl_avg_deviation = (fl_avg_deviation); */
592 
593     for(i = 0; i < u1_num_frms; i++)
594     {
595         LWORD64 i8_local_sad_sm = 0;
596         WORD32 i4_local_e = 0;
597         if ((-1 == pi1_frame_index[i]) /*&&
598             (i != 0)*/)
599             continue;
600 
601         u1_frm_indx = (UWORD8)pi1_frame_index[i];
602 
603         /*
604         x_val = pi4_sad_h264[u1_frm_indx] /
605                 (float) pui_avg_mpeg2_qp[u1_frm_indx];
606                 */
607 
608         /* s_sad_h264.sm = pi8_sad_h264[u1_frm_indx];
609         s_sad_h264.e  = 0;*/
610 
611         i8_local_sad_sm = pi8_sad_h264[u1_frm_indx];
612         while(i8_local_sad_sm > 0x7FFFFFFF)
613         {
614             i8_local_sad_sm = i8_local_sad_sm / 2;
615             i4_local_e++;
616         }
617         SET_VARQ_FRM_FIXQ(((WORD32)i8_local_sad_sm), s_sad_h264, -i4_local_e);
618 
619         /*fract_quant*/
620         SET_VARQ_FRM_FIXQ(pi4_avg_mpeg2_qp_q6[u1_frm_indx], s_avg_mpeg2_qp, QSCALE_Q_FAC);
621 
622         div32_var_q(s_sad_h264, s_avg_mpeg2_qp, &x_val);
623 
624         /*
625         fl_estimated_bits = (pmc_model_coeff[0] * x_val * x_val ) +
626                             (pmc_model_coeff[1] * x_val) +
627                             (pmc_model_coeff[2]);
628                             */
629         mult32_var_q(x_val, x_val, &temp);
630         mult32_var_q(temp, ps_model_coeff[0], &temp);
631         mult32_var_q(x_val, ps_model_coeff[1], &temp1);
632         add32_var_q(temp, temp1, &s_estimated_bits);
633         add32_var_q(s_estimated_bits, ps_model_coeff[2], &s_estimated_bits);
634 
635         /*
636         fl_deviation      = fabs(pi4_res_bits[u1_frm_indx] - fl_estimated_bits) /
637                             (float) pi4_res_bits[u1_frm_indx];
638                             */
639         s_res_bits.sm = pi4_res_bits[u1_frm_indx];
640         s_res_bits.e = 0;
641         sub32_var_q(s_res_bits, s_estimated_bits, &temp);
642         temp.sm = (temp.sm > 0) ? temp.sm : (-temp.sm);
643         div32_var_q(temp, s_res_bits, &s_deviation);
644 
645         /* to remove the sqrt function */
646         /*fl_deviation = fl_deviation * fl_deviation; */
647         mult32_var_q(s_deviation, s_deviation, &s_deviation);
648 
649         /*
650         if (fl_deviation > (fl_avg_deviation))
651         {
652             pi1_frame_index[i] = -1;
653         }
654         */
655         sub32_var_q(s_deviation, s_avg_deviation, &temp);
656         if(temp.sm > 0)
657         {
658             pi1_frame_index[i] = -1;
659         }
660     }
661 
662     {
663         number_t up_thr, lo_thr;
664 
665         /*
666         if (fl_avg_deviation > 0.0625)
667         u1_return_value = 0;
668         */
669         up_thr.sm = UP_THR_SM;
670         up_thr.e = UP_THR_E;
671         sub32_var_q(s_avg_deviation, up_thr, &temp);
672         if(temp.sm > 0)
673         {
674             u1_return_value = 0;
675         }
676 
677         /*
678         if (fl_avg_deviation < 0.0225)
679             u1_return_value = 2;
680             */
681         lo_thr.sm = LO_THR_SM;
682         lo_thr.e = LO_THR_E;
683         sub32_var_q(s_avg_deviation, lo_thr, &temp);
684         if(temp.sm < 0)
685         {
686             u1_return_value = 2;
687         }
688     }
689     *ps_avg_deviation = s_avg_deviation;
690     return (u1_return_value);
691 }
692 /******************************************************************************
693   Function Name   : calc_avg_sqr_dev_for_model
694   Description     :
695   Arguments       :
696   Return Values   : void
697   Revision History:
698                     Creation
699 *****************************************************************************/
700 /* TO DO : FLOAT_TO_FIX */
calc_avg_sqr_dev_for_model(UWORD32 * pi4_res_bits,LWORD64 * pi8_sad_h264,WORD32 * pi4_avg_mpeg2_qp_q6,UWORD8 u1_num_frms,WORD8 * pi1_frame_index,number_t * ps_model_coeff,number_t * ps_avg_deviation)701 static void calc_avg_sqr_dev_for_model(
702     UWORD32 *pi4_res_bits,
703     LWORD64 *pi8_sad_h264,
704     WORD32 *pi4_avg_mpeg2_qp_q6,
705     UWORD8 u1_num_frms,
706     WORD8 *pi1_frame_index,
707     number_t *ps_model_coeff,
708     number_t *ps_avg_deviation)
709 {
710     /* float  fl_avg_deviation, fl_estimated_bits, fl_deviation, x_val; */
711     number_t s_avg_deviation, s_estimated_bits, s_deviation, x_val;
712     /* UWORD8 u1_return_value = 1; */
713     UWORD32 i;
714     UWORD8 u1_num_frms_used, u1_frm_indx;
715 
716     number_t s_sad_h264;
717     number_t s_avg_mpeg2_qp;
718     number_t s_res_bits;
719     number_t temp;
720     number_t s_num_frms_used;
721 
722     u1_num_frms_used = 0;
723     /* fl_avg_deviation = 0; */
724     s_deviation.sm = 0;
725     s_deviation.e = 0;
726 
727     s_avg_deviation.sm = 0;
728     s_avg_deviation.e = 0;
729 
730     for(i = 0; i < u1_num_frms; i++)
731     {
732         LWORD64 i8_local_sad_sm;
733         WORD32 i4_local_e = 0;
734         if(-1 == pi1_frame_index[i])
735             continue;
736 
737         u1_frm_indx = (UWORD8)pi1_frame_index[i];
738 
739         u1_frm_indx = (UWORD8)i;
740         /*
741         x_val = pi4_sad_h264[u1_frm_indx] /
742                 (float) pui_avg_mpeg2_qp[u1_frm_indx];
743                 */
744         /* s_sad_h264.sm = pi8_sad_h264[u1_frm_indx];
745         s_sad_h264.e  = 0;*/
746         i8_local_sad_sm = pi8_sad_h264[u1_frm_indx];
747         while(i8_local_sad_sm > 0x7FFFFFFF)
748         {
749             i8_local_sad_sm = i8_local_sad_sm / 2;
750             i4_local_e++;
751         }
752         SET_VARQ_FRM_FIXQ(((WORD32)i8_local_sad_sm), s_sad_h264, -i4_local_e);
753         /*fract_quant*/
754         SET_VARQ_FRM_FIXQ(pi4_avg_mpeg2_qp_q6[u1_frm_indx], s_avg_mpeg2_qp, QSCALE_Q_FAC);
755 
756         div32_var_q(s_sad_h264, s_avg_mpeg2_qp, &x_val);
757 
758         /*fl_estimated_bits = (pmc_model_coeff[1] * x_val) +
759                             (pmc_model_coeff[2]); */
760         mult32_var_q(x_val, ps_model_coeff[1], &s_estimated_bits);
761         add32_var_q(s_estimated_bits, ps_model_coeff[2], &s_estimated_bits);
762 
763         /*fl_deviation        = fabs(pi4_res_bits[u1_frm_indx] - fl_estimated_bits) /
764                               (float) pi4_res_bits[u1_frm_indx]; */
765         s_res_bits.sm = pi4_res_bits[u1_frm_indx];
766         s_res_bits.e = 0;
767         sub32_var_q(s_res_bits, s_estimated_bits, &temp);
768         temp.sm = (temp.sm > 0) ? temp.sm : (-temp.sm);
769         div32_var_q(temp, s_res_bits, &s_deviation);
770 
771         /* fl_deviation        = fl_deviation * fl_deviation; */
772         mult32_var_q(s_deviation, s_deviation, &s_deviation);
773 
774         /* fl_avg_deviation    += fl_deviation; */
775         add32_var_q(s_avg_deviation, s_deviation, &s_avg_deviation);
776 
777         u1_num_frms_used++;
778     }
779 
780     /* fl_avg_deviation /= u1_num_frms_used; */
781     s_num_frms_used.sm = u1_num_frms_used;
782     s_num_frms_used.e = 0;
783     div32_var_q(s_avg_deviation, s_num_frms_used, &s_avg_deviation);
784     *ps_avg_deviation = s_avg_deviation;
785 }
786 /* end of "TO DO : FLOAT_TO_FIX" */
787 /******************************************************************************
788   Function Name   : is_qp_available
789   Description     :
790   Arguments       : ps_rd_model
791   Return Values   : void
792   Revision History:
793                     Creation
794 *****************************************************************************/
is_qp_available(rc_rd_model_t * ps_rd_model,UWORD8 u1_curr_frame_index,WORD32 i4_num_frames_to_check)795 static WORD32 is_qp_available(
796     rc_rd_model_t *ps_rd_model, UWORD8 u1_curr_frame_index, WORD32 i4_num_frames_to_check)
797 {
798     WORD32 i;
799     /*fract_quant*/
800     WORD32 i4_qp = ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index];
801     WORD32 i4_num_frms = 0;
802 
803     for(i = 0; i < i4_num_frames_to_check; i++)
804     {
805         u1_curr_frame_index++;
806         if(ps_rd_model->u1_max_frms_to_model == u1_curr_frame_index)
807             u1_curr_frame_index = 0;
808         /*fract_quant*/
809         if(ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index] == i4_qp)
810             i4_num_frms++;
811     }
812     if(i4_num_frms >= 2)
813         return (1);
814     else
815         return (0);
816 }
817 /****************************************************************************/
818 /*                                                                          */
819 /*  Function Name : example_of_a_function                                   */
820 /*                                                                          */
821 /*  Description   : This function illustrates the use of C coding standards.*/
822 /*                  switch/case, if, for, block comments have been shown    */
823 /*                  here.                                                   */
824 /*  Inputs        : <What inputs does the function take?>                   */
825 /*  Globals       : <Does it use any global variables?>                     */
826 /*  Processing    : <Describe how the function operates - include algorithm */
827 /*                  description>                                            */
828 /*  Outputs       : <What does the function produce?>                       */
829 /*  Returns       : <What does the function return?>                        */
830 /*                                                                          */
831 /*  Issues        : <List any issues or problems with this function>        */
832 /*                                                                          */
833 /*  Revision History:                                                       */
834 /*                                                                          */
835 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made) */
836 /*         13 07 2002   Ittiam          Draft                               */
837 /*                                                                          */
838 /****************************************************************************/
update_frame_rd_model(rc_rd_model_t * ps_rd_model)839 static void update_frame_rd_model(rc_rd_model_t *ps_rd_model)
840 {
841     WORD8 pi1_frame_index[MAX_FRAMES_MODELLED];
842     WORD8 pi1_frame_index_initial[MAX_FRAMES_MODELLED];
843     UWORD32 u4_num_skips;
844 
845     UWORD8 u1_num_skips_temp;
846     /*UWORD8  u1_avg_mpeg2_qp_temp, u1_min_mpeg2_qp, u1_max_mpeg2_qp; */
847     /*WORD32  i4_avg_mpeg2_qp_temp, i4_min_mpeg2_qp, i4_max_mpeg2_qp;*/
848     WORD32 i4_avg_mpeg2_qp_temp_q6, i4_min_mpeg2_qp_q6, i4_max_mpeg2_qp_q6;
849     UWORD8 u1_num_frms_input, u1_num_active_frames, u1_reject_frame;
850 
851     /* UWORD8  u1_min2_mpeg2_qp, u1_max2_mpeg2_qp; */
852     /* WORD32  i4_min2_mpeg2_qp, i4_max2_mpeg2_qp;*/
853     WORD32 i4_min2_mpeg2_qp_q6, i4_max2_mpeg2_qp_q6;
854     UWORD8 u1_min_qp_frame_indx, u1_max_qp_frame_indx;
855 
856     number_t model_coeff_array[3], model_coeff_array_lin[3];
857     number_t model_coeff_array_lin_wo_int[3];
858     WORD32 i;
859     UWORD8 u1_curr_frame_index;
860 
861 #if RC_MODEL_USED_BUG_FIX
862     UWORD8 u1_lin_model_valid;
863 #endif
864 
865     number_t s_quad_avg_sqr_dev, s_lin_avg_sqr_dev;
866 
867     UWORD8 u1_check_model;
868 
869     model_coeff_array[0].sm = 0;
870     model_coeff_array[0].e = 0;
871     model_coeff_array[1].sm = 0;
872     model_coeff_array[1].e = 0;
873     model_coeff_array[2].sm = 0;
874     model_coeff_array[2].e = 0;
875 
876     model_coeff_array_lin[0].sm = 0;
877     model_coeff_array_lin[0].e = 0;
878     model_coeff_array_lin[1].sm = 0;
879     model_coeff_array_lin[1].e = 0;
880     model_coeff_array_lin[2].sm = 0;
881     model_coeff_array_lin[2].e = 0;
882 
883     model_coeff_array_lin_wo_int[0].sm = 0;
884     model_coeff_array_lin_wo_int[0].e = 0;
885     model_coeff_array_lin_wo_int[1].sm = 0;
886     model_coeff_array_lin_wo_int[1].e = 0;
887     model_coeff_array_lin_wo_int[2].sm = 0;
888     model_coeff_array_lin_wo_int[2].e = 0;
889 
890     /* ps_rd_model += u1_pic_type; */
891 
892     u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter;
893 
894     ps_rd_model->u1_model_used = QUAD_MODEL;
895 
896     if(0 == u1_curr_frame_index)
897         u1_curr_frame_index = (UWORD8)(ps_rd_model->u1_max_frms_to_model - 1);
898     else
899         u1_curr_frame_index--;
900 
901     /************************************************************************/
902     /* Rearrange data to be fed into a Linear Regression Module             */
903     /* Module finds a,b,c such that                                         */
904     /*      y = ax + bx^2 + c                                               */
905     /************************************************************************/
906     u4_num_skips = 0;
907     u1_num_frms_input = 0;
908     /*memset(ps_rd_model->au1_num_frames,   0, MPEG2_QP_ELEM);*/
909     memset(pi1_frame_index, -1, MAX_FRAMES_MODELLED);
910     /*i4_min_mpeg2_qp = MAX_MPEG2_QP;
911     i4_max_mpeg2_qp = 0;*/
912 
913     i4_min_mpeg2_qp_q6 = (MAX_MPEG2_QP << QSCALE_Q_FAC);
914     i4_max_mpeg2_qp_q6 = MIN_QSCALE_Q6;
915 
916     u1_num_active_frames = ps_rd_model->u1_num_frms_in_model;
917     if(u1_num_active_frames > MAX_ACTIVE_FRAMES)
918         u1_num_active_frames = MAX_ACTIVE_FRAMES;
919 
920     /************************************************************************/
921     /* Choose the set of Points to be used for MSE fit of Quadratic model   */
922     /* Points chosen are spread across the Qp range. Max of 2 points are    */
923     /* chosen for a Qp.                                                     */
924     /************************************************************************/
925     for(i = 0; i < u1_num_active_frames; i++)
926     {
927         /* WORD32 i4_test1 = 0, i4_test2 = 0; NITT TBD */
928         u1_reject_frame = 0;
929         u1_num_skips_temp = ps_rd_model->pu1_num_skips[u1_curr_frame_index];
930         /*fract_quant*/
931         /*i4_avg_mpeg2_qp_temp = (ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index] >> QSCALE_Q_FAC);*/
932         i4_avg_mpeg2_qp_temp_q6 = ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index];
933 
934         if((0 == u4_num_skips) && (0 != u1_num_skips_temp))
935             u1_reject_frame = 1;
936         if((1 == u4_num_skips) && (u1_num_skips_temp > 1))
937             u1_reject_frame = 1;
938         /* If there is already a frame having same qp reject the current frame */
939         if(is_qp_available(ps_rd_model, u1_curr_frame_index, i))
940             u1_reject_frame = 1;
941         /*if (ps_rd_model->au1_num_frames[i4_avg_mpeg2_qp_temp]  >= 2)
942         {
943             u1_reject_frame = 1;
944             i4_test2 = 1;
945         }
946         if(i4_test2 != i4_test1)
947         {
948             printf("Why am I here??\n");
949         }*/
950 
951         if(0 == i)
952             u1_reject_frame = 0;
953 
954         if(0 == u1_reject_frame)
955         {
956             pi1_frame_index[u1_num_frms_input] = (WORD8)u1_curr_frame_index;
957             /* ps_rd_model->au1_num_frames[i4_avg_mpeg2_qp_temp] += 1; */
958 
959             /*if (i4_min_mpeg2_qp > i4_avg_mpeg2_qp_temp) i4_min_mpeg2_qp = i4_avg_mpeg2_qp_temp;
960             if (i4_max_mpeg2_qp < i4_avg_mpeg2_qp_temp) i4_max_mpeg2_qp = i4_avg_mpeg2_qp_temp;*/
961 
962             if(i4_min_mpeg2_qp_q6 > i4_avg_mpeg2_qp_temp_q6)
963                 i4_min_mpeg2_qp_q6 = i4_avg_mpeg2_qp_temp_q6;
964             if(i4_max_mpeg2_qp_q6 < i4_avg_mpeg2_qp_temp_q6)
965                 i4_max_mpeg2_qp_q6 = i4_avg_mpeg2_qp_temp_q6;
966             u1_num_frms_input++;
967         }
968 
969         if(0 == u1_curr_frame_index)
970             u1_curr_frame_index = (UWORD8)(ps_rd_model->u1_max_frms_to_model - 1);
971         else
972             u1_curr_frame_index--;
973     }
974 
975     /************************************************************************/
976     /* Add Pivot Points to the Data set to be used for finding Quadratic    */
977     /* Model Coeffs. These will help in constraining the shape of  Quadratic*/
978     /* to adapt too much to the Local deviations.                           */
979     /************************************************************************/
980     /*i4_min2_mpeg2_qp     = i4_min_mpeg2_qp;
981     i4_max2_mpeg2_qp     = i4_max_mpeg2_qp;*/
982 
983     i4_min2_mpeg2_qp_q6 = i4_min_mpeg2_qp_q6;
984     i4_max2_mpeg2_qp_q6 = i4_max_mpeg2_qp_q6;
985 
986     u1_min_qp_frame_indx = INVALID_FRAME_INDEX;
987     u1_max_qp_frame_indx = INVALID_FRAME_INDEX;
988 
989     /* Loop runnning over the Stored Frame Level Data
990        to find frames of MinQp and MaxQp */
991     for(; i < ps_rd_model->u1_num_frms_in_model; i++)
992     {
993         u1_num_skips_temp = ps_rd_model->pu1_num_skips[u1_curr_frame_index];
994         /*fract_quant*/
995         //i4_avg_mpeg2_qp_temp = ps_rd_model->ai4_avg_qp[u1_curr_frame_index];
996 
997         //i4_avg_mpeg2_qp_temp = (ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index] >> QSCALE_Q_FAC);
998 
999         i4_avg_mpeg2_qp_temp_q6 = ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index];
1000 
1001         if(((0 == u4_num_skips) && (0 != u1_num_skips_temp)) ||
1002            ((1 == u4_num_skips) && (u1_num_skips_temp > 1)))
1003             continue;
1004         /*
1005         if (i4_min2_mpeg2_qp > i4_avg_mpeg2_qp_temp)
1006         {
1007             i4_min2_mpeg2_qp     = i4_avg_mpeg2_qp_temp;
1008             u1_min_qp_frame_indx = u1_curr_frame_index;
1009         }
1010         if (i4_max2_mpeg2_qp < i4_avg_mpeg2_qp_temp)
1011         {
1012             i4_max2_mpeg2_qp     = i4_avg_mpeg2_qp_temp;
1013             u1_max_qp_frame_indx = u1_curr_frame_index;
1014         }
1015 */
1016 
1017         if(i4_min2_mpeg2_qp_q6 > i4_avg_mpeg2_qp_temp_q6)
1018         {
1019             i4_min2_mpeg2_qp_q6 = i4_avg_mpeg2_qp_temp_q6;
1020             u1_min_qp_frame_indx = u1_curr_frame_index;
1021         }
1022         if(i4_max2_mpeg2_qp_q6 < i4_avg_mpeg2_qp_temp_q6)
1023         {
1024             i4_max2_mpeg2_qp_q6 = i4_avg_mpeg2_qp_temp_q6;
1025             u1_max_qp_frame_indx = u1_curr_frame_index;
1026         }
1027 
1028         if(0 == u1_curr_frame_index)
1029             u1_curr_frame_index = (UWORD8)(ps_rd_model->u1_max_frms_to_model - 1);
1030         else
1031             u1_curr_frame_index--;
1032     }
1033 
1034     /* Add the Chosen Points to the regression data set */
1035     if(INVALID_FRAME_INDEX != u1_min_qp_frame_indx)
1036     {
1037         pi1_frame_index[u1_num_frms_input] = (WORD8)u1_min_qp_frame_indx;
1038         u1_num_frms_input++;
1039     }
1040     if(INVALID_FRAME_INDEX != u1_max_qp_frame_indx)
1041     {
1042         pi1_frame_index[u1_num_frms_input] = (WORD8)u1_max_qp_frame_indx;
1043         u1_num_frms_input++;
1044     }
1045 
1046     /* memcpy(pi1_frame_index_initial, pi1_frame_index, MAX_FRAMES_MODELLED); */
1047     {
1048         UWORD8 u1_k;
1049         for(u1_k = 0; u1_k < MAX_FRAMES_MODELLED; u1_k++)
1050         {
1051             pi1_frame_index_initial[u1_k] = pi1_frame_index[u1_k];
1052         }
1053     }
1054 
1055     if(QUAD_MODEL == ps_rd_model->u1_model_used)
1056     {
1057         if(u1_num_frms_input < (MIN_FRAMES_FOR_QUAD_MODEL))
1058             ps_rd_model->u1_model_used = LIN_MODEL;
1059         if((WORD32)i4_max_mpeg2_qp_q6 < ((WORD32)(21 * i4_min_mpeg2_qp_q6) >> 4))
1060             ps_rd_model->u1_model_used = LIN_MODEL;
1061     }
1062 
1063     if(LIN_MODEL == ps_rd_model->u1_model_used)
1064     {
1065         if(u1_num_frms_input < MIN_FRAMES_FOR_LIN_MODEL)
1066             ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1067         if((WORD32)i4_max_mpeg2_qp_q6 < ((WORD32)(19 * i4_min_mpeg2_qp_q6) >> 4))
1068             ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1069     }
1070 
1071     /***** Call the Module to Return the Coeffs for the Fed Data *****/
1072     ps_rd_model->u1_model_used = find_model_coeffs(
1073         ps_rd_model->pi4_res_bits,
1074         ps_rd_model->pi8_sad,
1075         ps_rd_model->ai4_avg_qp_q6,
1076         u1_num_frms_input,
1077         ps_rd_model->u1_model_used,
1078         pi1_frame_index,
1079         model_coeff_array,
1080         model_coeff_array_lin,
1081         model_coeff_array_lin_wo_int,
1082         ps_rd_model);
1083 
1084     if((model_coeff_array_lin[2].sm > 0) || (model_coeff_array_lin[0].sm < 0))
1085     {
1086 #if RC_MODEL_USED_BUG_FIX
1087         u1_lin_model_valid = 0;
1088 #endif
1089     }
1090     else
1091     {
1092 #if RC_MODEL_USED_BUG_FIX
1093         u1_lin_model_valid = 1;
1094 #endif
1095         /* lin deviation calculation */
1096         calc_avg_sqr_dev_for_model(
1097             ps_rd_model->pi4_res_bits,
1098             ps_rd_model->pi8_sad,
1099             ps_rd_model->ai4_avg_qp_q6,
1100             u1_num_frms_input,
1101             pi1_frame_index_initial,
1102             model_coeff_array_lin,
1103             &s_lin_avg_sqr_dev);
1104     }
1105 
1106     if(QUAD_MODEL == ps_rd_model->u1_model_used)
1107     {
1108         u1_check_model = refine_set_of_points(
1109             ps_rd_model->pi4_res_bits,
1110             ps_rd_model->pi8_sad,
1111             ps_rd_model->ai4_avg_qp_q6,
1112             u1_num_frms_input,
1113             pi1_frame_index,
1114             model_coeff_array,
1115             &s_quad_avg_sqr_dev);
1116 
1117         if(2 == u1_check_model)
1118         {
1119             ps_rd_model->u1_model_used = QUAD_MODEL;
1120         }
1121         else
1122         {
1123             /*******************************************************************/
1124             /* Make sure that some of the Pivot Points are used in the Refined */
1125             /* data set. 1. Previous Frame                                     */
1126             /*******************************************************************/
1127             /* pi1_frame_index[0] = ps_rd_model->u1_curr_frm_counter; */
1128 
1129             ps_rd_model->u1_model_used = find_model_coeffs(
1130                 ps_rd_model->pi4_res_bits,
1131                 ps_rd_model->pi8_sad,
1132                 ps_rd_model->ai4_avg_qp_q6,
1133                 u1_num_frms_input,
1134                 ps_rd_model->u1_model_used,
1135                 pi1_frame_index,
1136                 model_coeff_array,
1137                 NULL,
1138                 NULL,
1139                 ps_rd_model);
1140 
1141             u1_check_model = refine_set_of_points(
1142                 ps_rd_model->pi4_res_bits,
1143                 ps_rd_model->pi8_sad,
1144                 ps_rd_model->ai4_avg_qp_q6,
1145                 u1_num_frms_input,
1146                 pi1_frame_index,
1147                 model_coeff_array,
1148                 &s_quad_avg_sqr_dev);
1149 
1150             if((0 == u1_check_model))
1151             {
1152 #if RC_MODEL_USED_BUG_FIX
1153                 if((s_lin_avg_sqr_dev < s_quad_avg_sqr_dev) && (1 == u1_lin_model_valid))
1154 #endif
1155                     ps_rd_model->u1_model_used = LIN_MODEL;
1156             }
1157         }
1158     }
1159 
1160     if(QUAD_MODEL == ps_rd_model->u1_model_used)
1161     {
1162         /* min_res_bits = model_coeff_c -  */
1163         /*               ((model_coeff_a * model_coeff_a) / (4 * model_coeff_b)); */
1164 
1165         if(model_coeff_array[0].sm < 0)
1166             ps_rd_model->u1_model_used = LIN_MODEL;
1167 
1168         /* if ((model_coeff_a * model_coeff_b) > 0) */
1169         /*    u1_model_used = LIN_MODEL; */
1170 
1171         ps_rd_model->model_coeff_b_quad = model_coeff_array[0];
1172         ps_rd_model->model_coeff_a_quad = model_coeff_array[1];
1173         ps_rd_model->model_coeff_c_quad = model_coeff_array[2];
1174     }
1175     if(LIN_MODEL == ps_rd_model->u1_model_used)
1176     {
1177         if((model_coeff_array_lin[2].sm > 0) || (model_coeff_array_lin[0].sm < 0))
1178             ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1179     }
1180 /* TO DO : FLOAT_TO_FIX */
1181 #if RC_MODEL_USED_BUG_FIX
1182     {
1183         number_t s_quad_dev_thr;
1184         number_t s_lin_dev_thr;
1185         number_t s_diff;
1186 
1187         s_quad_dev_thr.sm = QUAD_DEV_THR_SM;
1188         s_quad_dev_thr.e = QUAD_DEV_THR_E;
1189 
1190         /* (s_quad_avg_sqr_dev > .25) */
1191         sub32_var_q(s_quad_avg_sqr_dev, s_quad_dev_thr, &s_diff);
1192 
1193         /* Another threshold of .25 on deviation i.e. deviation greater than 25%  */
1194         if((QUAD_MODEL == ps_rd_model->u1_model_used) && (s_diff.sm > 0))
1195             ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1196 
1197         s_lin_dev_thr.sm = LIN_DEV_THR_SM;
1198         s_lin_dev_thr.e = LIN_DEV_THR_E;
1199 
1200         /* (s_lin_avg_sqr_dev > .25) */
1201         sub32_var_q(s_lin_avg_sqr_dev, s_lin_dev_thr, &s_diff);
1202 
1203         if((LIN_MODEL == ps_rd_model->u1_model_used) && (s_diff.sm > 0))
1204             ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1205     }
1206 #endif /* #if RC_MODEL_USED_BUG_FIX */
1207     /* end of "TO DO : FLOAT_TO_FIX" */
1208     ps_rd_model->model_coeff_b_lin = model_coeff_array_lin[0];
1209     ps_rd_model->model_coeff_a_lin = model_coeff_array_lin[1];
1210     ps_rd_model->model_coeff_c_lin = model_coeff_array_lin[2];
1211     ps_rd_model->model_coeff_b_lin_wo_int = model_coeff_array_lin_wo_int[0];
1212     ps_rd_model->model_coeff_a_lin_wo_int = model_coeff_array_lin_wo_int[1];
1213     ps_rd_model->model_coeff_c_lin_wo_int = model_coeff_array_lin_wo_int[2];
1214     /* ps_rd_model->u1_model_used = PREV_FRAME_MODEL; */
1215 }
1216 #endif
1217 
1218 /******************************************************************************
1219   Function Name   : estimate_bits_for_qp
1220   Description     :
1221   Arguments       : ps_rd_model
1222   Return Values   : void
1223   Revision History:
1224                     Creation
1225 *****************************************************************************/
1226 UWORD32
estimate_bits_for_qp(rc_rd_model_t * ps_rd_model,UWORD32 u4_estimated_sad,WORD32 i4_avg_qp_q6)1227     estimate_bits_for_qp(rc_rd_model_t *ps_rd_model, UWORD32 u4_estimated_sad, WORD32 i4_avg_qp_q6)
1228 {
1229     /* float fl_num_bits; */
1230     number_t s_num_bits;
1231     number_t s_estimated_sad, s_avg_qp;
1232 
1233     /* number_t s_model_coeff_a, s_model_coeff_b, s_model_coeff_c; */
1234     WORD32 i4_temp;
1235     number_t x_val;
1236 
1237     /* ps_rd_model += u1_curr_pic_type; */
1238     s_estimated_sad.sm = u4_estimated_sad;
1239     s_estimated_sad.e = 0;
1240     /*fract_quant*/
1241     SET_VARQ_FRM_FIXQ(i4_avg_qp_q6, s_avg_qp, QSCALE_Q_FAC);
1242     /* initilising s_num_bits */
1243     s_num_bits.sm = 0;
1244     s_num_bits.e = 0;
1245 
1246     /*
1247     convert_float_to_fix(ps_rd_model->model_coeff_a, &s_model_coeff_a);
1248     convert_float_to_fix(ps_rd_model->model_coeff_b, &s_model_coeff_b);
1249     convert_float_to_fix(ps_rd_model->model_coeff_c, &s_model_coeff_c);
1250     */
1251     div32_var_q(s_estimated_sad, s_avg_qp, &x_val);
1252     {
1253         /* TO DO : FLOAT_TO_FIX */
1254         /* fl_num_bits = ps_rd_model->model_coeff_a_lin_wo_int * x_val; */
1255         mult32_var_q(ps_rd_model->model_coeff_a_lin_wo_int, x_val, &s_num_bits);
1256         /* end of "TO DO : FLOAT_TO_FIX" */
1257     }
1258 
1259     /* return ((UWORD32) fl_num_bits); */
1260     number_t_to_word32(s_num_bits, &i4_temp);
1261     if(i4_temp < 0)
1262         i4_temp = 0;
1263     return ((UWORD32)i4_temp);
1264 }
1265 
1266 /******************************************************************************
1267   Function Name   : find_qp_for_target_bits
1268   Description     :
1269   Arguments       : ps_rd_model
1270   Return Values   : void
1271   Revision History:
1272                     Creation
1273 *****************************************************************************/
find_qp_for_target_bits(rc_rd_model_handle ps_rd_model,UWORD32 u4_target_res_bits,UWORD32 u4_estimated_sad,WORD32 i4_max_qp_q6,WORD32 i4_min_qp_q6)1274 WORD32 find_qp_for_target_bits(
1275     rc_rd_model_handle ps_rd_model,
1276     UWORD32 u4_target_res_bits,
1277     UWORD32 u4_estimated_sad,
1278     WORD32 i4_max_qp_q6,
1279     WORD32 i4_min_qp_q6)
1280 {
1281     WORD32 i4_qp_q6;
1282     /* float  x_value, f_qp; */
1283     number_t x_value, s_qp;
1284     /* number_t s_model_coeff_a, s_model_coeff_b, s_model_coeff_c; */
1285     number_t s_target_res_bits;
1286     number_t s_estimated_sad;
1287     number_t temp, temp3;
1288     number_t temp2, temp1;
1289 
1290     /* ps_rd_model += u1_curr_pic_type; */
1291 
1292     s_target_res_bits.sm = u4_target_res_bits;
1293     s_target_res_bits.e = 0;
1294 
1295     s_estimated_sad.sm = u4_estimated_sad;
1296     s_estimated_sad.e = 0;
1297 
1298     /* initilising default value */
1299     x_value.sm = 0;
1300     x_value.e = 0;
1301 
1302     /*
1303     convert_float_to_fix(ps_rd_model->model_coeff_a, &(ps_rd_model->s_model_coeff_a));
1304     convert_float_to_fix(ps_rd_model->model_coeff_b, &(ps_rd_model->s_model_coeff_b));
1305     convert_float_to_fix(ps_rd_model->model_coeff_c, &(ps_rd_model->s_model_coeff_c));
1306     */
1307 
1308 #if ENABLE_QUAD_MODEL
1309     if(QUAD_MODEL == ps_rd_model->u1_model_used)
1310     {
1311         /* float det; */
1312         number_t det;
1313 
1314         /*
1315         det = (ps_rd_model->model_coeff_a * ps_rd_model->model_coeff_a) -
1316               (4 * (ps_rd_model->model_coeff_b) *
1317                (ps_rd_model->model_coeff_c - u4_target_res_bits));
1318         */
1319         mult32_var_q(ps_rd_model->model_coeff_a_quad, ps_rd_model->model_coeff_a_quad, &temp);
1320         temp3.sm = 4;
1321         temp3.e = 0;
1322         mult32_var_q(temp3, ps_rd_model->model_coeff_b_quad, &temp1);
1323         sub32_var_q(ps_rd_model->model_coeff_c_quad, s_target_res_bits, &temp2);
1324         mult32_var_q(temp1, temp2, &temp1);
1325         sub32_var_q(temp, temp1, &det);
1326 
1327         /* x_value = sqrt(det); */
1328         sqrt32_var_q(det, &x_value);
1329 
1330         /* x_value = (x_value - ps_rd_model->model_coeff_a) /
1331             (2 * ps_rd_model->model_coeff_b);
1332         */
1333         sub32_var_q(x_value, ps_rd_model->model_coeff_a_quad, &temp);
1334         temp3.sm = 2;
1335         temp3.e = 0;
1336         mult32_var_q(temp3, ps_rd_model->model_coeff_b_quad, &temp1);
1337         div32_var_q(temp, temp1, &x_value);
1338 
1339         if(det.sm < 0 || x_value.sm < 0)
1340         {
1341             /* x_value = 0; */
1342             ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1343         }
1344     }
1345 
1346     if(LIN_MODEL == ps_rd_model->u1_model_used)
1347     {
1348         /*
1349         x_value = ((float)u4_target_res_bits - ps_rd_model->model_coeff_c) /
1350                    (ps_rd_model->model_coeff_b);
1351         */
1352         sub32_var_q(s_target_res_bits, ps_rd_model->model_coeff_c_lin, &temp);
1353         div32_var_q(temp, ps_rd_model->model_coeff_b_lin, &x_value);
1354         if(x_value.sm < 0)
1355         {
1356             /* x_value = 0; */
1357             ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1358         }
1359     }
1360 #else
1361     ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1362 #endif
1363     if(PREV_FRAME_MODEL == ps_rd_model->u1_model_used)
1364     {
1365         /* TO DO : FLOAT_TO_FIX */
1366         /* x_value = (float) u4_target_res_bits / ps_rd_model->model_coeff_a_lin_wo_int; */
1367         div32_var_q(s_target_res_bits, ps_rd_model->model_coeff_a_lin_wo_int, &x_value);
1368         /* end of "TO DO : FLOAT_TO_FIX" */
1369     }
1370 
1371     if(0 != x_value.sm)
1372     {
1373         /* f_qp = u4_estimated_sad / x_value; */
1374         div32_var_q(s_estimated_sad, x_value, &s_qp);
1375     }
1376     else
1377     {
1378         s_qp.sm = MAX_MPEG2_QP;
1379         s_qp.e = 0;
1380     }
1381 
1382     /*
1383     if (f_qp > MAX_MPEG2_QP)
1384     f_qp = MAX_MPEG2_QP;
1385     */
1386     temp3.sm = MAX_MPEG2_QP;
1387     temp3.e = 0;
1388     sub32_var_q(s_qp, temp3, &temp);
1389     if(temp.sm > 0)
1390     {
1391         s_qp = temp3;
1392     }
1393     convert_varq_to_fixq(s_qp, &i4_qp_q6, (WORD32)QSCALE_Q_FAC);
1394     /* Truncating the QP to the Max and Min Qp values possible */
1395     if(i4_qp_q6 < i4_min_qp_q6)
1396     {
1397         i4_qp_q6 = i4_min_qp_q6;
1398     }
1399     if(i4_qp_q6 > i4_max_qp_q6)
1400     {
1401         i4_qp_q6 = i4_max_qp_q6;
1402     }
1403     return (i4_qp_q6);
1404 }
1405 /******************************************************************************
1406   Function Name   : add_frame_to_rd_model
1407   Description     :
1408   Arguments       : ps_rd_model
1409   Return Values   : void
1410   Revision History:
1411                     Creation
1412 *****************************************************************************/
add_frame_to_rd_model(rc_rd_model_t * ps_rd_model,UWORD32 i4_res_bits,WORD32 i4_avg_mp2qp_q6,LWORD64 i8_sad_h264,UWORD8 u1_num_skips)1413 void add_frame_to_rd_model(
1414     rc_rd_model_t *ps_rd_model,
1415     UWORD32 i4_res_bits,
1416     WORD32 i4_avg_mp2qp_q6,
1417     LWORD64 i8_sad_h264,
1418     UWORD8 u1_num_skips)
1419 {
1420     UWORD8 u1_curr_frame_index, i4_same_bit_count = 0;
1421     /* ps_rd_model += u1_curr_pic_type; */
1422     u1_curr_frame_index = ps_rd_model->u1_curr_frm_counter;
1423 
1424     {
1425         WORD32 i;
1426 
1427         i = ps_rd_model->u1_num_frms_in_model - 1;
1428         while(i >= 0)
1429         {
1430             if(ps_rd_model->pi4_res_bits[i] == i4_res_bits)
1431                 i4_same_bit_count++;
1432             i--;
1433         }
1434     }
1435     /* - the condition check is a temporary fix to avoid feeding zero into model.
1436     The change should be done so that 0 is not at all fed into model. When texture bit consumption becomes zero next frame qp should be explicitly decreased so that finite amount of texture
1437     bits is consumed and feeds valid data to model to come out of deadlock*/
1438 
1439     if(i4_same_bit_count < 3)
1440     {
1441         /*** Insert the Present Frame Data into the RD Model State Memory ***/
1442         ps_rd_model->pi4_res_bits[u1_curr_frame_index] = i4_res_bits;
1443         ps_rd_model->pi8_sad[u1_curr_frame_index] = i8_sad_h264;
1444         ps_rd_model->pu1_num_skips[u1_curr_frame_index] = u1_num_skips;
1445         ps_rd_model->ai4_avg_qp[u1_curr_frame_index] = (i4_avg_mp2qp_q6 >> QSCALE_Q_FAC);
1446         ps_rd_model->ai4_avg_qp_q6[u1_curr_frame_index] = i4_avg_mp2qp_q6;
1447 
1448         ps_rd_model->u1_curr_frm_counter++;
1449         if(ps_rd_model->u1_max_frms_to_model == ps_rd_model->u1_curr_frm_counter)
1450             ps_rd_model->u1_curr_frm_counter = 0;
1451 
1452         if(ps_rd_model->u1_num_frms_in_model < ps_rd_model->u1_max_frms_to_model)
1453         {
1454             ps_rd_model->u1_num_frms_in_model++;
1455         }
1456         update_frame_rd_model(ps_rd_model);
1457     }
1458 }
1459 /******************************************************************************
1460   Function Name   : get_linear_coefficient
1461   Description     :
1462   Arguments       : ps_rd_model
1463   Return Values   : void
1464   Revision History:
1465                     Creation
1466 *****************************************************************************/
get_linear_coefficient(rc_rd_model_t * ps_rd_model)1467 number_t get_linear_coefficient(rc_rd_model_t *ps_rd_model)
1468 {
1469     return (ps_rd_model->model_coeff_a_lin_wo_int);
1470 }
1471 /******************************************************************************
1472   Function Name   : set_linear_coefficient
1473   Description     :
1474   Arguments       : ps_rd_model
1475   Return Values   : void
1476   Revision History:
1477                     Creation
1478 *****************************************************************************/
set_linear_coefficient(rc_rd_model_t * ps_rd_model,number_t model_coeff_a_lin_wo_int)1479 void set_linear_coefficient(rc_rd_model_t *ps_rd_model, number_t model_coeff_a_lin_wo_int)
1480 {
1481     ps_rd_model->model_coeff_a_lin_wo_int = model_coeff_a_lin_wo_int;
1482     ps_rd_model->u1_model_used = PREV_FRAME_MODEL;
1483 }
1484 /******************************************************************************
1485   Function Name   : is_model_valid
1486   Description     :
1487   Arguments       : ps_rd_model
1488   Return Values   : void
1489   Revision History:
1490                     Creation
1491 *****************************************************************************/
is_model_valid(rc_rd_model_t * ps_rd_model)1492 WORD32 is_model_valid(rc_rd_model_t *ps_rd_model)
1493 {
1494     /*return 1 if atleast one data point is availbale: this is required because frames with zero texture consumption is not updated in model*/
1495     if(ps_rd_model->u1_num_frms_in_model > 0)
1496     {
1497         return 1;
1498     }
1499     else
1500     {
1501         return 0;
1502     }
1503 }
1504 
1505 #endif /* #if RC_FIXED_POINT */
1506