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