/src/libhevc/encoder/est_sad.c
Line | Count | Source (jump to first uncovered line) |
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 | 57.5k | { |
60 | 57.5k | WORD32 i4_mem_tab_idx = 0; |
61 | 57.5k | 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 | 57.5k | if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) |
66 | 49.3k | (*pps_est_sad) = &s_est_sad; |
67 | | |
68 | | /*for src rate control state structure*/ |
69 | 57.5k | if(e_func_type != GET_NUM_MEMTAB) |
70 | 24.6k | { |
71 | 24.6k | fill_memtab( |
72 | 24.6k | &ps_memtab[i4_mem_tab_idx], sizeof(est_sad_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR); |
73 | 24.6k | use_or_fill_base(&ps_memtab[0], (void **)pps_est_sad, e_func_type); |
74 | 24.6k | } |
75 | 57.5k | i4_mem_tab_idx++; |
76 | | |
77 | 57.5k | return (i4_mem_tab_idx); |
78 | 57.5k | } |
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 | 13.5k | { |
91 | 13.5k | WORD32 i; |
92 | 13.5k | ps_est_sad->i4_use_est_intra_sad = i4_use_est_intra_sad; |
93 | | |
94 | 135k | for(i = 0; i < MAX_PIC_TYPE; i++) |
95 | 122k | ps_est_sad->au4_prev_frm_sad[i] = 0; |
96 | | |
97 | 13.5k | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
98 | 13.5k | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad = 0; |
99 | 13.5k | ps_est_sad->u4_n_2_p_frm_ifi_avg_sad = 0; |
100 | 13.5k | ps_est_sad->i4_num_ifi_encoded = 0; |
101 | 13.5k | ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; |
102 | 13.5k | } |
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 | 8.92k | { |
113 | 8.92k | init_est_sad(ps_est_sad, ps_est_sad->i4_use_est_intra_sad); |
114 | 8.92k | } |
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 | 1.09M | { |
141 | 1.09M | if(ps_est_sad->i4_use_est_intra_sad) |
142 | 0 | { |
143 | 0 | UWORD32 u4_estimated_sad; |
144 | 0 | if(e_pic_type == P_PIC) |
145 | 0 | { |
146 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[P_PIC]; |
147 | 0 | } |
148 | 0 | else if(e_pic_type == B_PIC) |
149 | 0 | { |
150 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[B_PIC]; |
151 | 0 | } |
152 | 0 | else |
153 | 0 | { |
154 | 0 | if(ps_est_sad->i4_num_ifi_encoded < 2) |
155 | 0 | { |
156 | | /* Only one IFI has been encoded and so use the previous I frames SAD */ |
157 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; |
158 | 0 | } |
159 | 0 | else |
160 | 0 | { |
161 | | /* Since the n-1 'P' frame IFI would have just accumulated the frame sads |
162 | | we average it out here */ |
163 | 0 | UWORD32 u4_n_1_p_frm_ifi_avg_sad, u4_n_2_p_frm_ifi_avg_sad; |
164 | 0 | number_t vq_n_1_p_frm_ifi_avg_sad, vq_n_2_p_frm_ifi_avg_sad; |
165 | 0 | 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 | 0 | if(ps_est_sad->i4_num_p_frm_in_cur_ifi) |
168 | 0 | { |
169 | 0 | u4_n_1_p_frm_ifi_avg_sad = |
170 | 0 | (ps_est_sad->u4_n_p_frm_ifi_avg_sad / ps_est_sad->i4_num_p_frm_in_cur_ifi); |
171 | 0 | u4_n_2_p_frm_ifi_avg_sad = ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; |
172 | 0 | } |
173 | 0 | else |
174 | 0 | { |
175 | 0 | u4_n_1_p_frm_ifi_avg_sad = ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; |
176 | 0 | u4_n_2_p_frm_ifi_avg_sad = ps_est_sad->u4_n_2_p_frm_ifi_avg_sad; |
177 | 0 | } |
178 | | /* If any of the previous p frame SADs are zeros we just return the previous |
179 | | I frame SAD */ |
180 | 0 | if(u4_n_1_p_frm_ifi_avg_sad && u4_n_2_p_frm_ifi_avg_sad) |
181 | 0 | { |
182 | 0 | SET_VAR_Q(vq_prev_frm_sad_i, ps_est_sad->au4_prev_frm_sad[I_PIC], 0); |
183 | 0 | SET_VAR_Q(vq_n_1_p_frm_ifi_avg_sad, u4_n_1_p_frm_ifi_avg_sad, 0); |
184 | 0 | 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 | 0 | mult32_var_q(vq_prev_frm_sad_i, vq_n_1_p_frm_ifi_avg_sad, &vq_prev_frm_sad_i); |
191 | 0 | div32_var_q(vq_prev_frm_sad_i, vq_n_2_p_frm_ifi_avg_sad, &vq_prev_frm_sad_i); |
192 | 0 | number_t_to_word32(vq_prev_frm_sad_i, (WORD32 *)&u4_estimated_sad); |
193 | 0 | } |
194 | 0 | else |
195 | 0 | { |
196 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; |
197 | 0 | } |
198 | 0 | } |
199 | 0 | } |
200 | 0 | return u4_estimated_sad; |
201 | 0 | } |
202 | 1.09M | else |
203 | 1.09M | { |
204 | 1.09M | return ps_est_sad->au4_prev_frm_sad[e_pic_type]; |
205 | 1.09M | } |
206 | 1.09M | } |
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 | 0 | { |
217 | 0 | 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 | 0 | if(i4_est_sad > (WORD32)ps_est_sad->au4_prev_frm_sad[P_PIC]) |
220 | 0 | { |
221 | 0 | if(4 * i4_est_sad > 5 * i4_prev_p_sad) |
222 | 0 | i4_est_sad = (5 * i4_prev_p_sad) >> 2; |
223 | 0 | ps_est_sad->au4_prev_frm_sad[P_PIC] = i4_est_sad; |
224 | 0 | return 0; |
225 | 0 | } |
226 | 0 | return 1; |
227 | 0 | } |
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 | 87.6k | { |
238 | 87.6k | ps_est_sad->au4_prev_frm_sad[e_pic_type] = u4_actual_sad; |
239 | | |
240 | 87.6k | if(ps_est_sad->i4_use_est_intra_sad) |
241 | 0 | { |
242 | 0 | if(e_pic_type == I_PIC) |
243 | 0 | { |
244 | | /* The requirement is to have two IFI before estimating I frame SAD */ |
245 | 0 | if(ps_est_sad->i4_num_ifi_encoded < 2) |
246 | 0 | ps_est_sad->i4_num_ifi_encoded++; |
247 | | |
248 | | /* Calculate the average SAD */ |
249 | 0 | if(ps_est_sad->i4_num_p_frm_in_cur_ifi) |
250 | 0 | { |
251 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad /= ps_est_sad->i4_num_p_frm_in_cur_ifi; |
252 | 0 | } |
253 | 0 | else |
254 | 0 | { |
255 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
256 | 0 | } |
257 | | /* Push the (n-1)th average SAD to the (n-2)th average SAD */ |
258 | 0 | 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 | 0 | 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 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
263 | 0 | ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; |
264 | 0 | } |
265 | 0 | else |
266 | 0 | { |
267 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad += u4_actual_sad; |
268 | 0 | ps_est_sad->i4_num_p_frm_in_cur_ifi++; |
269 | 0 | } |
270 | 0 | } |
271 | 87.6k | } |
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 | 19.5k | { |
282 | 19.5k | ps_est_sad->au4_prev_frm_sad[I_PIC] = i4_intra_frm_sad; |
283 | 19.5k | } |
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 | 19.5k | { |
294 | 19.5k | return ps_est_sad->au4_prev_frm_sad[I_PIC]; |
295 | 19.5k | } |
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 | 64.1k | { |
306 | 64.1k | ps_est_sad->au4_prev_frm_sad[e_pic_type] = i4_frm_sad; |
307 | 64.1k | } |
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 | 64.1k | { |
318 | 64.1k | return ps_est_sad->au4_prev_frm_sad[e_pic_type]; |
319 | 64.1k | } |