blob: 62c78115241cf8dcd5ecdb7d14b6d8ef4d222bb7 [file] [log] [blame]
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301/******************************************************************************
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
53WORD32 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;
Martin Storsjo73136022015-06-23 14:51:06 +030058 rc_rd_model_t s_rc_rd_model_temp;
Hamsalekha S8d3d3032015-03-13 21:24:58 +053059
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
79void 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
92void 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
102static 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
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530118 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
Martin Storsjocc872412015-06-13 00:35:01 +0300129#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
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530135 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
196static 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
349UWORD32 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
361UWORD8 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
396void 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
456WORD32 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
561model_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