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