irc_est_sad.c revision c22addc6ee9c96f2996001362dbe39dd5e14038d
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
32typedef 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
56WORD32 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
81void 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
98void 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 */
119UWORD32 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
211void 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
253void 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