xref: /aosp_15_r20/external/libhevc/encoder/init_qp.c (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
1*c83a76b0SSuyog Pawar /******************************************************************************
2*c83a76b0SSuyog Pawar  *
3*c83a76b0SSuyog Pawar  * Copyright (C) 2018 The Android Open Source Project
4*c83a76b0SSuyog Pawar  *
5*c83a76b0SSuyog Pawar  * Licensed under the Apache License, Version 2.0 (the "License");
6*c83a76b0SSuyog Pawar  * you may not use this file except in compliance with the License.
7*c83a76b0SSuyog Pawar  * You may obtain a copy of the License at:
8*c83a76b0SSuyog Pawar  *
9*c83a76b0SSuyog Pawar  * http://www.apache.org/licenses/LICENSE-2.0
10*c83a76b0SSuyog Pawar  *
11*c83a76b0SSuyog Pawar  * Unless required by applicable law or agreed to in writing, software
12*c83a76b0SSuyog Pawar  * distributed under the License is distributed on an "AS IS" BASIS,
13*c83a76b0SSuyog Pawar  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*c83a76b0SSuyog Pawar  * See the License for the specific language governing permissions and
15*c83a76b0SSuyog Pawar  * limitations under the License.
16*c83a76b0SSuyog Pawar  *
17*c83a76b0SSuyog Pawar  *****************************************************************************
18*c83a76b0SSuyog Pawar  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*c83a76b0SSuyog Pawar */
20*c83a76b0SSuyog Pawar /*!
21*c83a76b0SSuyog Pawar ******************************************************************************
22*c83a76b0SSuyog Pawar * \file init_qp.c
23*c83a76b0SSuyog Pawar *
24*c83a76b0SSuyog Pawar * \brief
25*c83a76b0SSuyog Pawar *    This file contain qp initialization functions
26*c83a76b0SSuyog Pawar *
27*c83a76b0SSuyog Pawar * \date
28*c83a76b0SSuyog Pawar *
29*c83a76b0SSuyog Pawar * \author
30*c83a76b0SSuyog Pawar *    ittiam
31*c83a76b0SSuyog Pawar *
32*c83a76b0SSuyog Pawar ******************************************************************************
33*c83a76b0SSuyog Pawar */
34*c83a76b0SSuyog Pawar /*****************************************************************************/
35*c83a76b0SSuyog Pawar /* File Includes                                                             */
36*c83a76b0SSuyog Pawar /*****************************************************************************/
37*c83a76b0SSuyog Pawar /* User include files */
38*c83a76b0SSuyog Pawar #include "ittiam_datatypes.h"
39*c83a76b0SSuyog Pawar #include "rc_cntrl_param.h"
40*c83a76b0SSuyog Pawar #include "var_q_operator.h"
41*c83a76b0SSuyog Pawar #include "mem_req_and_acq.h"
42*c83a76b0SSuyog Pawar #include "rc_common.h"
43*c83a76b0SSuyog Pawar #include "init_qp.h"
44*c83a76b0SSuyog Pawar 
45*c83a76b0SSuyog Pawar typedef struct init_qp_t
46*c83a76b0SSuyog Pawar {
47*c83a76b0SSuyog Pawar     /* WORD32 ai4_bpp_for_qp[MAX_MPEG2_QP]; */
48*c83a76b0SSuyog Pawar     WORD32 i4_max_qp;
49*c83a76b0SSuyog Pawar     WORD32 i4_num_pels_in_frame;
50*c83a76b0SSuyog Pawar     WORD32 i4_is_hbr;
51*c83a76b0SSuyog Pawar } init_qp_t;
52*c83a76b0SSuyog Pawar 
53*c83a76b0SSuyog Pawar #define BPP_Q_FACTOR (16)
54*c83a76b0SSuyog Pawar #define QP_FOR_ONE_BPP (3) /*(10)*/
55*c83a76b0SSuyog Pawar 
56*c83a76b0SSuyog Pawar #if NON_STEADSTATE_CODE
init_qp_num_fill_use_free_memtab(init_qp_handle * pps_init_qp,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)57*c83a76b0SSuyog Pawar WORD32 init_qp_num_fill_use_free_memtab(
58*c83a76b0SSuyog Pawar     init_qp_handle *pps_init_qp, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
59*c83a76b0SSuyog Pawar {
60*c83a76b0SSuyog Pawar     WORD32 i4_mem_tab_idx = 0;
61*c83a76b0SSuyog Pawar     static init_qp_t s_init_qp;
62*c83a76b0SSuyog Pawar 
63*c83a76b0SSuyog Pawar     /* Hack for al alloc, during which we dont have any state memory.
64*c83a76b0SSuyog Pawar       Dereferencing can cause issues */
65*c83a76b0SSuyog Pawar     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
66*c83a76b0SSuyog Pawar         (*pps_init_qp) = &s_init_qp;
67*c83a76b0SSuyog Pawar 
68*c83a76b0SSuyog Pawar     /*for src rate control state structure*/
69*c83a76b0SSuyog Pawar     if(e_func_type != GET_NUM_MEMTAB)
70*c83a76b0SSuyog Pawar     {
71*c83a76b0SSuyog Pawar         fill_memtab(
72*c83a76b0SSuyog Pawar             &ps_memtab[i4_mem_tab_idx], sizeof(init_qp_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR);
73*c83a76b0SSuyog Pawar         use_or_fill_base(&ps_memtab[0], (void **)pps_init_qp, e_func_type);
74*c83a76b0SSuyog Pawar     }
75*c83a76b0SSuyog Pawar     i4_mem_tab_idx++;
76*c83a76b0SSuyog Pawar 
77*c83a76b0SSuyog Pawar     return (i4_mem_tab_idx);
78*c83a76b0SSuyog Pawar }
79*c83a76b0SSuyog Pawar 
80*c83a76b0SSuyog Pawar /****************************************************************************
81*c83a76b0SSuyog Pawar Function Name : init_init_qp
82*c83a76b0SSuyog Pawar Description   :
83*c83a76b0SSuyog Pawar Inputs        : ps_init_qp
84*c83a76b0SSuyog Pawar 
85*c83a76b0SSuyog Pawar Revision History:
86*c83a76b0SSuyog Pawar DD MM YYYY   Author(s)       Changes (Describe the changes made)
87*c83a76b0SSuyog Pawar  *****************************************************************************/
init_init_qp(init_qp_handle ps_init_qp,WORD32 * pi4_min_max_qp,WORD32 i4_num_pels_in_frame,WORD32 i4_is_hbr)88*c83a76b0SSuyog Pawar void init_init_qp(
89*c83a76b0SSuyog Pawar     init_qp_handle ps_init_qp, WORD32 *pi4_min_max_qp, WORD32 i4_num_pels_in_frame, WORD32 i4_is_hbr)
90*c83a76b0SSuyog Pawar {
91*c83a76b0SSuyog Pawar     WORD32 i4_max_qp;
92*c83a76b0SSuyog Pawar     /* Finding the max qp among I P and B frame */
93*c83a76b0SSuyog Pawar     i4_max_qp = pi4_min_max_qp[1];
94*c83a76b0SSuyog Pawar     if(i4_max_qp < pi4_min_max_qp[3])
95*c83a76b0SSuyog Pawar         i4_max_qp = pi4_min_max_qp[3];
96*c83a76b0SSuyog Pawar     if(i4_max_qp < pi4_min_max_qp[5])
97*c83a76b0SSuyog Pawar         i4_max_qp = pi4_min_max_qp[5];
98*c83a76b0SSuyog Pawar 
99*c83a76b0SSuyog Pawar     /*for(i=0;i<i4_max_qp;i++)
100*c83a76b0SSuyog Pawar     {
101*c83a76b0SSuyog Pawar         ps_init_qp->ai4_bpp_for_qp[i] = (QP_FOR_ONE_BPP*(1<<BPP_Q_FACTOR))/(i+1);
102*c83a76b0SSuyog Pawar     }*/
103*c83a76b0SSuyog Pawar     ps_init_qp->i4_max_qp = i4_max_qp;
104*c83a76b0SSuyog Pawar     ps_init_qp->i4_num_pels_in_frame = (!i4_num_pels_in_frame) ? 1 : i4_num_pels_in_frame;
105*c83a76b0SSuyog Pawar     ps_init_qp->i4_is_hbr = i4_is_hbr;
106*c83a76b0SSuyog Pawar }
107*c83a76b0SSuyog Pawar #endif /* #if NON_STEADSTATE_CODE */
108*c83a76b0SSuyog Pawar 
109*c83a76b0SSuyog Pawar /* To ensure init_qp for high bit rates is low */
110*c83a76b0SSuyog Pawar #define QP_FOR_ONE_BPP_HBR (5)
111*c83a76b0SSuyog Pawar 
112*c83a76b0SSuyog Pawar /****************************************************************************
113*c83a76b0SSuyog Pawar Function Name : get_init_qp_using_pels_bits_per_frame
114*c83a76b0SSuyog Pawar Description   :
115*c83a76b0SSuyog Pawar Inputs        : ps_init_qp
116*c83a76b0SSuyog Pawar 
117*c83a76b0SSuyog Pawar Revision History:
118*c83a76b0SSuyog Pawar DD MM YYYY   Author(s)       Changes (Describe the changes made)
119*c83a76b0SSuyog Pawar  *****************************************************************************/
120*c83a76b0SSuyog Pawar /* If the remaining pels in frame is zero we would be using the init time pixels for calculating the bits per pixel */
get_init_qp_using_pels_bits_per_frame(init_qp_handle ps_init_qp,picture_type_e e_pic_type,WORD32 i4_bits_remaining_in_frame,WORD32 i4_rem_pels_in_frame)121*c83a76b0SSuyog Pawar WORD32 get_init_qp_using_pels_bits_per_frame(
122*c83a76b0SSuyog Pawar     init_qp_handle ps_init_qp,
123*c83a76b0SSuyog Pawar     picture_type_e e_pic_type,
124*c83a76b0SSuyog Pawar     WORD32 i4_bits_remaining_in_frame,
125*c83a76b0SSuyog Pawar     WORD32 i4_rem_pels_in_frame)
126*c83a76b0SSuyog Pawar {
127*c83a76b0SSuyog Pawar     WORD32 i4_qp;
128*c83a76b0SSuyog Pawar     WORD32 i4_qp_for_one_bpp;
129*c83a76b0SSuyog Pawar 
130*c83a76b0SSuyog Pawar     if(ps_init_qp->i4_is_hbr)
131*c83a76b0SSuyog Pawar     {
132*c83a76b0SSuyog Pawar         i4_qp_for_one_bpp = QP_FOR_ONE_BPP_HBR;
133*c83a76b0SSuyog Pawar     }
134*c83a76b0SSuyog Pawar     else
135*c83a76b0SSuyog Pawar     {
136*c83a76b0SSuyog Pawar         i4_qp_for_one_bpp = QP_FOR_ONE_BPP;
137*c83a76b0SSuyog Pawar     }
138*c83a76b0SSuyog Pawar 
139*c83a76b0SSuyog Pawar     if(!i4_rem_pels_in_frame)
140*c83a76b0SSuyog Pawar         i4_rem_pels_in_frame = ps_init_qp->i4_num_pels_in_frame;
141*c83a76b0SSuyog Pawar     if(e_pic_type == P_PIC || e_pic_type == P1_PIC)
142*c83a76b0SSuyog Pawar         i4_bits_remaining_in_frame = i4_bits_remaining_in_frame * I_TO_P_BIT_RATIO;
143*c83a76b0SSuyog Pawar     if(e_pic_type >= B_PIC && e_pic_type != P1_PIC)
144*c83a76b0SSuyog Pawar         i4_bits_remaining_in_frame =
145*c83a76b0SSuyog Pawar             i4_bits_remaining_in_frame * (I_TO_P_BIT_RATIO * P_TO_B_BIT_RATIO);
146*c83a76b0SSuyog Pawar 
147*c83a76b0SSuyog Pawar     /* Assuming a 1 bpp => Qp = 12, So Qp = 1 => 12 bpp. [bpp halves with every doubling of Qp] */
148*c83a76b0SSuyog Pawar     /* x bpp =  i4_bits_remaining_in_frame/i4_rem_pels_in_frame
149*c83a76b0SSuyog Pawar        1 bpp = QP_FOR_ONE_BPP
150*c83a76b0SSuyog Pawar        QP_FOR_X_BPP = QP_FOR_ONE_BPP/(x) = QP_FOR_ONE_BPP*i4_rem_pels_in_frame/i4_bits_remaining_in_frame */
151*c83a76b0SSuyog Pawar     X_PROD_Y_DIV_Z(i4_qp_for_one_bpp, i4_rem_pels_in_frame, i4_bits_remaining_in_frame, i4_qp);
152*c83a76b0SSuyog Pawar 
153*c83a76b0SSuyog Pawar     /* Scaling the Qp values based on picture type */
154*c83a76b0SSuyog Pawar     if(e_pic_type == P_PIC || e_pic_type == P1_PIC)
155*c83a76b0SSuyog Pawar         i4_qp = ((i4_qp * I_TO_P_RATIO) >> K_Q);
156*c83a76b0SSuyog Pawar 
157*c83a76b0SSuyog Pawar     if(e_pic_type >= B_PIC && e_pic_type != P1_PIC)
158*c83a76b0SSuyog Pawar     {
159*c83a76b0SSuyog Pawar         if(!ps_init_qp->i4_is_hbr)
160*c83a76b0SSuyog Pawar         {
161*c83a76b0SSuyog Pawar             i4_qp = ((i4_qp * P_TO_B_RATIO * I_TO_P_RATIO) >> (K_Q + K_Q));
162*c83a76b0SSuyog Pawar         }
163*c83a76b0SSuyog Pawar         else
164*c83a76b0SSuyog Pawar         {
165*c83a76b0SSuyog Pawar             i4_qp = ((i4_qp * P_TO_B_RATIO_HBR * I_TO_P_RATIO) >> (K_Q + K_Q));
166*c83a76b0SSuyog Pawar         }
167*c83a76b0SSuyog Pawar     }
168*c83a76b0SSuyog Pawar 
169*c83a76b0SSuyog Pawar     if(i4_qp > ps_init_qp->i4_max_qp)
170*c83a76b0SSuyog Pawar         i4_qp = ps_init_qp->i4_max_qp;
171*c83a76b0SSuyog Pawar     else if(i4_qp == 0)
172*c83a76b0SSuyog Pawar         i4_qp = 1;
173*c83a76b0SSuyog Pawar 
174*c83a76b0SSuyog Pawar     return i4_qp;
175*c83a76b0SSuyog Pawar }
176*c83a76b0SSuyog Pawar 
177*c83a76b0SSuyog Pawar #if NON_STEADSTATE_CODE
178*c83a76b0SSuyog Pawar /****************************************************************************
179*c83a76b0SSuyog Pawar Function Name : change_init_qp_max_qp
180*c83a76b0SSuyog Pawar Description   :
181*c83a76b0SSuyog Pawar Inputs        : ps_init_qp
182*c83a76b0SSuyog Pawar 
183*c83a76b0SSuyog Pawar Revision History:
184*c83a76b0SSuyog Pawar DD MM YYYY   Author(s)       Changes (Describe the changes made)
185*c83a76b0SSuyog Pawar  *****************************************************************************/
change_init_qp_max_qp(init_qp_handle ps_init_qp,WORD32 * pi4_min_max_qp)186*c83a76b0SSuyog Pawar void change_init_qp_max_qp(init_qp_handle ps_init_qp, WORD32 *pi4_min_max_qp)
187*c83a76b0SSuyog Pawar {
188*c83a76b0SSuyog Pawar     WORD32 i4_max_qp;
189*c83a76b0SSuyog Pawar     /* Finding the max qp among I P and B frame */
190*c83a76b0SSuyog Pawar     i4_max_qp = pi4_min_max_qp[1];
191*c83a76b0SSuyog Pawar     if(i4_max_qp < pi4_min_max_qp[3])
192*c83a76b0SSuyog Pawar         i4_max_qp = pi4_min_max_qp[3];
193*c83a76b0SSuyog Pawar     if(i4_max_qp < pi4_min_max_qp[5])
194*c83a76b0SSuyog Pawar         i4_max_qp = pi4_min_max_qp[5];
195*c83a76b0SSuyog Pawar 
196*c83a76b0SSuyog Pawar     ps_init_qp->i4_max_qp = i4_max_qp;
197*c83a76b0SSuyog Pawar }
198*c83a76b0SSuyog Pawar #endif /* #if NON_STEADSTATE_CODE */
199