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 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; 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 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 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 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 567