Hamsalekha S | 8d3d303 | 2015-03-13 21:24:58 +0530 | [diff] [blame] | 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 | /* Includes */ |
| 23 | /*****************************************************************************/ |
| 24 | |
| 25 | /* User include files */ |
| 26 | #include "irc_datatypes.h" |
| 27 | #include "irc_cntrl_param.h" |
| 28 | #include "irc_mem_req_and_acq.h" |
| 29 | #include "irc_est_sad.h" |
| 30 | #include "irc_common.h" |
| 31 | |
| 32 | typedef struct est_sad_t |
| 33 | { |
| 34 | WORD32 i4_use_est_intra_sad; |
| 35 | |
| 36 | /* Previous frame SAD */ |
| 37 | UWORD32 au4_prev_frm_sad[MAX_PIC_TYPE]; |
| 38 | |
| 39 | /* Current (nth) ifi average P frame SAD */ |
| 40 | UWORD32 u4_n_p_frm_ifi_avg_sad; |
| 41 | |
| 42 | /* (n-1)th ifi average P frame SAD */ |
| 43 | UWORD32 u4_n_1_p_frm_ifi_avg_sad; |
| 44 | |
| 45 | /* (n-2)th ifi average P frame SAD */ |
| 46 | UWORD32 u4_n_2_p_frm_ifi_avg_sad; |
| 47 | |
| 48 | /* number of ifi encoded till now */ |
| 49 | WORD32 i4_num_ifi_encoded; |
| 50 | |
| 51 | /* number of P frames in the current IFI */ |
| 52 | WORD32 i4_num_p_frm_in_cur_ifi; |
| 53 | |
| 54 | } est_sad_t; |
| 55 | |
| 56 | WORD32 irc_est_sad_num_fill_use_free_memtab(est_sad_t **pps_est_sad, |
| 57 | itt_memtab_t *ps_memtab, |
| 58 | ITT_FUNC_TYPE_E e_func_type) |
| 59 | { |
| 60 | WORD32 i4_mem_tab_idx = 0; |
Martin Storsjo | 7313602 | 2015-06-23 14:51:06 +0300 | [diff] [blame] | 61 | est_sad_t s_est_sad; |
Hamsalekha S | 8d3d303 | 2015-03-13 21:24:58 +0530 | [diff] [blame] | 62 | |
| 63 | /* Hack for al alloc, during which we don't have any state memory. |
| 64 | * Dereferencing can cause issues |
| 65 | */ |
| 66 | if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) |
| 67 | (*pps_est_sad) = &s_est_sad; |
| 68 | |
| 69 | /* For src rate control state structure */ |
| 70 | if(e_func_type != GET_NUM_MEMTAB) |
| 71 | { |
| 72 | fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(est_sad_t), |
| 73 | ALIGN_128_BYTE, PERSISTENT, DDR); |
| 74 | use_or_fill_base(&ps_memtab[0], (void**)pps_est_sad, e_func_type); |
| 75 | } |
| 76 | i4_mem_tab_idx++; |
| 77 | |
| 78 | return (i4_mem_tab_idx); |
| 79 | } |
| 80 | |
| 81 | void irc_init_est_sad(est_sad_t *ps_est_sad, WORD32 i4_use_est_intra_sad) |
| 82 | { |
| 83 | WORD32 i; |
| 84 | ps_est_sad->i4_use_est_intra_sad = i4_use_est_intra_sad; |
| 85 | |
| 86 | for(i = 0; i < MAX_PIC_TYPE; i++) |
| 87 | { |
| 88 | ps_est_sad->au4_prev_frm_sad[i] = 0; |
| 89 | } |
| 90 | |
| 91 | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
| 92 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad = 0; |
| 93 | ps_est_sad->u4_n_2_p_frm_ifi_avg_sad = 0; |
| 94 | ps_est_sad->i4_num_ifi_encoded = 0; |
| 95 | ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; |
| 96 | } |
| 97 | |
| 98 | void irc_reset_est_sad(est_sad_t *ps_est_sad) |
| 99 | { |
| 100 | irc_init_est_sad(ps_est_sad, ps_est_sad->i4_use_est_intra_sad); |
| 101 | } |
| 102 | |
| 103 | /* |
| 104 | * Get estimated SAD can be called at any point. The various use cases are: |
| 105 | * 1) When a I frame is getting encoded, |
| 106 | * - get the estimated of P => No issues since we use the last coded P frame |
| 107 | * value |
| 108 | * - get estimated of I => This call for two cases: |
| 109 | * => a) if num_ifi_encoded is less than 2 |
| 110 | * then return the previous encoded I frame sad |
| 111 | * => b) if num_ifi_encoded is more than 2, then we scale |
| 112 | * the prev I sad by the ratio of (n-1) ifi P to n-2 ifi P |
| 113 | * 2) When P frame is getting encoded, |
| 114 | * - get the estimated of P => No issues since we use the last coded P frame value |
| 115 | * - get the estimated of I => Simillar to I we have two cases. |
| 116 | * To handle the b) case extra logic had to introduced using |
| 117 | * u1_is_n_1_p_frm_ifi_avg_sad_usable flag |
| 118 | */ |
| 119 | UWORD32 irc_get_est_sad(est_sad_t *ps_est_sad, picture_type_e e_pic_type) |
| 120 | { |
| 121 | if(ps_est_sad->i4_use_est_intra_sad) |
| 122 | { |
| 123 | UWORD32 u4_estimated_sad; |
| 124 | if(e_pic_type == P_PIC) |
| 125 | { |
| 126 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[P_PIC]; |
| 127 | } |
| 128 | else if(e_pic_type == B_PIC) |
| 129 | { |
| 130 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[B_PIC]; |
| 131 | } |
| 132 | else |
| 133 | { |
| 134 | if(ps_est_sad->i4_num_ifi_encoded < 2) |
| 135 | { |
| 136 | /* |
| 137 | * Only one IFI has been encoded and so use the previous I |
| 138 | * frames SAD |
| 139 | */ |
| 140 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; |
| 141 | } |
| 142 | else |
| 143 | { |
| 144 | /* |
| 145 | * Since the n-1 'P' frame IFI would have just accumulated the |
| 146 | * frame sads we average it out here |
| 147 | */ |
| 148 | UWORD32 u4_n_1_p_frm_ifi_avg_sad, u4_n_2_p_frm_ifi_avg_sad; |
| 149 | number_t vq_n_1_p_frm_ifi_avg_sad, vq_n_2_p_frm_ifi_avg_sad; |
| 150 | number_t vq_prev_frm_sad_i; |
| 151 | |
| 152 | /* |
| 153 | * If there are frames in the current IFI start using it to |
| 154 | * estimate the I frame SAD |
| 155 | */ |
| 156 | if(ps_est_sad->i4_num_p_frm_in_cur_ifi) |
| 157 | { |
| 158 | u4_n_1_p_frm_ifi_avg_sad = |
| 159 | (ps_est_sad->u4_n_p_frm_ifi_avg_sad |
| 160 | / ps_est_sad->i4_num_p_frm_in_cur_ifi); |
| 161 | u4_n_2_p_frm_ifi_avg_sad = |
| 162 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; |
| 163 | } |
| 164 | else |
| 165 | { |
| 166 | u4_n_1_p_frm_ifi_avg_sad = |
| 167 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; |
| 168 | u4_n_2_p_frm_ifi_avg_sad = |
| 169 | ps_est_sad->u4_n_2_p_frm_ifi_avg_sad; |
| 170 | } |
| 171 | |
| 172 | /* |
| 173 | * If any of the previous p frame SADs are zeros we just return |
| 174 | * the previous I frame SAD |
| 175 | */ |
| 176 | if(u4_n_1_p_frm_ifi_avg_sad && u4_n_2_p_frm_ifi_avg_sad) |
| 177 | { |
| 178 | SET_VAR_Q(vq_prev_frm_sad_i, |
| 179 | ps_est_sad->au4_prev_frm_sad[I_PIC], 0); |
| 180 | SET_VAR_Q(vq_n_1_p_frm_ifi_avg_sad, |
| 181 | u4_n_1_p_frm_ifi_avg_sad, 0); |
| 182 | SET_VAR_Q(vq_n_2_p_frm_ifi_avg_sad, |
| 183 | u4_n_2_p_frm_ifi_avg_sad, 0); |
| 184 | /* |
| 185 | * Estimated SAD = |
| 186 | *(n-1)th intra frame interval(ifi) P frame Avg SAD * |
| 187 | *(prev I frame SAD / |
| 188 | *(prev (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, |
| 191 | &vq_prev_frm_sad_i); |
| 192 | div32_var_q(vq_prev_frm_sad_i, vq_n_2_p_frm_ifi_avg_sad, |
| 193 | &vq_prev_frm_sad_i); |
| 194 | number_t_to_word32(vq_prev_frm_sad_i, |
| 195 | (WORD32*)&u4_estimated_sad); |
| 196 | } |
| 197 | else |
| 198 | { |
| 199 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; |
| 200 | } |
| 201 | } |
| 202 | } |
| 203 | return u4_estimated_sad; |
| 204 | } |
| 205 | else |
| 206 | { |
| 207 | return ps_est_sad->au4_prev_frm_sad[e_pic_type]; |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | void irc_update_actual_sad(est_sad_t *ps_est_sad, |
| 212 | UWORD32 u4_actual_sad, |
| 213 | picture_type_e e_pic_type) |
| 214 | { |
| 215 | ps_est_sad->au4_prev_frm_sad[e_pic_type] = u4_actual_sad; |
| 216 | |
| 217 | if(ps_est_sad->i4_use_est_intra_sad) |
| 218 | { |
| 219 | if(e_pic_type == I_PIC) |
| 220 | { |
| 221 | /* The requirement is to have two IFI before estimating I frame SAD */ |
| 222 | if(ps_est_sad->i4_num_ifi_encoded < 2) |
| 223 | ps_est_sad->i4_num_ifi_encoded++; |
| 224 | |
| 225 | /* Calculate the average SAD */ |
| 226 | if(ps_est_sad->i4_num_p_frm_in_cur_ifi) |
| 227 | { |
| 228 | ps_est_sad->u4_n_p_frm_ifi_avg_sad /= |
| 229 | ps_est_sad->i4_num_p_frm_in_cur_ifi; |
| 230 | } |
| 231 | else |
| 232 | { |
| 233 | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
| 234 | } |
| 235 | /* Push the (n-1)th average SAD to the (n-2)th average SAD */ |
| 236 | ps_est_sad->u4_n_2_p_frm_ifi_avg_sad = |
| 237 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; |
| 238 | /* Push the nth average SAD to the (n-1)th average SAD */ |
| 239 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad = |
| 240 | ps_est_sad->u4_n_p_frm_ifi_avg_sad; |
| 241 | /* Reset SAD and number of P frames */ |
| 242 | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
| 243 | ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; |
| 244 | } |
| 245 | else |
| 246 | { |
| 247 | ps_est_sad->u4_n_p_frm_ifi_avg_sad += u4_actual_sad; |
| 248 | ps_est_sad->i4_num_p_frm_in_cur_ifi++; |
| 249 | } |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | void irc_update_actual_sad_for_intra(est_sad_t *ps_est_sad, |
| 254 | WORD32 i4_intra_frm_cost) |
| 255 | { |
| 256 | if(!(ps_est_sad->i4_use_est_intra_sad)) |
| 257 | { |
| 258 | irc_update_actual_sad(ps_est_sad, i4_intra_frm_cost, I_PIC); |
| 259 | } |
| 260 | } |