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
irc_est_sad_num_fill_use_free_memtab(est_sad_t ** pps_est_sad,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)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;
61 est_sad_t s_est_sad;
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
irc_init_est_sad(est_sad_t * ps_est_sad,WORD32 i4_use_est_intra_sad)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
irc_reset_est_sad(est_sad_t * ps_est_sad)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 */
irc_get_est_sad(est_sad_t * ps_est_sad,picture_type_e e_pic_type)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
irc_update_actual_sad(est_sad_t * ps_est_sad,UWORD32 u4_actual_sad,picture_type_e e_pic_type)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
irc_update_actual_sad_for_intra(est_sad_t * ps_est_sad,WORD32 i4_intra_frm_cost)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 }
261