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 est_sad.c 23 * 24 * \brief 25 * This file contain sad estimation related functions 26 * 27 * \date 28 * 29 * \author 30 * ittiam 31 * 32 ****************************************************************************** 33 */ 34 /*****************************************************************************/ 35 /* File Includes */ 36 /*****************************************************************************/ 37 /* User include files */ 38 #include "ittiam_datatypes.h" 39 #include "rc_common.h" 40 #include "rc_cntrl_param.h" 41 #include "var_q_operator.h" 42 #include "mem_req_and_acq.h" 43 #include "est_sad.h" 44 45 typedef struct est_sad_t 46 { 47 WORD32 i4_use_est_intra_sad; 48 UWORD32 au4_prev_frm_sad[MAX_PIC_TYPE]; /* Previous frame SAD */ 49 UWORD32 u4_n_p_frm_ifi_avg_sad; /* Current (nth) ifi average P frame SAD */ 50 UWORD32 u4_n_1_p_frm_ifi_avg_sad; /* (n-1)th ifi average P frame SAD */ 51 UWORD32 u4_n_2_p_frm_ifi_avg_sad; /* (n-2)th ifi average P frame SAD */ 52 WORD32 i4_num_ifi_encoded; /* number of ifi encoded till now */ 53 WORD32 i4_num_p_frm_in_cur_ifi; /* number of P frames in the current IFI */ 54 } est_sad_t; 55 56 #if NON_STEADSTATE_CODE 57 WORD32 est_sad_num_fill_use_free_memtab( 58 est_sad_t **pps_est_sad, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type) 59 { 60 WORD32 i4_mem_tab_idx = 0; 61 static est_sad_t s_est_sad; 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_est_sad) = &s_est_sad; 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(est_sad_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR); 73 use_or_fill_base(&ps_memtab[0], (void **)pps_est_sad, e_func_type); 74 } 75 i4_mem_tab_idx++; 76 77 return (i4_mem_tab_idx); 78 } 79 #endif /* #if NON_STEADSTATE_CODE */ 80 /**************************************************************************** 81 Function Name : init_est_sad 82 Description : 83 Inputs : ps_est_sad 84 i4_use_est_intra_sad 85 86 Revision History: 87 DD MM YYYY Author(s) Changes (Describe the changes made) 88 *****************************************************************************/ 89 void init_est_sad(est_sad_t *ps_est_sad, WORD32 i4_use_est_intra_sad) 90 { 91 WORD32 i; 92 ps_est_sad->i4_use_est_intra_sad = i4_use_est_intra_sad; 93 94 for(i = 0; i < MAX_PIC_TYPE; i++) 95 ps_est_sad->au4_prev_frm_sad[i] = 0; 96 97 ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; 98 ps_est_sad->u4_n_1_p_frm_ifi_avg_sad = 0; 99 ps_est_sad->u4_n_2_p_frm_ifi_avg_sad = 0; 100 ps_est_sad->i4_num_ifi_encoded = 0; 101 ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; 102 } 103 /**************************************************************************** 104 Function Name : reset_est_sad 105 Description : 106 Inputs : ps_est_sad 107 108 Revision History: 109 DD MM YYYY Author(s) Changes (Describe the changes made) 110 *****************************************************************************/ 111 void reset_est_sad(est_sad_t *ps_est_sad) 112 { 113 init_est_sad(ps_est_sad, ps_est_sad->i4_use_est_intra_sad); 114 } 115 116 /**************************************************************************** 117 Function Name : get_est_sad 118 Description : 119 Inputs : ps_est_sad 120 121 Revision History: 122 DD MM YYYY Author(s) Changes (Describe the changes made) 123 *****************************************************************************/ 124 /* 125 Get estimated SAD can be called at any point. The various use cases are: 126 1) When a I frame is getting encoded, 127 - get the estimated of P => No issues since we use the last coded P frame value 128 - get estimated of I => This call for two cases: 129 => a) if num_ifi_encoded is less than 2 130 then return the previous encoded I frame sad 131 => b) if num_ifi_encoded is more than 2, then we scale 132 the prev I sad by the ratio of (n-1) ifi P to n-2 ifi P 133 2) When P frame is getting encoded, 134 - get the estimated of P => No issues since we use the last coded P frame value 135 - get the estimated of I => Simillar to I we have two cases. To handle the b) case 136 extra logic had to introduced using 137 u1_is_n_1_p_frm_ifi_avg_sad_usable flag 138 */ 139 UWORD32 get_est_sad(est_sad_t *ps_est_sad, picture_type_e e_pic_type) 140 { 141 if(ps_est_sad->i4_use_est_intra_sad) 142 { 143 UWORD32 u4_estimated_sad; 144 if(e_pic_type == P_PIC) 145 { 146 u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[P_PIC]; 147 } 148 else if(e_pic_type == B_PIC) 149 { 150 u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[B_PIC]; 151 } 152 else 153 { 154 if(ps_est_sad->i4_num_ifi_encoded < 2) 155 { 156 /* Only one IFI has been encoded and so use the previous I frames SAD */ 157 u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; 158 } 159 else 160 { 161 /* Since the n-1 'P' frame IFI would have just accumulated the frame sads 162 we average it out here */ 163 UWORD32 u4_n_1_p_frm_ifi_avg_sad, u4_n_2_p_frm_ifi_avg_sad; 164 number_t vq_n_1_p_frm_ifi_avg_sad, vq_n_2_p_frm_ifi_avg_sad; 165 number_t vq_prev_frm_sad_i; 166 /* If there are frames in the current IFI start using it to estimate the I frame SAD */ 167 if(ps_est_sad->i4_num_p_frm_in_cur_ifi) 168 { 169 u4_n_1_p_frm_ifi_avg_sad = 170 (ps_est_sad->u4_n_p_frm_ifi_avg_sad / ps_est_sad->i4_num_p_frm_in_cur_ifi); 171 u4_n_2_p_frm_ifi_avg_sad = ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; 172 } 173 else 174 { 175 u4_n_1_p_frm_ifi_avg_sad = ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; 176 u4_n_2_p_frm_ifi_avg_sad = ps_est_sad->u4_n_2_p_frm_ifi_avg_sad; 177 } 178 /* If any of the previous p frame SADs are zeros we just return the previous 179 I frame SAD */ 180 if(u4_n_1_p_frm_ifi_avg_sad && u4_n_2_p_frm_ifi_avg_sad) 181 { 182 SET_VAR_Q(vq_prev_frm_sad_i, ps_est_sad->au4_prev_frm_sad[I_PIC], 0); 183 SET_VAR_Q(vq_n_1_p_frm_ifi_avg_sad, u4_n_1_p_frm_ifi_avg_sad, 0); 184 SET_VAR_Q(vq_n_2_p_frm_ifi_avg_sad, u4_n_2_p_frm_ifi_avg_sad, 0); 185 /************************************************************************** 186 Estimated SAD = 187 (n-1)th intra frame interval(ifi) P frame Avg SAD * 188 (prev I frame SAD / (n-2)nd intra frame interval(ifi) P frame Avg SAD) 189 **************************************************************************/ 190 mult32_var_q(vq_prev_frm_sad_i, vq_n_1_p_frm_ifi_avg_sad, &vq_prev_frm_sad_i); 191 div32_var_q(vq_prev_frm_sad_i, vq_n_2_p_frm_ifi_avg_sad, &vq_prev_frm_sad_i); 192 number_t_to_word32(vq_prev_frm_sad_i, (WORD32 *)&u4_estimated_sad); 193 } 194 else 195 { 196 u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; 197 } 198 } 199 } 200 return u4_estimated_sad; 201 } 202 else 203 { 204 return ps_est_sad->au4_prev_frm_sad[e_pic_type]; 205 } 206 } 207 /**************************************************************************** 208 Function Name : update_ppic_sad 209 Description : 210 Inputs : ps_est_sad 211 212 Revision History: 213 DD MM YYYY Author(s) Changes (Describe the changes made) 214 *****************************************************************************/ 215 WORD32 update_ppic_sad(est_sad_t *ps_est_sad, WORD32 i4_est_sad, WORD32 i4_prev_p_sad) 216 { 217 i4_est_sad = ((ps_est_sad->au4_prev_frm_sad[P_PIC]) * ((i4_est_sad << 4) / i4_prev_p_sad)) >> 4; 218 /* printf("i4_est_sad=%d prev_psad=%d\n",i4_est_sad,ps_est_sad->au4_prev_frm_sad[P_PIC]); */ 219 if(i4_est_sad > (WORD32)ps_est_sad->au4_prev_frm_sad[P_PIC]) 220 { 221 if(4 * i4_est_sad > 5 * i4_prev_p_sad) 222 i4_est_sad = (5 * i4_prev_p_sad) >> 2; 223 ps_est_sad->au4_prev_frm_sad[P_PIC] = i4_est_sad; 224 return 0; 225 } 226 return 1; 227 } 228 /**************************************************************************** 229 Function Name : update_actual_sad 230 Description : 231 Inputs : ps_est_sad 232 233 Revision History: 234 DD MM YYYY Author(s) Changes (Describe the changes made) 235 *****************************************************************************/ 236 void update_actual_sad(est_sad_t *ps_est_sad, UWORD32 u4_actual_sad, picture_type_e e_pic_type) 237 { 238 ps_est_sad->au4_prev_frm_sad[e_pic_type] = u4_actual_sad; 239 240 if(ps_est_sad->i4_use_est_intra_sad) 241 { 242 if(e_pic_type == I_PIC) 243 { 244 /* The requirement is to have two IFI before estimating I frame SAD */ 245 if(ps_est_sad->i4_num_ifi_encoded < 2) 246 ps_est_sad->i4_num_ifi_encoded++; 247 248 /* Calculate the average SAD */ 249 if(ps_est_sad->i4_num_p_frm_in_cur_ifi) 250 { 251 ps_est_sad->u4_n_p_frm_ifi_avg_sad /= ps_est_sad->i4_num_p_frm_in_cur_ifi; 252 } 253 else 254 { 255 ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; 256 } 257 /* Push the (n-1)th average SAD to the (n-2)th average SAD */ 258 ps_est_sad->u4_n_2_p_frm_ifi_avg_sad = ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; 259 /* Push the nth average SAD to the (n-1)th average SAD */ 260 ps_est_sad->u4_n_1_p_frm_ifi_avg_sad = ps_est_sad->u4_n_p_frm_ifi_avg_sad; 261 /* Reset SAD and number of P frames */ 262 ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; 263 ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; 264 } 265 else 266 { 267 ps_est_sad->u4_n_p_frm_ifi_avg_sad += u4_actual_sad; 268 ps_est_sad->i4_num_p_frm_in_cur_ifi++; 269 } 270 } 271 } 272 /**************************************************************************** 273 Function Name : update_prev_frame_intra_sad 274 Description : 275 Inputs : ps_est_sad 276 277 Revision History: 278 DD MM YYYY Author(s) Changes (Describe the changes made) 279 *****************************************************************************/ 280 void update_prev_frame_intra_sad(est_sad_t *ps_est_sad, WORD32 i4_intra_frm_sad) 281 { 282 ps_est_sad->au4_prev_frm_sad[I_PIC] = i4_intra_frm_sad; 283 } 284 /**************************************************************************** 285 Function Name : get_prev_frame_intra_sad 286 Description : 287 Inputs : ps_est_sad 288 289 Revision History: 290 DD MM YYYY Author(s) Changes (Describe the changes made) 291 *****************************************************************************/ 292 WORD32 get_prev_frame_intra_sad(est_sad_t *ps_est_sad) 293 { 294 return ps_est_sad->au4_prev_frm_sad[I_PIC]; 295 } 296 /**************************************************************************** 297 Function Name : update_prev_frame_sad 298 Description : 299 Inputs : ps_est_sad 300 301 Revision History: 302 DD MM YYYY Author(s) Changes (Describe the changes made) 303 *****************************************************************************/ 304 void update_prev_frame_sad(est_sad_t *ps_est_sad, WORD32 i4_frm_sad, picture_type_e e_pic_type) 305 { 306 ps_est_sad->au4_prev_frm_sad[e_pic_type] = i4_frm_sad; 307 } 308 /**************************************************************************** 309 Function Name : get_prev_frame_sad 310 Description : 311 Inputs : ps_est_sad 312 313 Revision History: 314 DD MM YYYY Author(s) Changes (Describe the changes made) 315 *****************************************************************************/ 316 WORD32 get_prev_frame_sad(est_sad_t *ps_est_sad, picture_type_e e_pic_type) 317 { 318 return ps_est_sad->au4_prev_frm_sad[e_pic_type]; 319 } 320