/src/libavc/encoder/irc_est_sad.c
Line | Count | Source (jump to first uncovered line) |
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 | 127k | { |
60 | 127k | WORD32 i4_mem_tab_idx = 0; |
61 | 127k | 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 | 127k | if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB) |
67 | 106k | (*pps_est_sad) = &s_est_sad; |
68 | | |
69 | | /* For src rate control state structure */ |
70 | 127k | if(e_func_type != GET_NUM_MEMTAB) |
71 | 63.8k | { |
72 | 63.8k | fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(est_sad_t), |
73 | 63.8k | ALIGN_128_BYTE, PERSISTENT, DDR); |
74 | 63.8k | use_or_fill_base(&ps_memtab[0], (void**)pps_est_sad, e_func_type); |
75 | 63.8k | } |
76 | 127k | i4_mem_tab_idx++; |
77 | | |
78 | 127k | return (i4_mem_tab_idx); |
79 | 127k | } |
80 | | |
81 | | void irc_init_est_sad(est_sad_t *ps_est_sad, WORD32 i4_use_est_intra_sad) |
82 | 44.7k | { |
83 | 44.7k | WORD32 i; |
84 | 44.7k | ps_est_sad->i4_use_est_intra_sad = i4_use_est_intra_sad; |
85 | | |
86 | 179k | for(i = 0; i < MAX_PIC_TYPE; i++) |
87 | 134k | { |
88 | 134k | ps_est_sad->au4_prev_frm_sad[i] = 0; |
89 | 134k | } |
90 | | |
91 | 44.7k | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
92 | 44.7k | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad = 0; |
93 | 44.7k | ps_est_sad->u4_n_2_p_frm_ifi_avg_sad = 0; |
94 | 44.7k | ps_est_sad->i4_num_ifi_encoded = 0; |
95 | 44.7k | ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; |
96 | 44.7k | } |
97 | | |
98 | | void irc_reset_est_sad(est_sad_t *ps_est_sad) |
99 | 2.88k | { |
100 | 2.88k | irc_init_est_sad(ps_est_sad, ps_est_sad->i4_use_est_intra_sad); |
101 | 2.88k | } |
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 | 171k | { |
121 | 171k | if(ps_est_sad->i4_use_est_intra_sad) |
122 | 0 | { |
123 | 0 | UWORD32 u4_estimated_sad; |
124 | 0 | if(e_pic_type == P_PIC) |
125 | 0 | { |
126 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[P_PIC]; |
127 | 0 | } |
128 | 0 | else if(e_pic_type == B_PIC) |
129 | 0 | { |
130 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[B_PIC]; |
131 | 0 | } |
132 | 0 | else |
133 | 0 | { |
134 | 0 | if(ps_est_sad->i4_num_ifi_encoded < 2) |
135 | 0 | { |
136 | | /* |
137 | | * Only one IFI has been encoded and so use the previous I |
138 | | * frames SAD |
139 | | */ |
140 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; |
141 | 0 | } |
142 | 0 | else |
143 | 0 | { |
144 | | /* |
145 | | * Since the n-1 'P' frame IFI would have just accumulated the |
146 | | * frame sads we average it out here |
147 | | */ |
148 | 0 | UWORD32 u4_n_1_p_frm_ifi_avg_sad, u4_n_2_p_frm_ifi_avg_sad; |
149 | 0 | number_t vq_n_1_p_frm_ifi_avg_sad, vq_n_2_p_frm_ifi_avg_sad; |
150 | 0 | 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 | 0 | if(ps_est_sad->i4_num_p_frm_in_cur_ifi) |
157 | 0 | { |
158 | 0 | u4_n_1_p_frm_ifi_avg_sad = |
159 | 0 | (ps_est_sad->u4_n_p_frm_ifi_avg_sad |
160 | 0 | / ps_est_sad->i4_num_p_frm_in_cur_ifi); |
161 | 0 | u4_n_2_p_frm_ifi_avg_sad = |
162 | 0 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; |
163 | 0 | } |
164 | 0 | else |
165 | 0 | { |
166 | 0 | u4_n_1_p_frm_ifi_avg_sad = |
167 | 0 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad; |
168 | 0 | u4_n_2_p_frm_ifi_avg_sad = |
169 | 0 | ps_est_sad->u4_n_2_p_frm_ifi_avg_sad; |
170 | 0 | } |
171 | | |
172 | | /* |
173 | | * If any of the previous p frame SADs are zeros we just return |
174 | | * the previous I frame SAD |
175 | | */ |
176 | 0 | if(u4_n_1_p_frm_ifi_avg_sad && u4_n_2_p_frm_ifi_avg_sad) |
177 | 0 | { |
178 | 0 | SET_VAR_Q(vq_prev_frm_sad_i, |
179 | 0 | ps_est_sad->au4_prev_frm_sad[I_PIC], 0); |
180 | 0 | SET_VAR_Q(vq_n_1_p_frm_ifi_avg_sad, |
181 | 0 | u4_n_1_p_frm_ifi_avg_sad, 0); |
182 | 0 | SET_VAR_Q(vq_n_2_p_frm_ifi_avg_sad, |
183 | 0 | 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 | 0 | mult32_var_q(vq_prev_frm_sad_i, vq_n_1_p_frm_ifi_avg_sad, |
191 | 0 | &vq_prev_frm_sad_i); |
192 | 0 | div32_var_q(vq_prev_frm_sad_i, vq_n_2_p_frm_ifi_avg_sad, |
193 | 0 | &vq_prev_frm_sad_i); |
194 | 0 | number_t_to_word32(vq_prev_frm_sad_i, |
195 | 0 | (WORD32*)&u4_estimated_sad); |
196 | 0 | } |
197 | 0 | else |
198 | 0 | { |
199 | 0 | u4_estimated_sad = ps_est_sad->au4_prev_frm_sad[I_PIC]; |
200 | 0 | } |
201 | 0 | } |
202 | 0 | } |
203 | 0 | return u4_estimated_sad; |
204 | 0 | } |
205 | 171k | else |
206 | 171k | { |
207 | 171k | return ps_est_sad->au4_prev_frm_sad[e_pic_type]; |
208 | 171k | } |
209 | 171k | } |
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 | 137k | { |
215 | 137k | ps_est_sad->au4_prev_frm_sad[e_pic_type] = u4_actual_sad; |
216 | | |
217 | 137k | if(ps_est_sad->i4_use_est_intra_sad) |
218 | 0 | { |
219 | 0 | if(e_pic_type == I_PIC) |
220 | 0 | { |
221 | | /* The requirement is to have two IFI before estimating I frame SAD */ |
222 | 0 | if(ps_est_sad->i4_num_ifi_encoded < 2) |
223 | 0 | ps_est_sad->i4_num_ifi_encoded++; |
224 | | |
225 | | /* Calculate the average SAD */ |
226 | 0 | if(ps_est_sad->i4_num_p_frm_in_cur_ifi) |
227 | 0 | { |
228 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad /= |
229 | 0 | ps_est_sad->i4_num_p_frm_in_cur_ifi; |
230 | 0 | } |
231 | 0 | else |
232 | 0 | { |
233 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
234 | 0 | } |
235 | | /* Push the (n-1)th average SAD to the (n-2)th average SAD */ |
236 | 0 | ps_est_sad->u4_n_2_p_frm_ifi_avg_sad = |
237 | 0 | 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 | 0 | ps_est_sad->u4_n_1_p_frm_ifi_avg_sad = |
240 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad; |
241 | | /* Reset SAD and number of P frames */ |
242 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad = 0; |
243 | 0 | ps_est_sad->i4_num_p_frm_in_cur_ifi = 0; |
244 | 0 | } |
245 | 0 | else |
246 | 0 | { |
247 | 0 | ps_est_sad->u4_n_p_frm_ifi_avg_sad += u4_actual_sad; |
248 | 0 | ps_est_sad->i4_num_p_frm_in_cur_ifi++; |
249 | 0 | } |
250 | 0 | } |
251 | 137k | } |
252 | | |
253 | | void irc_update_actual_sad_for_intra(est_sad_t *ps_est_sad, |
254 | | WORD32 i4_intra_frm_cost) |
255 | 68.8k | { |
256 | 68.8k | if(!(ps_est_sad->i4_use_est_intra_sad)) |
257 | 68.8k | { |
258 | 68.8k | irc_update_actual_sad(ps_est_sad, i4_intra_frm_cost, I_PIC); |
259 | 68.8k | } |
260 | 68.8k | } |