Home | History | Annotate | Download | only in encoder
      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;
     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 
     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 }
    261