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 init_qp.c
23 *
24 * \brief
25 * This file contain qp initialization 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_cntrl_param.h"
40 #include "var_q_operator.h"
41 #include "mem_req_and_acq.h"
42 #include "rc_common.h"
43 #include "init_qp.h"
44
45 typedef struct init_qp_t
46 {
47 /* WORD32 ai4_bpp_for_qp[MAX_MPEG2_QP]; */
48 WORD32 i4_max_qp;
49 WORD32 i4_num_pels_in_frame;
50 WORD32 i4_is_hbr;
51 } init_qp_t;
52
53 #define BPP_Q_FACTOR (16)
54 #define QP_FOR_ONE_BPP (3) /*(10)*/
55
56 #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 WORD32 init_qp_num_fill_use_free_memtab(
58 init_qp_handle *pps_init_qp, itt_memtab_t *ps_memtab, ITT_FUNC_TYPE_E e_func_type)
59 {
60 WORD32 i4_mem_tab_idx = 0;
61 static init_qp_t s_init_qp;
62
63 /* Hack for al alloc, during which we dont have any state memory.
64 Dereferencing can cause issues */
65 if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
66 (*pps_init_qp) = &s_init_qp;
67
68 /*for src rate control state structure*/
69 if(e_func_type != GET_NUM_MEMTAB)
70 {
71 fill_memtab(
72 &ps_memtab[i4_mem_tab_idx], sizeof(init_qp_t), MEM_TAB_ALIGNMENT, PERSISTENT, DDR);
73 use_or_fill_base(&ps_memtab[0], (void **)pps_init_qp, e_func_type);
74 }
75 i4_mem_tab_idx++;
76
77 return (i4_mem_tab_idx);
78 }
79
80 /****************************************************************************
81 Function Name : init_init_qp
82 Description :
83 Inputs : ps_init_qp
84
85 Revision History:
86 DD MM YYYY Author(s) Changes (Describe the changes made)
87 *****************************************************************************/
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 void init_init_qp(
89 init_qp_handle ps_init_qp, WORD32 *pi4_min_max_qp, WORD32 i4_num_pels_in_frame, WORD32 i4_is_hbr)
90 {
91 WORD32 i4_max_qp;
92 /* Finding the max qp among I P and B frame */
93 i4_max_qp = pi4_min_max_qp[1];
94 if(i4_max_qp < pi4_min_max_qp[3])
95 i4_max_qp = pi4_min_max_qp[3];
96 if(i4_max_qp < pi4_min_max_qp[5])
97 i4_max_qp = pi4_min_max_qp[5];
98
99 /*for(i=0;i<i4_max_qp;i++)
100 {
101 ps_init_qp->ai4_bpp_for_qp[i] = (QP_FOR_ONE_BPP*(1<<BPP_Q_FACTOR))/(i+1);
102 }*/
103 ps_init_qp->i4_max_qp = i4_max_qp;
104 ps_init_qp->i4_num_pels_in_frame = (!i4_num_pels_in_frame) ? 1 : i4_num_pels_in_frame;
105 ps_init_qp->i4_is_hbr = i4_is_hbr;
106 }
107 #endif /* #if NON_STEADSTATE_CODE */
108
109 /* To ensure init_qp for high bit rates is low */
110 #define QP_FOR_ONE_BPP_HBR (5)
111
112 /****************************************************************************
113 Function Name : get_init_qp_using_pels_bits_per_frame
114 Description :
115 Inputs : ps_init_qp
116
117 Revision History:
118 DD MM YYYY Author(s) Changes (Describe the changes made)
119 *****************************************************************************/
120 /* 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 WORD32 get_init_qp_using_pels_bits_per_frame(
122 init_qp_handle ps_init_qp,
123 picture_type_e e_pic_type,
124 WORD32 i4_bits_remaining_in_frame,
125 WORD32 i4_rem_pels_in_frame)
126 {
127 WORD32 i4_qp;
128 WORD32 i4_qp_for_one_bpp;
129
130 if(ps_init_qp->i4_is_hbr)
131 {
132 i4_qp_for_one_bpp = QP_FOR_ONE_BPP_HBR;
133 }
134 else
135 {
136 i4_qp_for_one_bpp = QP_FOR_ONE_BPP;
137 }
138
139 if(!i4_rem_pels_in_frame)
140 i4_rem_pels_in_frame = ps_init_qp->i4_num_pels_in_frame;
141 if(e_pic_type == P_PIC || e_pic_type == P1_PIC)
142 i4_bits_remaining_in_frame = i4_bits_remaining_in_frame * I_TO_P_BIT_RATIO;
143 if(e_pic_type >= B_PIC && e_pic_type != P1_PIC)
144 i4_bits_remaining_in_frame =
145 i4_bits_remaining_in_frame * (I_TO_P_BIT_RATIO * P_TO_B_BIT_RATIO);
146
147 /* Assuming a 1 bpp => Qp = 12, So Qp = 1 => 12 bpp. [bpp halves with every doubling of Qp] */
148 /* x bpp = i4_bits_remaining_in_frame/i4_rem_pels_in_frame
149 1 bpp = QP_FOR_ONE_BPP
150 QP_FOR_X_BPP = QP_FOR_ONE_BPP/(x) = QP_FOR_ONE_BPP*i4_rem_pels_in_frame/i4_bits_remaining_in_frame */
151 X_PROD_Y_DIV_Z(i4_qp_for_one_bpp, i4_rem_pels_in_frame, i4_bits_remaining_in_frame, i4_qp);
152
153 /* Scaling the Qp values based on picture type */
154 if(e_pic_type == P_PIC || e_pic_type == P1_PIC)
155 i4_qp = ((i4_qp * I_TO_P_RATIO) >> K_Q);
156
157 if(e_pic_type >= B_PIC && e_pic_type != P1_PIC)
158 {
159 if(!ps_init_qp->i4_is_hbr)
160 {
161 i4_qp = ((i4_qp * P_TO_B_RATIO * I_TO_P_RATIO) >> (K_Q + K_Q));
162 }
163 else
164 {
165 i4_qp = ((i4_qp * P_TO_B_RATIO_HBR * I_TO_P_RATIO) >> (K_Q + K_Q));
166 }
167 }
168
169 if(i4_qp > ps_init_qp->i4_max_qp)
170 i4_qp = ps_init_qp->i4_max_qp;
171 else if(i4_qp == 0)
172 i4_qp = 1;
173
174 return i4_qp;
175 }
176
177 #if NON_STEADSTATE_CODE
178 /****************************************************************************
179 Function Name : change_init_qp_max_qp
180 Description :
181 Inputs : ps_init_qp
182
183 Revision History:
184 DD MM YYYY Author(s) Changes (Describe the changes made)
185 *****************************************************************************/
change_init_qp_max_qp(init_qp_handle ps_init_qp,WORD32 * pi4_min_max_qp)186 void change_init_qp_max_qp(init_qp_handle ps_init_qp, WORD32 *pi4_min_max_qp)
187 {
188 WORD32 i4_max_qp;
189 /* Finding the max qp among I P and B frame */
190 i4_max_qp = pi4_min_max_qp[1];
191 if(i4_max_qp < pi4_min_max_qp[3])
192 i4_max_qp = pi4_min_max_qp[3];
193 if(i4_max_qp < pi4_min_max_qp[5])
194 i4_max_qp = pi4_min_max_qp[5];
195
196 ps_init_qp->i4_max_qp = i4_max_qp;
197 }
198 #endif /* #if NON_STEADSTATE_CODE */
199