xref: /aosp_15_r20/external/libavc/encoder/ih264e_utils.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
4*495ae853SAndroid Build Coastguard Worker  *
5*495ae853SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*495ae853SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*495ae853SAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*495ae853SAndroid Build Coastguard Worker  *
9*495ae853SAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*495ae853SAndroid Build Coastguard Worker  *
11*495ae853SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*495ae853SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*495ae853SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*495ae853SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*495ae853SAndroid Build Coastguard Worker  * limitations under the License.
16*495ae853SAndroid Build Coastguard Worker  *
17*495ae853SAndroid Build Coastguard Worker  *****************************************************************************
18*495ae853SAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*495ae853SAndroid Build Coastguard Worker */
20*495ae853SAndroid Build Coastguard Worker 
21*495ae853SAndroid Build Coastguard Worker /**
22*495ae853SAndroid Build Coastguard Worker *******************************************************************************
23*495ae853SAndroid Build Coastguard Worker * @file
24*495ae853SAndroid Build Coastguard Worker *  ih264e_utils.c
25*495ae853SAndroid Build Coastguard Worker *
26*495ae853SAndroid Build Coastguard Worker * @brief
27*495ae853SAndroid Build Coastguard Worker *  Contains miscellaneous utility functions used by the encoder
28*495ae853SAndroid Build Coastguard Worker *
29*495ae853SAndroid Build Coastguard Worker * @author
30*495ae853SAndroid Build Coastguard Worker *  ittiam
31*495ae853SAndroid Build Coastguard Worker *
32*495ae853SAndroid Build Coastguard Worker * @par List of Functions:
33*495ae853SAndroid Build Coastguard Worker *  - ih264e_input_queue_update
34*495ae853SAndroid Build Coastguard Worker *  - ih264e_get_min_level
35*495ae853SAndroid Build Coastguard Worker *  - ih264e_get_lvl_idx
36*495ae853SAndroid Build Coastguard Worker *  - ih264e_get_dpb_size
37*495ae853SAndroid Build Coastguard Worker *  - ih264e_get_total_pic_buf_size
38*495ae853SAndroid Build Coastguard Worker *  - ih264e_get_pic_mv_bank_size
39*495ae853SAndroid Build Coastguard Worker *  - ih264e_pic_buf_mgr_add_bufs
40*495ae853SAndroid Build Coastguard Worker *  - ih264e_mv_buf_mgr_add_bufs
41*495ae853SAndroid Build Coastguard Worker *  - ih264e_init_quant_params
42*495ae853SAndroid Build Coastguard Worker *  - ih264e_init_air_map
43*495ae853SAndroid Build Coastguard Worker *  - ih264e_codec_init
44*495ae853SAndroid Build Coastguard Worker *  - ih264e_pic_init
45*495ae853SAndroid Build Coastguard Worker *
46*495ae853SAndroid Build Coastguard Worker * @remarks
47*495ae853SAndroid Build Coastguard Worker *  none
48*495ae853SAndroid Build Coastguard Worker *
49*495ae853SAndroid Build Coastguard Worker *******************************************************************************
50*495ae853SAndroid Build Coastguard Worker */
51*495ae853SAndroid Build Coastguard Worker 
52*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
53*495ae853SAndroid Build Coastguard Worker /* File Includes                                                             */
54*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
55*495ae853SAndroid Build Coastguard Worker 
56*495ae853SAndroid Build Coastguard Worker /* System Include Files */
57*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
58*495ae853SAndroid Build Coastguard Worker #include <stddef.h>
59*495ae853SAndroid Build Coastguard Worker #include <stdlib.h>
60*495ae853SAndroid Build Coastguard Worker #include <string.h>
61*495ae853SAndroid Build Coastguard Worker #include <assert.h>
62*495ae853SAndroid Build Coastguard Worker 
63*495ae853SAndroid Build Coastguard Worker /* User Include Files */
64*495ae853SAndroid Build Coastguard Worker #include "ih264e_config.h"
65*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
66*495ae853SAndroid Build Coastguard Worker #include "iv2.h"
67*495ae853SAndroid Build Coastguard Worker #include "ive2.h"
68*495ae853SAndroid Build Coastguard Worker #include "ithread.h"
69*495ae853SAndroid Build Coastguard Worker 
70*495ae853SAndroid Build Coastguard Worker #include "ih264_debug.h"
71*495ae853SAndroid Build Coastguard Worker #include "ih264_macros.h"
72*495ae853SAndroid Build Coastguard Worker #include "ih264_error.h"
73*495ae853SAndroid Build Coastguard Worker #include "ih264_defs.h"
74*495ae853SAndroid Build Coastguard Worker #include "ih264_mem_fns.h"
75*495ae853SAndroid Build Coastguard Worker #include "ih264_padding.h"
76*495ae853SAndroid Build Coastguard Worker #include "ih264_structs.h"
77*495ae853SAndroid Build Coastguard Worker #include "ih264_size_defs.h"
78*495ae853SAndroid Build Coastguard Worker #include "ih264_trans_quant_itrans_iquant.h"
79*495ae853SAndroid Build Coastguard Worker #include "ih264_inter_pred_filters.h"
80*495ae853SAndroid Build Coastguard Worker #include "ih264_intra_pred_filters.h"
81*495ae853SAndroid Build Coastguard Worker #include "ih264_deblk_edge_filters.h"
82*495ae853SAndroid Build Coastguard Worker #include "ih264_common_tables.h"
83*495ae853SAndroid Build Coastguard Worker #include "ih264_trans_data.h"
84*495ae853SAndroid Build Coastguard Worker #include "ih264_cavlc_tables.h"
85*495ae853SAndroid Build Coastguard Worker #include "ih264_cabac_tables.h"
86*495ae853SAndroid Build Coastguard Worker #include "ih264_buf_mgr.h"
87*495ae853SAndroid Build Coastguard Worker #include "ih264_list.h"
88*495ae853SAndroid Build Coastguard Worker #include "ih264_dpb_mgr.h"
89*495ae853SAndroid Build Coastguard Worker 
90*495ae853SAndroid Build Coastguard Worker #include "ime_defs.h"
91*495ae853SAndroid Build Coastguard Worker #include "ime_distortion_metrics.h"
92*495ae853SAndroid Build Coastguard Worker #include "ime_structs.h"
93*495ae853SAndroid Build Coastguard Worker #include "ime.h"
94*495ae853SAndroid Build Coastguard Worker #include "ime_statistics.h"
95*495ae853SAndroid Build Coastguard Worker 
96*495ae853SAndroid Build Coastguard Worker #include "irc_mem_req_and_acq.h"
97*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
98*495ae853SAndroid Build Coastguard Worker #include "irc_frame_info_collector.h"
99*495ae853SAndroid Build Coastguard Worker #include "irc_rate_control_api.h"
100*495ae853SAndroid Build Coastguard Worker 
101*495ae853SAndroid Build Coastguard Worker #include "psnr.h"
102*495ae853SAndroid Build Coastguard Worker 
103*495ae853SAndroid Build Coastguard Worker #include "ih264e.h"
104*495ae853SAndroid Build Coastguard Worker #include "ih264e_error.h"
105*495ae853SAndroid Build Coastguard Worker #include "ih264e_version.h"
106*495ae853SAndroid Build Coastguard Worker #include "ih264e_defs.h"
107*495ae853SAndroid Build Coastguard Worker #include "ih264e_globals.h"
108*495ae853SAndroid Build Coastguard Worker #include "ih264e_time_stamp.h"
109*495ae853SAndroid Build Coastguard Worker #include "ih264e_modify_frm_rate.h"
110*495ae853SAndroid Build Coastguard Worker #include "ih264e_rate_control.h"
111*495ae853SAndroid Build Coastguard Worker #include "ih264e_bitstream.h"
112*495ae853SAndroid Build Coastguard Worker #include "ih264e_cabac_structs.h"
113*495ae853SAndroid Build Coastguard Worker #include "ih264e_structs.h"
114*495ae853SAndroid Build Coastguard Worker #include "ih264e_me.h"
115*495ae853SAndroid Build Coastguard Worker #include "ih264e_utils.h"
116*495ae853SAndroid Build Coastguard Worker #include "ih264e_core_coding.h"
117*495ae853SAndroid Build Coastguard Worker #include "ih264e_encode_header.h"
118*495ae853SAndroid Build Coastguard Worker #include "ih264e_cavlc.h"
119*495ae853SAndroid Build Coastguard Worker #include "ih264e_cabac.h"
120*495ae853SAndroid Build Coastguard Worker #include "ih264e_master.h"
121*495ae853SAndroid Build Coastguard Worker #include "ih264e_process.h"
122*495ae853SAndroid Build Coastguard Worker #include "ih264e_fmt_conv.h"
123*495ae853SAndroid Build Coastguard Worker #include "ih264e_statistics.h"
124*495ae853SAndroid Build Coastguard Worker #include "ih264e_trace.h"
125*495ae853SAndroid Build Coastguard Worker 
126*495ae853SAndroid Build Coastguard Worker 
127*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
128*495ae853SAndroid Build Coastguard Worker /* Function Definitions                                                      */
129*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
130*495ae853SAndroid Build Coastguard Worker 
131*495ae853SAndroid Build Coastguard Worker /**
132*495ae853SAndroid Build Coastguard Worker *******************************************************************************
133*495ae853SAndroid Build Coastguard Worker *
134*495ae853SAndroid Build Coastguard Worker * @brief
135*495ae853SAndroid Build Coastguard Worker *  Queues the current buffer, gets back a another buffer for encoding with
136*495ae853SAndroid Build Coastguard Worker *  current picture type
137*495ae853SAndroid Build Coastguard Worker *
138*495ae853SAndroid Build Coastguard Worker * @par Description:
139*495ae853SAndroid Build Coastguard Worker *  This function performs 3 distinct but related functions.
140*495ae853SAndroid Build Coastguard Worker *  1) Maintains an input queue [Note the the term queue do not imply a first-in
141*495ae853SAndroid Build Coastguard Worker *  first-out logic here] that queues input and dequeues them so that input
142*495ae853SAndroid Build Coastguard Worker *  frames can be encoded at any predetermined encoding order
143*495ae853SAndroid Build Coastguard Worker *  2) Uses RC library to decide which frame must be encoded in current pass
144*495ae853SAndroid Build Coastguard Worker *  and which picture type it must be encoded to.
145*495ae853SAndroid Build Coastguard Worker *  3) Uses RC library to decide the QP at which current frame has to be encoded
146*495ae853SAndroid Build Coastguard Worker *  4) Determines if the current picture must be encoded or not based on PRE-ENC
147*495ae853SAndroid Build Coastguard Worker *  skip
148*495ae853SAndroid Build Coastguard Worker *
149*495ae853SAndroid Build Coastguard Worker *  Input queue is used for storing input buffers till they are used for
150*495ae853SAndroid Build Coastguard Worker *  encoding. This queue is maintained at ps_codec->as_inp_list. Whenever a
151*495ae853SAndroid Build Coastguard Worker *  valid input comes, it is added to the end of queue. This same input is
152*495ae853SAndroid Build Coastguard Worker *  added to RC queue using the identifier as ps_codec->i4_pic_cnt. Hence any
153*495ae853SAndroid Build Coastguard Worker *  pic from RC can be located in the input queue easily.
154*495ae853SAndroid Build Coastguard Worker *
155*495ae853SAndroid Build Coastguard Worker *  The dequeue operation does not start till we have ps_codec->s_cfg.u4_max_num_bframes
156*495ae853SAndroid Build Coastguard Worker *  frames in the queue. This is done in order to ensure that once output
157*495ae853SAndroid Build Coastguard Worker *  starts we will have a constant stream of output with no gaps.
158*495ae853SAndroid Build Coastguard Worker *
159*495ae853SAndroid Build Coastguard Worker *  The output frame order is governed by RC library. When ever we dequeue a
160*495ae853SAndroid Build Coastguard Worker *  buffer from RC library, it ensures that we will get them in encoding order
161*495ae853SAndroid Build Coastguard Worker *  With the output of RC library, we can use the picture id to dequeue the
162*495ae853SAndroid Build Coastguard Worker *  corresponding buffer from input queue and encode it.
163*495ae853SAndroid Build Coastguard Worker *
164*495ae853SAndroid Build Coastguard Worker *  Condition at the end of stream:
165*495ae853SAndroid Build Coastguard Worker *  -------------------------------
166*495ae853SAndroid Build Coastguard Worker *  At the last valid buffer from the app, we will get ps_ive_ip->u4_is_last
167*495ae853SAndroid Build Coastguard Worker *  to be set. This will the given to lib when appropriate input buffer is
168*495ae853SAndroid Build Coastguard Worker *  given to encoding.
169*495ae853SAndroid Build Coastguard Worker *
170*495ae853SAndroid Build Coastguard Worker *  Since we have to output is not in sync with input, we will have frames to
171*495ae853SAndroid Build Coastguard Worker *  encode even after we receive the last valid input buffer. Hence we have to
172*495ae853SAndroid Build Coastguard Worker *  make sure that we do not queue any new buffers once we get the flag [It may
173*495ae853SAndroid Build Coastguard Worker *  mess up GOP ?]. This is achieved by setting ps_codec->i4_last_inp_buff_received
174*495ae853SAndroid Build Coastguard Worker *  to act as a permanent marker for last frame received [This may not be needed,
175*495ae853SAndroid Build Coastguard Worker *  because in our current app, all buffers after the last are marked as last.
176*495ae853SAndroid Build Coastguard Worker *  But can we rely on that?] . Hence after this flag is set no new buffers are
177*495ae853SAndroid Build Coastguard Worker *  queued.
178*495ae853SAndroid Build Coastguard Worker *
179*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
180*495ae853SAndroid Build Coastguard Worker *  Pointer to codec descriptor
181*495ae853SAndroid Build Coastguard Worker *
182*495ae853SAndroid Build Coastguard Worker * @param[in] ps_ive_ip
183*495ae853SAndroid Build Coastguard Worker *  Current input buffer to the encoder
184*495ae853SAndroid Build Coastguard Worker *
185*495ae853SAndroid Build Coastguard Worker * @param[out] ps_inp
186*495ae853SAndroid Build Coastguard Worker *  Buffer to be encoded in the current pass
187*495ae853SAndroid Build Coastguard Worker *
188*495ae853SAndroid Build Coastguard Worker * @returns
189*495ae853SAndroid Build Coastguard Worker *  Flag indicating if we have a pre-enc skip or not
190*495ae853SAndroid Build Coastguard Worker *
191*495ae853SAndroid Build Coastguard Worker * @remarks
192*495ae853SAndroid Build Coastguard Worker *  TODO (bpic) : The check for null and is last is redundant. Need to see if we
193*495ae853SAndroid Build Coastguard Worker *  can remove it
194*495ae853SAndroid Build Coastguard Worker *
195*495ae853SAndroid Build Coastguard Worker *******************************************************************************
196*495ae853SAndroid Build Coastguard Worker */
ih264e_input_queue_update(codec_t * ps_codec,ive_video_encode_ip_t * ps_ive_ip,inp_buf_t * ps_enc_buff)197*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_input_queue_update(codec_t *ps_codec,
198*495ae853SAndroid Build Coastguard Worker                                  ive_video_encode_ip_t *ps_ive_ip,
199*495ae853SAndroid Build Coastguard Worker                                  inp_buf_t *ps_enc_buff)
200*495ae853SAndroid Build Coastguard Worker {
201*495ae853SAndroid Build Coastguard Worker 
202*495ae853SAndroid Build Coastguard Worker     inp_buf_t *ps_inp_buf;
203*495ae853SAndroid Build Coastguard Worker     picture_type_e e_pictype;
204*495ae853SAndroid Build Coastguard Worker     WORD32 i4_skip;
205*495ae853SAndroid Build Coastguard Worker     UWORD32 ctxt_sel, u4_pic_id, u4_pic_disp_id;
206*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_frame_qp, i;
207*495ae853SAndroid Build Coastguard Worker     UWORD32 max_frame_bits = 0x7FFFFFFF;
208*495ae853SAndroid Build Coastguard Worker 
209*495ae853SAndroid Build Coastguard Worker     /*  Mark that the last input frame has been received */
210*495ae853SAndroid Build Coastguard Worker     if (ps_ive_ip->u4_is_last == 1)
211*495ae853SAndroid Build Coastguard Worker     {
212*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_last_inp_buff_received = 1;
213*495ae853SAndroid Build Coastguard Worker     }
214*495ae853SAndroid Build Coastguard Worker 
215*495ae853SAndroid Build Coastguard Worker     if (ps_ive_ip->s_inp_buf.apv_bufs[0] == NULL
216*495ae853SAndroid Build Coastguard Worker                     && !ps_codec->i4_last_inp_buff_received)
217*495ae853SAndroid Build Coastguard Worker     {
218*495ae853SAndroid Build Coastguard Worker         ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
219*495ae853SAndroid Build Coastguard Worker         ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last;
220*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_pic_cnt -= 1;
221*495ae853SAndroid Build Coastguard Worker         return 0;
222*495ae853SAndroid Build Coastguard Worker     }
223*495ae853SAndroid Build Coastguard Worker 
224*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
225*495ae853SAndroid Build Coastguard Worker      * Check for pre enc skip
226*495ae853SAndroid Build Coastguard Worker      *   When src and target frame rates donot match, we skip some frames to
227*495ae853SAndroid Build Coastguard Worker      *   maintain the relation ship between them
228*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
229*495ae853SAndroid Build Coastguard Worker     {
230*495ae853SAndroid Build Coastguard Worker         WORD32 skip_src;
231*495ae853SAndroid Build Coastguard Worker 
232*495ae853SAndroid Build Coastguard Worker         skip_src = ih264e_update_rc_framerates(
233*495ae853SAndroid Build Coastguard Worker                         ps_codec->s_rate_control.pps_rate_control_api,
234*495ae853SAndroid Build Coastguard Worker                         ps_codec->s_rate_control.pps_pd_frm_rate,
235*495ae853SAndroid Build Coastguard Worker                         ps_codec->s_rate_control.pps_time_stamp,
236*495ae853SAndroid Build Coastguard Worker                         ps_codec->s_rate_control.pps_frame_time);
237*495ae853SAndroid Build Coastguard Worker 
238*495ae853SAndroid Build Coastguard Worker         if (skip_src)
239*495ae853SAndroid Build Coastguard Worker         {
240*495ae853SAndroid Build Coastguard Worker             ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last;
241*495ae853SAndroid Build Coastguard Worker             ps_codec->i4_pic_cnt -= 1;
242*495ae853SAndroid Build Coastguard Worker             return 1;
243*495ae853SAndroid Build Coastguard Worker         }
244*495ae853SAndroid Build Coastguard Worker     }
245*495ae853SAndroid Build Coastguard Worker 
246*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
247*495ae853SAndroid Build Coastguard Worker      * Queue the input to the queue
248*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
249*495ae853SAndroid Build Coastguard Worker     ps_inp_buf = &(ps_codec->as_inp_list[ps_codec->i4_pic_cnt
250*495ae853SAndroid Build Coastguard Worker                                          % MAX_NUM_INP_FRAMES]);
251*495ae853SAndroid Build Coastguard Worker 
252*495ae853SAndroid Build Coastguard Worker     /* copy input info. to internal structure */
253*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->s_raw_buf = ps_ive_ip->s_inp_buf;
254*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->u4_timestamp_low = ps_ive_ip->u4_timestamp_low;
255*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->u4_timestamp_high = ps_ive_ip->u4_timestamp_high;
256*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->u4_is_last = ps_ive_ip->u4_is_last;
257*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->pv_mb_info = ps_ive_ip->pv_mb_info;
258*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->u4_mb_info_type = ps_ive_ip->u4_mb_info_type;
259*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->pv_pic_info = ps_ive_ip->pv_pic_info;
260*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->u4_pic_info_type = ps_ive_ip->u4_pic_info_type;
261*495ae853SAndroid Build Coastguard Worker 
262*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->u1_sei_ccv_params_present_flag =
263*495ae853SAndroid Build Coastguard Worker                 ps_codec->s_cfg.s_sei.u1_sei_ccv_params_present_flag;
264*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->s_sei_ccv = ps_codec->s_cfg.s_sei.s_sei_ccv_params;
265*495ae853SAndroid Build Coastguard Worker 
266*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->u1_sei_sii_params_present_flag =
267*495ae853SAndroid Build Coastguard Worker         ps_codec->s_cfg.s_sei.u1_sei_sii_params_present_flag;
268*495ae853SAndroid Build Coastguard Worker     ps_inp_buf->s_sei_sii = ps_codec->s_cfg.s_sei.s_sei_sii_params;
269*495ae853SAndroid Build Coastguard Worker 
270*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
271*495ae853SAndroid Build Coastguard Worker      * Now we should add the picture to RC stack here
272*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
273*495ae853SAndroid Build Coastguard Worker     /*
274*495ae853SAndroid Build Coastguard Worker      * If an I frame has been requested, ask  RC to force it
275*495ae853SAndroid Build Coastguard Worker      * For IDR requests, we have to ask RC to force I and set IDR by our selves
276*495ae853SAndroid Build Coastguard Worker      * since RC Donot know about IDR. For forcing an IDR at dequeue stage we
277*495ae853SAndroid Build Coastguard Worker      * should record that an IDR has been requested some where. Hence we will
278*495ae853SAndroid Build Coastguard Worker      * store it in the u4_idr_inp_list at a position same as that of input frame
279*495ae853SAndroid Build Coastguard Worker      */
280*495ae853SAndroid Build Coastguard Worker     {
281*495ae853SAndroid Build Coastguard Worker         WORD32 i4_force_idr, i4_force_i;
282*495ae853SAndroid Build Coastguard Worker 
283*495ae853SAndroid Build Coastguard Worker         i4_force_idr = (ps_codec->force_curr_frame_type == IV_IDR_FRAME);
284*495ae853SAndroid Build Coastguard Worker         i4_force_idr |= !(ps_codec->i4_pic_cnt % ps_codec->s_cfg.u4_idr_frm_interval);
285*495ae853SAndroid Build Coastguard Worker 
286*495ae853SAndroid Build Coastguard Worker         i4_force_i = (ps_codec->force_curr_frame_type == IV_I_FRAME);
287*495ae853SAndroid Build Coastguard Worker 
288*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_pending_idr_flag |= i4_force_idr;
289*495ae853SAndroid Build Coastguard Worker 
290*495ae853SAndroid Build Coastguard Worker         if ((ps_codec->i4_pic_cnt > 0) && (i4_force_idr || i4_force_i))
291*495ae853SAndroid Build Coastguard Worker         {
292*495ae853SAndroid Build Coastguard Worker             irc_force_I_frame(ps_codec->s_rate_control.pps_rate_control_api);
293*495ae853SAndroid Build Coastguard Worker         }
294*495ae853SAndroid Build Coastguard Worker         ps_codec->force_curr_frame_type = IV_NA_FRAME;
295*495ae853SAndroid Build Coastguard Worker     }
296*495ae853SAndroid Build Coastguard Worker 
297*495ae853SAndroid Build Coastguard Worker     irc_add_picture_to_stack(ps_codec->s_rate_control.pps_rate_control_api,
298*495ae853SAndroid Build Coastguard Worker                              ps_codec->i4_pic_cnt);
299*495ae853SAndroid Build Coastguard Worker 
300*495ae853SAndroid Build Coastguard Worker 
301*495ae853SAndroid Build Coastguard Worker     /* Delay */
302*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_pic_cnt < (WORD32)(ps_codec->s_cfg.u4_num_bframes))
303*495ae853SAndroid Build Coastguard Worker     {
304*495ae853SAndroid Build Coastguard Worker         ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
305*495ae853SAndroid Build Coastguard Worker         ps_enc_buff->u4_is_last = 0;
306*495ae853SAndroid Build Coastguard Worker         return 0;
307*495ae853SAndroid Build Coastguard Worker     }
308*495ae853SAndroid Build Coastguard Worker 
309*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
310*495ae853SAndroid Build Coastguard Worker      * Get a new pic to encode
311*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
312*495ae853SAndroid Build Coastguard Worker     /* Query the picture_type */
313*495ae853SAndroid Build Coastguard Worker     e_pictype = ih264e_rc_get_picture_details(
314*495ae853SAndroid Build Coastguard Worker                     ps_codec->s_rate_control.pps_rate_control_api, (WORD32 *)(&u4_pic_id),
315*495ae853SAndroid Build Coastguard Worker                     (WORD32 *)(&u4_pic_disp_id));
316*495ae853SAndroid Build Coastguard Worker 
317*495ae853SAndroid Build Coastguard Worker     switch (e_pictype)
318*495ae853SAndroid Build Coastguard Worker     {
319*495ae853SAndroid Build Coastguard Worker         case I_PIC:
320*495ae853SAndroid Build Coastguard Worker             ps_codec->pic_type = PIC_I;
321*495ae853SAndroid Build Coastguard Worker             break;
322*495ae853SAndroid Build Coastguard Worker         case P_PIC:
323*495ae853SAndroid Build Coastguard Worker             ps_codec->pic_type = PIC_P;
324*495ae853SAndroid Build Coastguard Worker             break;
325*495ae853SAndroid Build Coastguard Worker         case B_PIC:
326*495ae853SAndroid Build Coastguard Worker             ps_codec->pic_type = PIC_B;
327*495ae853SAndroid Build Coastguard Worker             break;
328*495ae853SAndroid Build Coastguard Worker         default:
329*495ae853SAndroid Build Coastguard Worker             ps_codec->pic_type = PIC_NA;
330*495ae853SAndroid Build Coastguard Worker             ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
331*495ae853SAndroid Build Coastguard Worker             return 0;
332*495ae853SAndroid Build Coastguard Worker     }
333*495ae853SAndroid Build Coastguard Worker 
334*495ae853SAndroid Build Coastguard Worker     /* Set IDR if it has been requested */
335*495ae853SAndroid Build Coastguard Worker     if (ps_codec->pic_type == PIC_I)
336*495ae853SAndroid Build Coastguard Worker     {
337*495ae853SAndroid Build Coastguard Worker         ps_codec->pic_type = ps_codec->i4_pending_idr_flag ?
338*495ae853SAndroid Build Coastguard Worker                                     PIC_IDR : ps_codec->pic_type;
339*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_pending_idr_flag = 0;
340*495ae853SAndroid Build Coastguard Worker     }
341*495ae853SAndroid Build Coastguard Worker 
342*495ae853SAndroid Build Coastguard Worker     /* Get current frame Qp */
343*495ae853SAndroid Build Coastguard Worker     u1_frame_qp = (UWORD8)irc_get_frame_level_qp(
344*495ae853SAndroid Build Coastguard Worker                     ps_codec->s_rate_control.pps_rate_control_api, e_pictype,
345*495ae853SAndroid Build Coastguard Worker                     max_frame_bits);
346*495ae853SAndroid Build Coastguard Worker     ps_codec->u4_frame_qp = gau1_mpeg2_to_h264_qmap[u1_frame_qp];
347*495ae853SAndroid Build Coastguard Worker 
348*495ae853SAndroid Build Coastguard Worker     /*
349*495ae853SAndroid Build Coastguard Worker      * copy the pic id to poc because the display order is assumed to be same
350*495ae853SAndroid Build Coastguard Worker      * as input order
351*495ae853SAndroid Build Coastguard Worker      */
352*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_poc = u4_pic_id;
353*495ae853SAndroid Build Coastguard Worker 
354*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
355*495ae853SAndroid Build Coastguard Worker      * Now retrieve the correct picture from the queue
356*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
357*495ae853SAndroid Build Coastguard Worker     /* Mark the skip flag   */
358*495ae853SAndroid Build Coastguard Worker     i4_skip = 0;
359*495ae853SAndroid Build Coastguard Worker     ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
360*495ae853SAndroid Build Coastguard Worker     ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = i4_skip;
361*495ae853SAndroid Build Coastguard Worker 
362*495ae853SAndroid Build Coastguard Worker     /* Get a buffer to encode */
363*495ae853SAndroid Build Coastguard Worker     ps_inp_buf = &(ps_codec->as_inp_list[u4_pic_id % MAX_NUM_INP_FRAMES]);
364*495ae853SAndroid Build Coastguard Worker 
365*495ae853SAndroid Build Coastguard Worker     /* copy dequeued input to output */
366*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->s_raw_buf = ps_inp_buf->s_raw_buf;
367*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
368*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
369*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->u4_is_last = ps_inp_buf->u4_is_last;
370*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->pv_mb_info = ps_inp_buf->pv_mb_info;
371*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->u4_mb_info_type = ps_inp_buf->u4_mb_info_type;
372*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->pv_pic_info = ps_inp_buf->pv_pic_info;
373*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->u4_pic_info_type = ps_inp_buf->u4_pic_info_type;
374*495ae853SAndroid Build Coastguard Worker 
375*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->u1_sei_ccv_params_present_flag = ps_inp_buf->u1_sei_ccv_params_present_flag;
376*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->s_sei_ccv = ps_inp_buf->s_sei_ccv;
377*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->u1_sei_sii_params_present_flag = ps_inp_buf->u1_sei_sii_params_present_flag;
378*495ae853SAndroid Build Coastguard Worker     ps_enc_buff->s_sei_sii = ps_inp_buf->s_sei_sii;
379*495ae853SAndroid Build Coastguard Worker 
380*495ae853SAndroid Build Coastguard Worker     /* Special case for encoding trailing B frames
381*495ae853SAndroid Build Coastguard Worker      *
382*495ae853SAndroid Build Coastguard Worker      * In encoding streams with B frames it may happen that we have a B frame
383*495ae853SAndroid Build Coastguard Worker      * at the end without a P/I frame after it. Hence when we are dequeing from
384*495ae853SAndroid Build Coastguard Worker      * the RC, it will return the P frame [next in display order but before in
385*495ae853SAndroid Build Coastguard Worker      * encoding order] first. Since the dequeue happens for an invalid frame we
386*495ae853SAndroid Build Coastguard Worker      * will get a frame with null buff and set u4_is_last. Hence lib with return
387*495ae853SAndroid Build Coastguard Worker      * last frame flag at this point and will stop encoding.
388*495ae853SAndroid Build Coastguard Worker      *
389*495ae853SAndroid Build Coastguard Worker      * Since for the last B frame, we does not have the forward ref frame
390*495ae853SAndroid Build Coastguard Worker      * it makes sense to force it into P.
391*495ae853SAndroid Build Coastguard Worker      *
392*495ae853SAndroid Build Coastguard Worker      * To solve this, in case the current frame is P and if the last frame flag
393*495ae853SAndroid Build Coastguard Worker      * is set, we need to see if there is and pending B frames. If there are any,
394*495ae853SAndroid Build Coastguard Worker      * we should just encode that picture as the current P frame and set
395*495ae853SAndroid Build Coastguard Worker      * that B frame as the last frame. Hence the encoder will terminate naturally
396*495ae853SAndroid Build Coastguard Worker      * once that B-frame is encoded after all the in between frames.
397*495ae853SAndroid Build Coastguard Worker      *
398*495ae853SAndroid Build Coastguard Worker      * Since we cannot touch RC stack directly, the option of actually swapping
399*495ae853SAndroid Build Coastguard Worker      * frames in RC is ruled out. We have to modify the as_inp_list to simulate
400*495ae853SAndroid Build Coastguard Worker      * such a behavior by RC. We can do that by
401*495ae853SAndroid Build Coastguard Worker      *  1) Search through as_inp_list to locate the largest u4_timestamp_low less
402*495ae853SAndroid Build Coastguard Worker      *     than current u4_timestamp_low. This will give us the last B frame before
403*495ae853SAndroid Build Coastguard Worker      *     the current P frame. Note that this will handle pre encode skip too since
404*495ae853SAndroid Build Coastguard Worker      *     queue happens after pre enc skip.
405*495ae853SAndroid Build Coastguard Worker      *  2) Swap the position in as_inp_list. Hence now the last B frame is
406*495ae853SAndroid Build Coastguard Worker      *     encoded as P frame. And the new last B frame will have u4_is_last
407*495ae853SAndroid Build Coastguard Worker      *     set so that encoder will end naturally once we reached that B frame
408*495ae853SAndroid Build Coastguard Worker      *     or any subsequent frame. Also the current GOP will have 1 less B frame
409*495ae853SAndroid Build Coastguard Worker      *     Since we are swapping, the poc will also be in-order.
410*495ae853SAndroid Build Coastguard Worker      *  3) In case we have an IPP stream, the result of our search will be an
411*495ae853SAndroid Build Coastguard Worker      *     I/P frame which is already encoded. Thus swap and encode will result
412*495ae853SAndroid Build Coastguard Worker      *     in encoding of duplicate frames. Hence to avoid this we will only
413*495ae853SAndroid Build Coastguard Worker      *     have this work around in case of u4_num_bframes > 0.
414*495ae853SAndroid Build Coastguard Worker      *
415*495ae853SAndroid Build Coastguard Worker      *     In case we have forced an I/IDR frame In between this P frame and
416*495ae853SAndroid Build Coastguard Worker      *     the last B frame -> This cannot happen as the current P frame is
417*495ae853SAndroid Build Coastguard Worker      *     supposed to have u4_is_last set. Thus forcing an I/ IDR after this
418*495ae853SAndroid Build Coastguard Worker      *     is illogical.
419*495ae853SAndroid Build Coastguard Worker      *
420*495ae853SAndroid Build Coastguard Worker      *     In cae if we have forced an I such that the frame just before last frame
421*495ae853SAndroid Build Coastguard Worker      *     in is I/P -> This case will never arise. Since we have a closed GOP now,
422*495ae853SAndroid Build Coastguard Worker      *     once we force an I, the gop gets reset, hence there will be a B between
423*495ae853SAndroid Build Coastguard Worker      *     I/P and I/P.
424*495ae853SAndroid Build Coastguard Worker      */
425*495ae853SAndroid Build Coastguard Worker     if (ps_enc_buff->u4_is_last && (ps_codec->pic_type == PIC_P)
426*495ae853SAndroid Build Coastguard Worker                     && ps_codec->s_cfg.u4_num_bframes)
427*495ae853SAndroid Build Coastguard Worker     {
428*495ae853SAndroid Build Coastguard Worker         WORD32 cntr;
429*495ae853SAndroid Build Coastguard Worker         WORD32 lst_bframe = -1;
430*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_timestamp_low = 0;
431*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_timestamp_high = 0;
432*495ae853SAndroid Build Coastguard Worker         inp_buf_t *ps_swap_buff, *ps_inp_list;
433*495ae853SAndroid Build Coastguard Worker 
434*495ae853SAndroid Build Coastguard Worker         ps_inp_list = &ps_codec->as_inp_list[0];
435*495ae853SAndroid Build Coastguard Worker 
436*495ae853SAndroid Build Coastguard Worker         /* Now search the inp list for highest timestamp */
437*495ae853SAndroid Build Coastguard Worker         for(cntr = 0; cntr < MAX_NUM_INP_FRAMES; cntr++)
438*495ae853SAndroid Build Coastguard Worker         {
439*495ae853SAndroid Build Coastguard Worker             if(ps_inp_list[cntr].s_raw_buf.apv_bufs[0] != NULL)
440*495ae853SAndroid Build Coastguard Worker             {
441*495ae853SAndroid Build Coastguard Worker                 if ((ps_inp_list[cntr].u4_timestamp_high  > u4_timestamp_high) ||
442*495ae853SAndroid Build Coastguard Worker                     (ps_inp_list[cntr].u4_timestamp_high  == u4_timestamp_high &&
443*495ae853SAndroid Build Coastguard Worker                      ps_inp_list[cntr].u4_timestamp_low  > u4_timestamp_low))
444*495ae853SAndroid Build Coastguard Worker                 {
445*495ae853SAndroid Build Coastguard Worker                     u4_timestamp_low = ps_inp_list[cntr].u4_timestamp_low;
446*495ae853SAndroid Build Coastguard Worker                     u4_timestamp_high = ps_inp_list[cntr].u4_timestamp_high;
447*495ae853SAndroid Build Coastguard Worker                     lst_bframe = cntr;
448*495ae853SAndroid Build Coastguard Worker                 }
449*495ae853SAndroid Build Coastguard Worker             }
450*495ae853SAndroid Build Coastguard Worker         }
451*495ae853SAndroid Build Coastguard Worker 
452*495ae853SAndroid Build Coastguard Worker         if(lst_bframe != -1)
453*495ae853SAndroid Build Coastguard Worker         {
454*495ae853SAndroid Build Coastguard Worker             ps_swap_buff = &(ps_codec->as_inp_list[lst_bframe]);
455*495ae853SAndroid Build Coastguard Worker 
456*495ae853SAndroid Build Coastguard Worker             /* copy the last B buffer to output */
457*495ae853SAndroid Build Coastguard Worker             *ps_enc_buff = *ps_swap_buff;
458*495ae853SAndroid Build Coastguard Worker 
459*495ae853SAndroid Build Coastguard Worker             /* Store the current buf into the queue in place of last B buf */
460*495ae853SAndroid Build Coastguard Worker             *ps_swap_buff = *ps_inp_buf;
461*495ae853SAndroid Build Coastguard Worker         }
462*495ae853SAndroid Build Coastguard Worker     }
463*495ae853SAndroid Build Coastguard Worker 
464*495ae853SAndroid Build Coastguard Worker     /* The buffer in the queue is set to NULL to specify that encoding is done for that frame */
465*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < 3; i++)
466*495ae853SAndroid Build Coastguard Worker     {
467*495ae853SAndroid Build Coastguard Worker         ps_inp_buf->s_raw_buf.apv_bufs[i] = NULL;
468*495ae853SAndroid Build Coastguard Worker     }
469*495ae853SAndroid Build Coastguard Worker 
470*495ae853SAndroid Build Coastguard Worker     /* Return the buffer status */
471*495ae853SAndroid Build Coastguard Worker     return (0);
472*495ae853SAndroid Build Coastguard Worker }
473*495ae853SAndroid Build Coastguard Worker 
474*495ae853SAndroid Build Coastguard Worker /**
475*495ae853SAndroid Build Coastguard Worker *******************************************************************************
476*495ae853SAndroid Build Coastguard Worker *
477*495ae853SAndroid Build Coastguard Worker * @brief
478*495ae853SAndroid Build Coastguard Worker *  Used to get minimum level index for a given picture size
479*495ae853SAndroid Build Coastguard Worker *
480*495ae853SAndroid Build Coastguard Worker * @par Description:
481*495ae853SAndroid Build Coastguard Worker *  Gets the minimum level index and then gets corresponding level.
482*495ae853SAndroid Build Coastguard Worker *  Also used to ignore invalid levels like 2.3, 3.3 etc
483*495ae853SAndroid Build Coastguard Worker *
484*495ae853SAndroid Build Coastguard Worker * @param[in] level
485*495ae853SAndroid Build Coastguard Worker *  Level of the stream
486*495ae853SAndroid Build Coastguard Worker *
487*495ae853SAndroid Build Coastguard Worker * @returns  Level index for a given level
488*495ae853SAndroid Build Coastguard Worker *
489*495ae853SAndroid Build Coastguard Worker * @remarks
490*495ae853SAndroid Build Coastguard Worker *
491*495ae853SAndroid Build Coastguard Worker *******************************************************************************
492*495ae853SAndroid Build Coastguard Worker */
ih264e_get_min_level(WORD32 wd,WORD32 ht)493*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_get_min_level(WORD32 wd, WORD32 ht)
494*495ae853SAndroid Build Coastguard Worker {
495*495ae853SAndroid Build Coastguard Worker     WORD32 lvl_idx = MAX_LEVEL, i;
496*495ae853SAndroid Build Coastguard Worker     WORD32 pic_size = wd * ht;
497*495ae853SAndroid Build Coastguard Worker     WORD32 max = MAX(wd, ht);
498*495ae853SAndroid Build Coastguard Worker 
499*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < MAX_LEVEL; i++)
500*495ae853SAndroid Build Coastguard Worker     {
501*495ae853SAndroid Build Coastguard Worker         if ((pic_size <= gai4_ih264_max_luma_pic_size[i]) &&
502*495ae853SAndroid Build Coastguard Worker             (max <= gai4_ih264_max_wd_ht[i]))
503*495ae853SAndroid Build Coastguard Worker         {
504*495ae853SAndroid Build Coastguard Worker             lvl_idx = i;
505*495ae853SAndroid Build Coastguard Worker             break;
506*495ae853SAndroid Build Coastguard Worker         }
507*495ae853SAndroid Build Coastguard Worker     }
508*495ae853SAndroid Build Coastguard Worker     return gai4_ih264_levels[lvl_idx];
509*495ae853SAndroid Build Coastguard Worker }
510*495ae853SAndroid Build Coastguard Worker 
511*495ae853SAndroid Build Coastguard Worker /**
512*495ae853SAndroid Build Coastguard Worker *******************************************************************************
513*495ae853SAndroid Build Coastguard Worker *
514*495ae853SAndroid Build Coastguard Worker * @brief
515*495ae853SAndroid Build Coastguard Worker *  Used to get level index for a given level
516*495ae853SAndroid Build Coastguard Worker *
517*495ae853SAndroid Build Coastguard Worker * @par Description:
518*495ae853SAndroid Build Coastguard Worker *  Converts from level_idc (which is multiplied by 30) to an index that can be
519*495ae853SAndroid Build Coastguard Worker *  used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
520*495ae853SAndroid Build Coastguard Worker *
521*495ae853SAndroid Build Coastguard Worker * @param[in] level
522*495ae853SAndroid Build Coastguard Worker *  Level of the stream
523*495ae853SAndroid Build Coastguard Worker *
524*495ae853SAndroid Build Coastguard Worker * @returns  Level index for a given level
525*495ae853SAndroid Build Coastguard Worker *
526*495ae853SAndroid Build Coastguard Worker * @remarks
527*495ae853SAndroid Build Coastguard Worker *
528*495ae853SAndroid Build Coastguard Worker *******************************************************************************
529*495ae853SAndroid Build Coastguard Worker */
ih264e_get_lvl_idx(WORD32 level)530*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_get_lvl_idx(WORD32 level)
531*495ae853SAndroid Build Coastguard Worker {
532*495ae853SAndroid Build Coastguard Worker     WORD32 lvl_idx = 0;
533*495ae853SAndroid Build Coastguard Worker 
534*495ae853SAndroid Build Coastguard Worker     if (level < IH264_LEVEL_11)
535*495ae853SAndroid Build Coastguard Worker     {
536*495ae853SAndroid Build Coastguard Worker         lvl_idx = 0;
537*495ae853SAndroid Build Coastguard Worker     }
538*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_12)
539*495ae853SAndroid Build Coastguard Worker     {
540*495ae853SAndroid Build Coastguard Worker         lvl_idx = 1;
541*495ae853SAndroid Build Coastguard Worker     }
542*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_13)
543*495ae853SAndroid Build Coastguard Worker     {
544*495ae853SAndroid Build Coastguard Worker         lvl_idx = 2;
545*495ae853SAndroid Build Coastguard Worker     }
546*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_20)
547*495ae853SAndroid Build Coastguard Worker     {
548*495ae853SAndroid Build Coastguard Worker         lvl_idx = 3;
549*495ae853SAndroid Build Coastguard Worker     }
550*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_21)
551*495ae853SAndroid Build Coastguard Worker     {
552*495ae853SAndroid Build Coastguard Worker         lvl_idx = 4;
553*495ae853SAndroid Build Coastguard Worker     }
554*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_22)
555*495ae853SAndroid Build Coastguard Worker     {
556*495ae853SAndroid Build Coastguard Worker         lvl_idx = 5;
557*495ae853SAndroid Build Coastguard Worker     }
558*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_30)
559*495ae853SAndroid Build Coastguard Worker     {
560*495ae853SAndroid Build Coastguard Worker         lvl_idx = 6;
561*495ae853SAndroid Build Coastguard Worker     }
562*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_31)
563*495ae853SAndroid Build Coastguard Worker     {
564*495ae853SAndroid Build Coastguard Worker         lvl_idx = 7;
565*495ae853SAndroid Build Coastguard Worker     }
566*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_32)
567*495ae853SAndroid Build Coastguard Worker     {
568*495ae853SAndroid Build Coastguard Worker         lvl_idx = 8;
569*495ae853SAndroid Build Coastguard Worker     }
570*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_40)
571*495ae853SAndroid Build Coastguard Worker     {
572*495ae853SAndroid Build Coastguard Worker         lvl_idx = 9;
573*495ae853SAndroid Build Coastguard Worker     }
574*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_41)
575*495ae853SAndroid Build Coastguard Worker     {
576*495ae853SAndroid Build Coastguard Worker         lvl_idx = 10;
577*495ae853SAndroid Build Coastguard Worker     }
578*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_42)
579*495ae853SAndroid Build Coastguard Worker     {
580*495ae853SAndroid Build Coastguard Worker         lvl_idx = 11;
581*495ae853SAndroid Build Coastguard Worker     }
582*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_50)
583*495ae853SAndroid Build Coastguard Worker     {
584*495ae853SAndroid Build Coastguard Worker         lvl_idx = 12;
585*495ae853SAndroid Build Coastguard Worker     }
586*495ae853SAndroid Build Coastguard Worker     else if (level < IH264_LEVEL_51)
587*495ae853SAndroid Build Coastguard Worker     {
588*495ae853SAndroid Build Coastguard Worker         lvl_idx = 13;
589*495ae853SAndroid Build Coastguard Worker     }
590*495ae853SAndroid Build Coastguard Worker     else
591*495ae853SAndroid Build Coastguard Worker     {
592*495ae853SAndroid Build Coastguard Worker         lvl_idx = 14;
593*495ae853SAndroid Build Coastguard Worker     }
594*495ae853SAndroid Build Coastguard Worker 
595*495ae853SAndroid Build Coastguard Worker     return (lvl_idx);
596*495ae853SAndroid Build Coastguard Worker }
597*495ae853SAndroid Build Coastguard Worker 
598*495ae853SAndroid Build Coastguard Worker /**
599*495ae853SAndroid Build Coastguard Worker *******************************************************************************
600*495ae853SAndroid Build Coastguard Worker *
601*495ae853SAndroid Build Coastguard Worker * @brief returns maximum number of pictures allowed in dpb for a given level
602*495ae853SAndroid Build Coastguard Worker *
603*495ae853SAndroid Build Coastguard Worker * @par Description:
604*495ae853SAndroid Build Coastguard Worker *  For given width, height and level, number of pictures allowed in decoder
605*495ae853SAndroid Build Coastguard Worker *  picture buffer is computed as per Annex A.3.1
606*495ae853SAndroid Build Coastguard Worker *
607*495ae853SAndroid Build Coastguard Worker * @param[in] level
608*495ae853SAndroid Build Coastguard Worker *  level of the bit-stream
609*495ae853SAndroid Build Coastguard Worker *
610*495ae853SAndroid Build Coastguard Worker * @param[in] pic_size
611*495ae853SAndroid Build Coastguard Worker *  width * height
612*495ae853SAndroid Build Coastguard Worker *
613*495ae853SAndroid Build Coastguard Worker * @returns  Number of buffers in DPB
614*495ae853SAndroid Build Coastguard Worker *
615*495ae853SAndroid Build Coastguard Worker * @remarks
616*495ae853SAndroid Build Coastguard Worker *  From annexure A.3.1 of H264 specification,
617*495ae853SAndroid Build Coastguard Worker *  max_dec_frame_buffering <= MaxDpbSize, where MaxDpbSize is equal to
618*495ae853SAndroid Build Coastguard Worker *  Min( 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 384 ), 16 ) and
619*495ae853SAndroid Build Coastguard Worker *  MaxDPB is given in Table A-1 in units of 1024 bytes. However the MaxDPB size
620*495ae853SAndroid Build Coastguard Worker *  presented in the look up table gas_ih264_lvl_tbl is in units of 512
621*495ae853SAndroid Build Coastguard Worker *  bytes. Hence the expression is modified accordingly.
622*495ae853SAndroid Build Coastguard Worker *
623*495ae853SAndroid Build Coastguard Worker *******************************************************************************
624*495ae853SAndroid Build Coastguard Worker */
ih264e_get_dpb_size(WORD32 level,WORD32 pic_size)625*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_get_dpb_size(WORD32 level, WORD32 pic_size)
626*495ae853SAndroid Build Coastguard Worker {
627*495ae853SAndroid Build Coastguard Worker     /* dpb size */
628*495ae853SAndroid Build Coastguard Worker     WORD32 max_dpb_size_bytes = 0;
629*495ae853SAndroid Build Coastguard Worker 
630*495ae853SAndroid Build Coastguard Worker     /* dec frame buffering */
631*495ae853SAndroid Build Coastguard Worker     WORD32 max_dpb_size_frames = 0;
632*495ae853SAndroid Build Coastguard Worker 
633*495ae853SAndroid Build Coastguard Worker     /* temp var */
634*495ae853SAndroid Build Coastguard Worker     WORD32 i;
635*495ae853SAndroid Build Coastguard Worker 
636*495ae853SAndroid Build Coastguard Worker     /* determine max luma samples */
637*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < 16; i++)
638*495ae853SAndroid Build Coastguard Worker         if (level == (WORD32)gas_ih264_lvl_tbl[i].u4_level_idc)
639*495ae853SAndroid Build Coastguard Worker             max_dpb_size_bytes = gas_ih264_lvl_tbl[i].u4_max_dpb_size;
640*495ae853SAndroid Build Coastguard Worker 
641*495ae853SAndroid Build Coastguard Worker     /* from Annexure A.3.1 h264 specification */
642*495ae853SAndroid Build Coastguard Worker     max_dpb_size_frames =
643*495ae853SAndroid Build Coastguard Worker                     MIN( 1024 * max_dpb_size_bytes / ( pic_size * 3 ), MAX_DPB_SIZE );
644*495ae853SAndroid Build Coastguard Worker 
645*495ae853SAndroid Build Coastguard Worker     return max_dpb_size_frames;
646*495ae853SAndroid Build Coastguard Worker }
647*495ae853SAndroid Build Coastguard Worker 
648*495ae853SAndroid Build Coastguard Worker /**
649*495ae853SAndroid Build Coastguard Worker *******************************************************************************
650*495ae853SAndroid Build Coastguard Worker *
651*495ae853SAndroid Build Coastguard Worker * @brief
652*495ae853SAndroid Build Coastguard Worker *  Used to get reference picture buffer size for a given level and
653*495ae853SAndroid Build Coastguard Worker *  and padding used
654*495ae853SAndroid Build Coastguard Worker *
655*495ae853SAndroid Build Coastguard Worker * @par Description:
656*495ae853SAndroid Build Coastguard Worker *  Used to get reference picture buffer size for a given level and padding used
657*495ae853SAndroid Build Coastguard Worker *  Each picture is padded on all four sides
658*495ae853SAndroid Build Coastguard Worker *
659*495ae853SAndroid Build Coastguard Worker * @param[in] pic_size
660*495ae853SAndroid Build Coastguard Worker *  Number of luma samples (Width * Height)
661*495ae853SAndroid Build Coastguard Worker *
662*495ae853SAndroid Build Coastguard Worker * @param[in] level
663*495ae853SAndroid Build Coastguard Worker *  Level
664*495ae853SAndroid Build Coastguard Worker *
665*495ae853SAndroid Build Coastguard Worker * @param[in] horz_pad
666*495ae853SAndroid Build Coastguard Worker *  Total padding used in horizontal direction
667*495ae853SAndroid Build Coastguard Worker *
668*495ae853SAndroid Build Coastguard Worker * @param[in] vert_pad
669*495ae853SAndroid Build Coastguard Worker *  Total padding used in vertical direction
670*495ae853SAndroid Build Coastguard Worker *
671*495ae853SAndroid Build Coastguard Worker * @returns  Total picture buffer size
672*495ae853SAndroid Build Coastguard Worker *
673*495ae853SAndroid Build Coastguard Worker * @remarks
674*495ae853SAndroid Build Coastguard Worker *
675*495ae853SAndroid Build Coastguard Worker *******************************************************************************
676*495ae853SAndroid Build Coastguard Worker */
ih264e_get_total_pic_buf_size(WORD32 pic_size,WORD32 level,WORD32 horz_pad,WORD32 vert_pad,WORD32 num_ref_frames,WORD32 num_reorder_frames)677*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_get_total_pic_buf_size(WORD32 pic_size,
678*495ae853SAndroid Build Coastguard Worker                                      WORD32 level,
679*495ae853SAndroid Build Coastguard Worker                                      WORD32 horz_pad,
680*495ae853SAndroid Build Coastguard Worker                                      WORD32 vert_pad,
681*495ae853SAndroid Build Coastguard Worker                                      WORD32 num_ref_frames,
682*495ae853SAndroid Build Coastguard Worker                                      WORD32 num_reorder_frames)
683*495ae853SAndroid Build Coastguard Worker {
684*495ae853SAndroid Build Coastguard Worker     WORD32 size;
685*495ae853SAndroid Build Coastguard Worker     WORD32 num_luma_samples;
686*495ae853SAndroid Build Coastguard Worker     WORD32 lvl_idx;
687*495ae853SAndroid Build Coastguard Worker     WORD32 max_wd, min_ht;
688*495ae853SAndroid Build Coastguard Worker     WORD32 num_samples;
689*495ae853SAndroid Build Coastguard Worker     WORD32 max_num_bufs;
690*495ae853SAndroid Build Coastguard Worker     WORD32 pad = MAX(horz_pad, vert_pad);
691*495ae853SAndroid Build Coastguard Worker 
692*495ae853SAndroid Build Coastguard Worker     /*
693*495ae853SAndroid Build Coastguard Worker      * If num_ref_frames and num_reorder_frmaes is specified
694*495ae853SAndroid Build Coastguard Worker      * Use minimum value
695*495ae853SAndroid Build Coastguard Worker      */
696*495ae853SAndroid Build Coastguard Worker     max_num_bufs = (num_ref_frames + num_reorder_frames + MAX_CTXT_SETS);
697*495ae853SAndroid Build Coastguard Worker 
698*495ae853SAndroid Build Coastguard Worker     /* Get level index */
699*495ae853SAndroid Build Coastguard Worker     lvl_idx = ih264e_get_lvl_idx(level);
700*495ae853SAndroid Build Coastguard Worker 
701*495ae853SAndroid Build Coastguard Worker     /* Maximum number of luma samples in a picture at given level */
702*495ae853SAndroid Build Coastguard Worker     num_luma_samples = gai4_ih264_max_luma_pic_size[lvl_idx];
703*495ae853SAndroid Build Coastguard Worker     num_luma_samples = MAX(num_luma_samples, pic_size);
704*495ae853SAndroid Build Coastguard Worker 
705*495ae853SAndroid Build Coastguard Worker     /* Account for chroma */
706*495ae853SAndroid Build Coastguard Worker     num_samples = num_luma_samples * 3 / 2;
707*495ae853SAndroid Build Coastguard Worker 
708*495ae853SAndroid Build Coastguard Worker     /* Maximum width of luma samples in a picture at given level */
709*495ae853SAndroid Build Coastguard Worker     max_wd = gai4_ih264_max_wd_ht[lvl_idx];
710*495ae853SAndroid Build Coastguard Worker 
711*495ae853SAndroid Build Coastguard Worker     /* Minimum height of luma samples in a picture at given level */
712*495ae853SAndroid Build Coastguard Worker     min_ht = gai4_ih264_min_wd_ht[lvl_idx];
713*495ae853SAndroid Build Coastguard Worker 
714*495ae853SAndroid Build Coastguard Worker     /* Allocation is required for
715*495ae853SAndroid Build Coastguard Worker      * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
716*495ae853SAndroid Build Coastguard Worker      *
717*495ae853SAndroid Build Coastguard Worker      * Above expanded as
718*495ae853SAndroid Build Coastguard Worker      * ((Wd * Ht) + (horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
719*495ae853SAndroid Build Coastguard Worker      * (Wd * Ht) * (2 * max_dpb_size + 1) + ((horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
720*495ae853SAndroid Build Coastguard Worker      * Now  max_dpb_size increases with smaller Wd and Ht, but Wd * ht * max_dpb_size will still be lesser or equal to max_wd * max_ht * dpb_size
721*495ae853SAndroid Build Coastguard Worker      *
722*495ae853SAndroid Build Coastguard Worker      * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by using num_samples * (2 * max_dpb_size + 1) below
723*495ae853SAndroid Build Coastguard Worker      *
724*495ae853SAndroid Build Coastguard Worker      * For the padded area use MAX(horz_pad, vert_pad) as pad
725*495ae853SAndroid Build Coastguard Worker      * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted from the above for padding
726*495ae853SAndroid Build Coastguard Worker      *
727*495ae853SAndroid Build Coastguard Worker      * Since Width and Height can change worst Wd + Ht is when One of the dimensions is max and other is min
728*495ae853SAndroid Build Coastguard Worker      * So use max_wd and min_ht
729*495ae853SAndroid Build Coastguard Worker      */
730*495ae853SAndroid Build Coastguard Worker 
731*495ae853SAndroid Build Coastguard Worker     /* Number of bytes in reference pictures */
732*495ae853SAndroid Build Coastguard Worker     size = num_samples * max_num_bufs;
733*495ae853SAndroid Build Coastguard Worker 
734*495ae853SAndroid Build Coastguard Worker     /* Account for padding area */
735*495ae853SAndroid Build Coastguard Worker     size += ((pad * pad) + pad * (max_wd + min_ht)) * 3 / 2 * max_num_bufs;
736*495ae853SAndroid Build Coastguard Worker 
737*495ae853SAndroid Build Coastguard Worker     return size;
738*495ae853SAndroid Build Coastguard Worker }
739*495ae853SAndroid Build Coastguard Worker 
740*495ae853SAndroid Build Coastguard Worker /**
741*495ae853SAndroid Build Coastguard Worker *******************************************************************************
742*495ae853SAndroid Build Coastguard Worker *
743*495ae853SAndroid Build Coastguard Worker * @brief Returns MV bank buffer size for a given number of luma samples
744*495ae853SAndroid Build Coastguard Worker *
745*495ae853SAndroid Build Coastguard Worker * @par Description:
746*495ae853SAndroid Build Coastguard Worker *  For given number of luma samples  one MV bank size is computed.
747*495ae853SAndroid Build Coastguard Worker *  Each MV bank includes pu_map and enc_pu_t for all the min PUs(4x4) in a picture
748*495ae853SAndroid Build Coastguard Worker *
749*495ae853SAndroid Build Coastguard Worker * @param[in] num_luma_samples
750*495ae853SAndroid Build Coastguard Worker *  Max number of luma pixels in the frame
751*495ae853SAndroid Build Coastguard Worker *
752*495ae853SAndroid Build Coastguard Worker * @returns  Total MV Bank size
753*495ae853SAndroid Build Coastguard Worker *
754*495ae853SAndroid Build Coastguard Worker * @remarks
755*495ae853SAndroid Build Coastguard Worker *
756*495ae853SAndroid Build Coastguard Worker *******************************************************************************
757*495ae853SAndroid Build Coastguard Worker */
ih264e_get_pic_mv_bank_size(WORD32 num_luma_samples)758*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_get_pic_mv_bank_size(WORD32 num_luma_samples)
759*495ae853SAndroid Build Coastguard Worker {
760*495ae853SAndroid Build Coastguard Worker     /* mv bank buffer size */
761*495ae853SAndroid Build Coastguard Worker     WORD32 mv_bank_size = 0;
762*495ae853SAndroid Build Coastguard Worker 
763*495ae853SAndroid Build Coastguard Worker     /* number of sub mb partitions possible */
764*495ae853SAndroid Build Coastguard Worker     WORD32 num_pu = num_luma_samples / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE);
765*495ae853SAndroid Build Coastguard Worker 
766*495ae853SAndroid Build Coastguard Worker     /* number of mbs */
767*495ae853SAndroid Build Coastguard Worker     WORD32 num_mb = num_luma_samples / (MB_SIZE * MB_SIZE);
768*495ae853SAndroid Build Coastguard Worker 
769*495ae853SAndroid Build Coastguard Worker     /* Size for storing enc_pu_t start index each MB */
770*495ae853SAndroid Build Coastguard Worker     /* One extra entry is needed to compute number of PUs in the last MB */
771*495ae853SAndroid Build Coastguard Worker     mv_bank_size += num_mb * sizeof(WORD32);
772*495ae853SAndroid Build Coastguard Worker 
773*495ae853SAndroid Build Coastguard Worker     /* Size for pu_map */
774*495ae853SAndroid Build Coastguard Worker     mv_bank_size += ALIGN4(num_pu);
775*495ae853SAndroid Build Coastguard Worker 
776*495ae853SAndroid Build Coastguard Worker     /* Size for storing enc_pu_t for each PU */
777*495ae853SAndroid Build Coastguard Worker     mv_bank_size += ALIGN4(num_pu * sizeof(enc_pu_t));
778*495ae853SAndroid Build Coastguard Worker 
779*495ae853SAndroid Build Coastguard Worker     return mv_bank_size;
780*495ae853SAndroid Build Coastguard Worker }
781*495ae853SAndroid Build Coastguard Worker 
782*495ae853SAndroid Build Coastguard Worker /**
783*495ae853SAndroid Build Coastguard Worker *******************************************************************************
784*495ae853SAndroid Build Coastguard Worker *
785*495ae853SAndroid Build Coastguard Worker * @brief
786*495ae853SAndroid Build Coastguard Worker *  Function to initialize ps_pic_buf structs add pic buffers to
787*495ae853SAndroid Build Coastguard Worker *  buffer manager in case of non-shared mode
788*495ae853SAndroid Build Coastguard Worker *
789*495ae853SAndroid Build Coastguard Worker * @par Description:
790*495ae853SAndroid Build Coastguard Worker *  Function to initialize ps_pic_buf structs add pic buffers to
791*495ae853SAndroid Build Coastguard Worker *  buffer manager in case of non-shared mode
792*495ae853SAndroid Build Coastguard Worker *  To be called once per stream or for every reset
793*495ae853SAndroid Build Coastguard Worker *
794*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
795*495ae853SAndroid Build Coastguard Worker *  Pointer to codec context
796*495ae853SAndroid Build Coastguard Worker *
797*495ae853SAndroid Build Coastguard Worker * @returns  error status
798*495ae853SAndroid Build Coastguard Worker *
799*495ae853SAndroid Build Coastguard Worker * @remarks
800*495ae853SAndroid Build Coastguard Worker *
801*495ae853SAndroid Build Coastguard Worker *******************************************************************************
802*495ae853SAndroid Build Coastguard Worker */
ih264e_pic_buf_mgr_add_bufs(codec_t * ps_codec)803*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T ih264e_pic_buf_mgr_add_bufs(codec_t *ps_codec)
804*495ae853SAndroid Build Coastguard Worker {
805*495ae853SAndroid Build Coastguard Worker     /* error status */
806*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T ret = IH264E_SUCCESS;
807*495ae853SAndroid Build Coastguard Worker 
808*495ae853SAndroid Build Coastguard Worker     /* max ref buffer cnt */
809*495ae853SAndroid Build Coastguard Worker     WORD32 max_num_bufs = ps_codec->i4_ref_buf_cnt;
810*495ae853SAndroid Build Coastguard Worker 
811*495ae853SAndroid Build Coastguard Worker     /* total size for pic buffers */
812*495ae853SAndroid Build Coastguard Worker     WORD32 pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size
813*495ae853SAndroid Build Coastguard Worker                     - BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
814*495ae853SAndroid Build Coastguard Worker 
815*495ae853SAndroid Build Coastguard Worker     /* temp var */
816*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_buf = (UWORD8 *) ps_codec->ps_pic_buf;
817*495ae853SAndroid Build Coastguard Worker     pic_buf_t *ps_pic_buf = (pic_buf_t *) ps_codec->ps_pic_buf;
818*495ae853SAndroid Build Coastguard Worker     WORD32 i;
819*495ae853SAndroid Build Coastguard Worker 
820*495ae853SAndroid Build Coastguard Worker     pu1_buf += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
821*495ae853SAndroid Build Coastguard Worker 
822*495ae853SAndroid Build Coastguard Worker     /* In case of non-shared mode, add picture buffers to buffer manager
823*495ae853SAndroid Build Coastguard Worker      * In case of shared mode, buffers are added in the run-time
824*495ae853SAndroid Build Coastguard Worker      */
825*495ae853SAndroid Build Coastguard Worker     {
826*495ae853SAndroid Build Coastguard Worker         WORD32 buf_ret;
827*495ae853SAndroid Build Coastguard Worker 
828*495ae853SAndroid Build Coastguard Worker         WORD32 luma_samples = (ps_codec->i4_rec_strd)
829*495ae853SAndroid Build Coastguard Worker                         * (ps_codec->s_cfg.u4_ht + PAD_HT);
830*495ae853SAndroid Build Coastguard Worker 
831*495ae853SAndroid Build Coastguard Worker         WORD32 chroma_samples = luma_samples >> 1;
832*495ae853SAndroid Build Coastguard Worker 
833*495ae853SAndroid Build Coastguard Worker         /* Try and add as many buffers as possible for the memory that is allocated */
834*495ae853SAndroid Build Coastguard Worker         /* If the number of buffers that can be added is less than max_num_bufs
835*495ae853SAndroid Build Coastguard Worker          * return with an error */
836*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < max_num_bufs; i++)
837*495ae853SAndroid Build Coastguard Worker         {
838*495ae853SAndroid Build Coastguard Worker             pic_buf_size_allocated -= (luma_samples + chroma_samples);
839*495ae853SAndroid Build Coastguard Worker 
840*495ae853SAndroid Build Coastguard Worker             if (pic_buf_size_allocated < 0)
841*495ae853SAndroid Build Coastguard Worker             {
842*495ae853SAndroid Build Coastguard Worker                 return IH264E_INSUFFICIENT_MEM_PICBUF;
843*495ae853SAndroid Build Coastguard Worker             }
844*495ae853SAndroid Build Coastguard Worker 
845*495ae853SAndroid Build Coastguard Worker             ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_rec_strd * PAD_TOP
846*495ae853SAndroid Build Coastguard Worker                             + PAD_LEFT;
847*495ae853SAndroid Build Coastguard Worker             pu1_buf += luma_samples;
848*495ae853SAndroid Build Coastguard Worker 
849*495ae853SAndroid Build Coastguard Worker             ps_pic_buf->pu1_chroma = pu1_buf
850*495ae853SAndroid Build Coastguard Worker                             + ps_codec->i4_rec_strd * (PAD_TOP / 2)+ PAD_LEFT;
851*495ae853SAndroid Build Coastguard Worker             pu1_buf += chroma_samples;
852*495ae853SAndroid Build Coastguard Worker 
853*495ae853SAndroid Build Coastguard Worker             buf_ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_ref_buf_mgr,
854*495ae853SAndroid Build Coastguard Worker                                         ps_pic_buf, i);
855*495ae853SAndroid Build Coastguard Worker 
856*495ae853SAndroid Build Coastguard Worker             if (0 != buf_ret)
857*495ae853SAndroid Build Coastguard Worker             {
858*495ae853SAndroid Build Coastguard Worker                 return IH264E_BUF_MGR_ERROR;
859*495ae853SAndroid Build Coastguard Worker             }
860*495ae853SAndroid Build Coastguard Worker             pu1_buf += (HPEL_PLANES_CNT - 1) * (chroma_samples + luma_samples);
861*495ae853SAndroid Build Coastguard Worker             ps_pic_buf++;
862*495ae853SAndroid Build Coastguard Worker         }
863*495ae853SAndroid Build Coastguard Worker     }
864*495ae853SAndroid Build Coastguard Worker 
865*495ae853SAndroid Build Coastguard Worker     return ret;
866*495ae853SAndroid Build Coastguard Worker }
867*495ae853SAndroid Build Coastguard Worker 
868*495ae853SAndroid Build Coastguard Worker /**
869*495ae853SAndroid Build Coastguard Worker *******************************************************************************
870*495ae853SAndroid Build Coastguard Worker *
871*495ae853SAndroid Build Coastguard Worker * @brief Function to add buffers to MV Bank buffer manager
872*495ae853SAndroid Build Coastguard Worker *
873*495ae853SAndroid Build Coastguard Worker * @par Description:
874*495ae853SAndroid Build Coastguard Worker *  Function to add buffers to MV Bank buffer manager.  To be called once per
875*495ae853SAndroid Build Coastguard Worker *  stream or for every reset
876*495ae853SAndroid Build Coastguard Worker *
877*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
878*495ae853SAndroid Build Coastguard Worker *  Pointer to codec context
879*495ae853SAndroid Build Coastguard Worker *
880*495ae853SAndroid Build Coastguard Worker * @returns  error status
881*495ae853SAndroid Build Coastguard Worker *
882*495ae853SAndroid Build Coastguard Worker * @remarks
883*495ae853SAndroid Build Coastguard Worker *
884*495ae853SAndroid Build Coastguard Worker *******************************************************************************
885*495ae853SAndroid Build Coastguard Worker */
ih264e_mv_buf_mgr_add_bufs(codec_t * ps_codec)886*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T ih264e_mv_buf_mgr_add_bufs(codec_t *ps_codec)
887*495ae853SAndroid Build Coastguard Worker {
888*495ae853SAndroid Build Coastguard Worker     /* error status */
889*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
890*495ae853SAndroid Build Coastguard Worker     IH264_ERROR_T ret;
891*495ae853SAndroid Build Coastguard Worker 
892*495ae853SAndroid Build Coastguard Worker     /* max dpb size in frames */
893*495ae853SAndroid Build Coastguard Worker     WORD32 max_dpb_size = 0;
894*495ae853SAndroid Build Coastguard Worker 
895*495ae853SAndroid Build Coastguard Worker     /* mv bank size for the entire dpb */
896*495ae853SAndroid Build Coastguard Worker     WORD32 mv_bank_size_allocated = 0;
897*495ae853SAndroid Build Coastguard Worker 
898*495ae853SAndroid Build Coastguard Worker     /* mv bank size per pic */
899*495ae853SAndroid Build Coastguard Worker     WORD32 pic_mv_bank_size = 0;
900*495ae853SAndroid Build Coastguard Worker 
901*495ae853SAndroid Build Coastguard Worker     /* mv buffer ptr */
902*495ae853SAndroid Build Coastguard Worker     mv_buf_t *ps_mv_buf = NULL;
903*495ae853SAndroid Build Coastguard Worker 
904*495ae853SAndroid Build Coastguard Worker     /* num of luma samples */
905*495ae853SAndroid Build Coastguard Worker     WORD32 num_luma_samples = ALIGN16(ps_codec->s_cfg.u4_wd)
906*495ae853SAndroid Build Coastguard Worker                             * ALIGN16(ps_codec->s_cfg.u4_ht);
907*495ae853SAndroid Build Coastguard Worker 
908*495ae853SAndroid Build Coastguard Worker     /* number of mb's & frame partitions */
909*495ae853SAndroid Build Coastguard Worker     WORD32 num_pu, num_mb;
910*495ae853SAndroid Build Coastguard Worker 
911*495ae853SAndroid Build Coastguard Worker     /* temp var */
912*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_buf = NULL;
913*495ae853SAndroid Build Coastguard Worker     WORD32 i;
914*495ae853SAndroid Build Coastguard Worker 
915*495ae853SAndroid Build Coastguard Worker     /* Compute the number of MB Bank buffers needed */
916*495ae853SAndroid Build Coastguard Worker     max_dpb_size = ps_codec->i4_ref_buf_cnt;
917*495ae853SAndroid Build Coastguard Worker 
918*495ae853SAndroid Build Coastguard Worker     /* allocate memory for mv buffer array */
919*495ae853SAndroid Build Coastguard Worker     ps_codec->ps_mv_buf = ps_codec->pv_mv_bank_buf_base;
920*495ae853SAndroid Build Coastguard Worker     pu1_buf = ps_codec->pv_mv_bank_buf_base;
921*495ae853SAndroid Build Coastguard Worker     pu1_buf += BUF_MGR_MAX_CNT * sizeof(mv_buf_t);
922*495ae853SAndroid Build Coastguard Worker 
923*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
924*495ae853SAndroid Build Coastguard Worker     /* allocate memory for individual elements of mv buffer ptr         */
925*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
926*495ae853SAndroid Build Coastguard Worker     mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size
927*495ae853SAndroid Build Coastguard Worker                     - (BUF_MGR_MAX_CNT * sizeof(mv_buf_t));
928*495ae853SAndroid Build Coastguard Worker 
929*495ae853SAndroid Build Coastguard Worker     /* compute MV bank size per picture */
930*495ae853SAndroid Build Coastguard Worker     pic_mv_bank_size = ih264e_get_pic_mv_bank_size(num_luma_samples);
931*495ae853SAndroid Build Coastguard Worker 
932*495ae853SAndroid Build Coastguard Worker     num_pu = num_luma_samples / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE);
933*495ae853SAndroid Build Coastguard Worker     num_mb = num_luma_samples / (MB_SIZE * MB_SIZE);
934*495ae853SAndroid Build Coastguard Worker     i = 0;
935*495ae853SAndroid Build Coastguard Worker     ps_mv_buf = ps_codec->pv_mv_bank_buf_base;
936*495ae853SAndroid Build Coastguard Worker 
937*495ae853SAndroid Build Coastguard Worker     while (i < max_dpb_size)
938*495ae853SAndroid Build Coastguard Worker     {
939*495ae853SAndroid Build Coastguard Worker         mv_bank_size_allocated -= pic_mv_bank_size;
940*495ae853SAndroid Build Coastguard Worker 
941*495ae853SAndroid Build Coastguard Worker         if (mv_bank_size_allocated < 0)
942*495ae853SAndroid Build Coastguard Worker         {
943*495ae853SAndroid Build Coastguard Worker             return IH264E_INSUFFICIENT_MEM_MVBANK;
944*495ae853SAndroid Build Coastguard Worker         }
945*495ae853SAndroid Build Coastguard Worker 
946*495ae853SAndroid Build Coastguard Worker         ps_mv_buf->pu4_mb_pu_cnt = (UWORD32 *) pu1_buf;
947*495ae853SAndroid Build Coastguard Worker         pu1_buf += num_mb * sizeof(WORD32);
948*495ae853SAndroid Build Coastguard Worker 
949*495ae853SAndroid Build Coastguard Worker         ps_mv_buf->pu1_pic_pu_map = pu1_buf;
950*495ae853SAndroid Build Coastguard Worker         pu1_buf += ALIGN4(num_pu);
951*495ae853SAndroid Build Coastguard Worker 
952*495ae853SAndroid Build Coastguard Worker         ps_mv_buf->ps_pic_pu = (enc_pu_t *) (pu1_buf);
953*495ae853SAndroid Build Coastguard Worker         pu1_buf += ALIGN4(num_pu * sizeof(enc_pu_t));
954*495ae853SAndroid Build Coastguard Worker 
955*495ae853SAndroid Build Coastguard Worker         ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_mv_buf_mgr,
956*495ae853SAndroid Build Coastguard Worker                                 ps_mv_buf, i);
957*495ae853SAndroid Build Coastguard Worker 
958*495ae853SAndroid Build Coastguard Worker         if (IH264_SUCCESS != ret)
959*495ae853SAndroid Build Coastguard Worker         {
960*495ae853SAndroid Build Coastguard Worker             return IH264E_BUF_MGR_ERROR;
961*495ae853SAndroid Build Coastguard Worker         }
962*495ae853SAndroid Build Coastguard Worker 
963*495ae853SAndroid Build Coastguard Worker         ps_mv_buf++;
964*495ae853SAndroid Build Coastguard Worker         i++;
965*495ae853SAndroid Build Coastguard Worker     }
966*495ae853SAndroid Build Coastguard Worker 
967*495ae853SAndroid Build Coastguard Worker     return error_status;
968*495ae853SAndroid Build Coastguard Worker }
969*495ae853SAndroid Build Coastguard Worker 
970*495ae853SAndroid Build Coastguard Worker /**
971*495ae853SAndroid Build Coastguard Worker *******************************************************************************
972*495ae853SAndroid Build Coastguard Worker *
973*495ae853SAndroid Build Coastguard Worker * @brief Function to initialize quant params structure
974*495ae853SAndroid Build Coastguard Worker *
975*495ae853SAndroid Build Coastguard Worker * @par Description:
976*495ae853SAndroid Build Coastguard Worker *  The forward quantization modules depends on qp/6, qp mod 6, forward scale
977*495ae853SAndroid Build Coastguard Worker *  matrix, forward threshold matrix, weight list. The inverse quantization
978*495ae853SAndroid Build Coastguard Worker *  modules depends on qp/6, qp mod 6, inverse scale matrix, weight list.
979*495ae853SAndroid Build Coastguard Worker *  These params are initialized in this function.
980*495ae853SAndroid Build Coastguard Worker *
981*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
982*495ae853SAndroid Build Coastguard Worker *  pointer to process context
983*495ae853SAndroid Build Coastguard Worker *
984*495ae853SAndroid Build Coastguard Worker * @param[in] qp
985*495ae853SAndroid Build Coastguard Worker *  quantization parameter
986*495ae853SAndroid Build Coastguard Worker *
987*495ae853SAndroid Build Coastguard Worker * @returns none
988*495ae853SAndroid Build Coastguard Worker *
989*495ae853SAndroid Build Coastguard Worker * @remarks
990*495ae853SAndroid Build Coastguard Worker *
991*495ae853SAndroid Build Coastguard Worker *******************************************************************************
992*495ae853SAndroid Build Coastguard Worker */
ih264e_init_quant_params(process_ctxt_t * ps_proc,int qp)993*495ae853SAndroid Build Coastguard Worker void ih264e_init_quant_params(process_ctxt_t *ps_proc, int qp)
994*495ae853SAndroid Build Coastguard Worker {
995*495ae853SAndroid Build Coastguard Worker     /* quant params */
996*495ae853SAndroid Build Coastguard Worker     quant_params_t *ps_qp_params;
997*495ae853SAndroid Build Coastguard Worker 
998*495ae853SAndroid Build Coastguard Worker     /* ptr to forward quant threshold matrix */
999*495ae853SAndroid Build Coastguard Worker     const UWORD16 *pu2_thres_mat = NULL;
1000*495ae853SAndroid Build Coastguard Worker 
1001*495ae853SAndroid Build Coastguard Worker     /* ptr to forward scale matrix */
1002*495ae853SAndroid Build Coastguard Worker     const UWORD16 *pu2_scale_mat = gu2_quant_scale_matrix_4x4;
1003*495ae853SAndroid Build Coastguard Worker 
1004*495ae853SAndroid Build Coastguard Worker     /* ptr to inverse scale matrix */
1005*495ae853SAndroid Build Coastguard Worker     const UWORD16 *pu2_iscale_mat = gau2_ih264_iquant_scale_matrix_4x4;
1006*495ae853SAndroid Build Coastguard Worker 
1007*495ae853SAndroid Build Coastguard Worker     /* temp var */
1008*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_qp[3], u4_qp_div6, u4_qp_mod6;
1009*495ae853SAndroid Build Coastguard Worker     COMPONENT_TYPE plane;
1010*495ae853SAndroid Build Coastguard Worker     WORD32 i;
1011*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_satdq_t;
1012*495ae853SAndroid Build Coastguard Worker     const UWORD16 *pu2_smat;
1013*495ae853SAndroid Build Coastguard Worker 
1014*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1015*495ae853SAndroid Build Coastguard Worker     /* init quant params for all planes Y, U and V                      */
1016*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1017*495ae853SAndroid Build Coastguard Worker     /* luma qp */
1018*495ae853SAndroid Build Coastguard Worker     u4_qp[Y] = qp;
1019*495ae853SAndroid Build Coastguard Worker 
1020*495ae853SAndroid Build Coastguard Worker     /* chroma qp
1021*495ae853SAndroid Build Coastguard Worker      * TODO_LATER : just in case if the chroma planes use different qp's this
1022*495ae853SAndroid Build Coastguard Worker      * needs to be corrected accordingly.
1023*495ae853SAndroid Build Coastguard Worker      */
1024*495ae853SAndroid Build Coastguard Worker     u4_qp[U] = gu1_qpc_fqpi[qp];
1025*495ae853SAndroid Build Coastguard Worker     u4_qp[V] = gu1_qpc_fqpi[qp];
1026*495ae853SAndroid Build Coastguard Worker 
1027*495ae853SAndroid Build Coastguard Worker     plane = Y;
1028*495ae853SAndroid Build Coastguard Worker     while (plane <= V)
1029*495ae853SAndroid Build Coastguard Worker     {
1030*495ae853SAndroid Build Coastguard Worker         u4_qp_div6 = (u4_qp[plane] / 6);
1031*495ae853SAndroid Build Coastguard Worker         u4_qp_mod6 = (u4_qp[plane] % 6);
1032*495ae853SAndroid Build Coastguard Worker 
1033*495ae853SAndroid Build Coastguard Worker         ps_qp_params = ps_proc->ps_qp_params[plane];
1034*495ae853SAndroid Build Coastguard Worker 
1035*495ae853SAndroid Build Coastguard Worker         /* mb qp */
1036*495ae853SAndroid Build Coastguard Worker         ps_qp_params->u1_mb_qp = u4_qp[plane];
1037*495ae853SAndroid Build Coastguard Worker 
1038*495ae853SAndroid Build Coastguard Worker         /* mb qp / 6 */
1039*495ae853SAndroid Build Coastguard Worker         ps_qp_params->u1_qp_div = u4_qp_div6;
1040*495ae853SAndroid Build Coastguard Worker 
1041*495ae853SAndroid Build Coastguard Worker         /* mb qp % 6 */
1042*495ae853SAndroid Build Coastguard Worker         ps_qp_params->u1_qp_rem = u4_qp_mod6;
1043*495ae853SAndroid Build Coastguard Worker 
1044*495ae853SAndroid Build Coastguard Worker         /* QP bits */
1045*495ae853SAndroid Build Coastguard Worker         ps_qp_params->u1_qbits = QP_BITS_h264_4x4 + u4_qp_div6;
1046*495ae853SAndroid Build Coastguard Worker 
1047*495ae853SAndroid Build Coastguard Worker         /* forward scale matrix */
1048*495ae853SAndroid Build Coastguard Worker         ps_qp_params->pu2_scale_mat = pu2_scale_mat + (u4_qp_mod6 * 16);
1049*495ae853SAndroid Build Coastguard Worker 
1050*495ae853SAndroid Build Coastguard Worker         /* threshold matrix & weight for quantization */
1051*495ae853SAndroid Build Coastguard Worker         pu2_thres_mat = gu2_forward_quant_threshold_4x4 + (u4_qp_mod6 * 16);
1052*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < 16; i++)
1053*495ae853SAndroid Build Coastguard Worker         {
1054*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_thres_mat[i] = pu2_thres_mat[i]
1055*495ae853SAndroid Build Coastguard Worker                             >> (8 - u4_qp_div6);
1056*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_weigh_mat[i] = 16;
1057*495ae853SAndroid Build Coastguard Worker         }
1058*495ae853SAndroid Build Coastguard Worker 
1059*495ae853SAndroid Build Coastguard Worker         /* qp dependent rounding constant */
1060*495ae853SAndroid Build Coastguard Worker         ps_qp_params->u4_dead_zone =
1061*495ae853SAndroid Build Coastguard Worker                         gu4_forward_quant_round_factor_4x4[u4_qp_div6];
1062*495ae853SAndroid Build Coastguard Worker 
1063*495ae853SAndroid Build Coastguard Worker         /* slice dependent rounding constant */
1064*495ae853SAndroid Build Coastguard Worker         if (ps_proc->i4_slice_type != ISLICE
1065*495ae853SAndroid Build Coastguard Worker                         && ps_proc->i4_slice_type != SISLICE)
1066*495ae853SAndroid Build Coastguard Worker         {
1067*495ae853SAndroid Build Coastguard Worker             ps_qp_params->u4_dead_zone >>= 1;
1068*495ae853SAndroid Build Coastguard Worker         }
1069*495ae853SAndroid Build Coastguard Worker 
1070*495ae853SAndroid Build Coastguard Worker         /* SATQD threshold for zero block prediction */
1071*495ae853SAndroid Build Coastguard Worker         if (ps_proc->ps_codec->s_cfg.u4_enable_satqd)
1072*495ae853SAndroid Build Coastguard Worker         {
1073*495ae853SAndroid Build Coastguard Worker             pu2_smat = ps_qp_params->pu2_scale_mat;
1074*495ae853SAndroid Build Coastguard Worker 
1075*495ae853SAndroid Build Coastguard Worker             u4_satdq_t = ((1 << (ps_qp_params->u1_qbits)) - ps_qp_params->u4_dead_zone);
1076*495ae853SAndroid Build Coastguard Worker 
1077*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[0] = u4_satdq_t / MAX(pu2_smat[3], pu2_smat[11]);
1078*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[1] = u4_satdq_t / MAX(pu2_smat[1], pu2_smat[9]);
1079*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[2] = u4_satdq_t / pu2_smat[15];
1080*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[3] = u4_satdq_t / pu2_smat[7];
1081*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[4] = u4_satdq_t / MAX(pu2_smat[12], pu2_smat[14]);
1082*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[5] = u4_satdq_t / MAX(pu2_smat[4], pu2_smat[6]);
1083*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[6] = u4_satdq_t / pu2_smat[13];
1084*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[7] = u4_satdq_t / pu2_smat[5];
1085*495ae853SAndroid Build Coastguard Worker             ps_qp_params->pu2_sad_thrsh[8] = u4_satdq_t / MAX(MAX3(pu2_smat[0], pu2_smat[2], pu2_smat[8]), pu2_smat[10]);
1086*495ae853SAndroid Build Coastguard Worker         }
1087*495ae853SAndroid Build Coastguard Worker 
1088*495ae853SAndroid Build Coastguard Worker         /* inverse scale matrix */
1089*495ae853SAndroid Build Coastguard Worker         ps_qp_params->pu2_iscale_mat = pu2_iscale_mat + (u4_qp_mod6 * 16);
1090*495ae853SAndroid Build Coastguard Worker 
1091*495ae853SAndroid Build Coastguard Worker         plane += 1;
1092*495ae853SAndroid Build Coastguard Worker     }
1093*495ae853SAndroid Build Coastguard Worker     return ;
1094*495ae853SAndroid Build Coastguard Worker }
1095*495ae853SAndroid Build Coastguard Worker 
1096*495ae853SAndroid Build Coastguard Worker /**
1097*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1098*495ae853SAndroid Build Coastguard Worker *
1099*495ae853SAndroid Build Coastguard Worker * @brief
1100*495ae853SAndroid Build Coastguard Worker *  Initialize AIR mb frame Map
1101*495ae853SAndroid Build Coastguard Worker *
1102*495ae853SAndroid Build Coastguard Worker * @par Description:
1103*495ae853SAndroid Build Coastguard Worker *  Initialize AIR mb frame map.  MB frame map indicates which MB in a frame
1104*495ae853SAndroid Build Coastguard Worker *  should be coded as intra according to AIR
1105*495ae853SAndroid Build Coastguard Worker *
1106*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
1107*495ae853SAndroid Build Coastguard Worker *  Pointer to codec context
1108*495ae853SAndroid Build Coastguard Worker *
1109*495ae853SAndroid Build Coastguard Worker * @returns  error_status
1110*495ae853SAndroid Build Coastguard Worker *
1111*495ae853SAndroid Build Coastguard Worker * @remarks
1112*495ae853SAndroid Build Coastguard Worker *
1113*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1114*495ae853SAndroid Build Coastguard Worker */
ih264e_init_air_map(codec_t * ps_codec)1115*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T ih264e_init_air_map(codec_t *ps_codec)
1116*495ae853SAndroid Build Coastguard Worker {
1117*495ae853SAndroid Build Coastguard Worker     /* intra refresh map */
1118*495ae853SAndroid Build Coastguard Worker     UWORD16 *pu2_intr_rfrsh_map = ps_codec->pu2_intr_rfrsh_map;
1119*495ae853SAndroid Build Coastguard Worker 
1120*495ae853SAndroid Build Coastguard Worker     /* air mode */
1121*495ae853SAndroid Build Coastguard Worker     IVE_AIR_MODE_T air_mode = ps_codec->s_cfg.e_air_mode;
1122*495ae853SAndroid Build Coastguard Worker 
1123*495ae853SAndroid Build Coastguard Worker     /* refresh period */
1124*495ae853SAndroid Build Coastguard Worker     UWORD32 air_period = ps_codec->s_cfg.u4_air_refresh_period;
1125*495ae853SAndroid Build Coastguard Worker 
1126*495ae853SAndroid Build Coastguard Worker     /* mb cnt */
1127*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_mb_cnt = ps_codec->s_cfg.i4_wd_mbs * ps_codec->s_cfg.i4_ht_mbs;
1128*495ae853SAndroid Build Coastguard Worker 
1129*495ae853SAndroid Build Coastguard Worker     /* temp var */
1130*495ae853SAndroid Build Coastguard Worker     UWORD32 curr_mb, seed_rand = 1;
1131*495ae853SAndroid Build Coastguard Worker 
1132*495ae853SAndroid Build Coastguard Worker     switch (air_mode)
1133*495ae853SAndroid Build Coastguard Worker     {
1134*495ae853SAndroid Build Coastguard Worker         case IVE_AIR_MODE_CYCLIC:
1135*495ae853SAndroid Build Coastguard Worker 
1136*495ae853SAndroid Build Coastguard Worker             for (curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
1137*495ae853SAndroid Build Coastguard Worker             {
1138*495ae853SAndroid Build Coastguard Worker                 pu2_intr_rfrsh_map[curr_mb] = curr_mb % air_period;
1139*495ae853SAndroid Build Coastguard Worker             }
1140*495ae853SAndroid Build Coastguard Worker             break;
1141*495ae853SAndroid Build Coastguard Worker 
1142*495ae853SAndroid Build Coastguard Worker         case IVE_AIR_MODE_RANDOM:
1143*495ae853SAndroid Build Coastguard Worker 
1144*495ae853SAndroid Build Coastguard Worker             for (curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
1145*495ae853SAndroid Build Coastguard Worker             {
1146*495ae853SAndroid Build Coastguard Worker                 seed_rand = (seed_rand * 32719 + 3) % 32749;
1147*495ae853SAndroid Build Coastguard Worker                 pu2_intr_rfrsh_map[curr_mb] = seed_rand % air_period;
1148*495ae853SAndroid Build Coastguard Worker             }
1149*495ae853SAndroid Build Coastguard Worker             break;
1150*495ae853SAndroid Build Coastguard Worker 
1151*495ae853SAndroid Build Coastguard Worker         default:
1152*495ae853SAndroid Build Coastguard Worker 
1153*495ae853SAndroid Build Coastguard Worker             break;
1154*495ae853SAndroid Build Coastguard Worker     }
1155*495ae853SAndroid Build Coastguard Worker 
1156*495ae853SAndroid Build Coastguard Worker     return IH264E_SUCCESS;
1157*495ae853SAndroid Build Coastguard Worker }
1158*495ae853SAndroid Build Coastguard Worker 
1159*495ae853SAndroid Build Coastguard Worker /**
1160*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1161*495ae853SAndroid Build Coastguard Worker *
1162*495ae853SAndroid Build Coastguard Worker * @brief Speed preset side effects
1163*495ae853SAndroid Build Coastguard Worker *
1164*495ae853SAndroid Build Coastguard Worker * @par Description:
1165*495ae853SAndroid Build Coastguard Worker *  Force apply the configuration options basing on the configured speed preset
1166*495ae853SAndroid Build Coastguard Worker *
1167*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
1168*495ae853SAndroid Build Coastguard Worker *  Pointer to codec context
1169*495ae853SAndroid Build Coastguard Worker *
1170*495ae853SAndroid Build Coastguard Worker * @returns none
1171*495ae853SAndroid Build Coastguard Worker *
1172*495ae853SAndroid Build Coastguard Worker * @remarks
1173*495ae853SAndroid Build Coastguard Worker *
1174*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1175*495ae853SAndroid Build Coastguard Worker */
ih264e_speed_preset_side_effects(codec_t * ps_codec)1176*495ae853SAndroid Build Coastguard Worker void ih264e_speed_preset_side_effects(codec_t *ps_codec)
1177*495ae853SAndroid Build Coastguard Worker {
1178*495ae853SAndroid Build Coastguard Worker     cfg_params_t *ps_cfg = &ps_codec->s_cfg;
1179*495ae853SAndroid Build Coastguard Worker 
1180*495ae853SAndroid Build Coastguard Worker     if (ps_cfg->u4_enc_speed_preset == IVE_SLOWEST)
1181*495ae853SAndroid Build Coastguard Worker     {/* high quality */
1182*495ae853SAndroid Build Coastguard Worker         /* enable diamond search */
1183*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_me_speed_preset = DMND_SRCH;
1184*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_fast_sad = 0;
1185*495ae853SAndroid Build Coastguard Worker 
1186*495ae853SAndroid Build Coastguard Worker         /* disable intra 4x4 */
1187*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_intra_4x4 = 1;
1188*495ae853SAndroid Build Coastguard Worker         ps_codec->luma_energy_compaction[1] =
1189*495ae853SAndroid Build Coastguard Worker                         ih264e_code_luma_intra_macroblock_4x4_rdopt_on;
1190*495ae853SAndroid Build Coastguard Worker 
1191*495ae853SAndroid Build Coastguard Worker         /* sub pel off */
1192*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_hpel = 1;
1193*495ae853SAndroid Build Coastguard Worker 
1194*495ae853SAndroid Build Coastguard Worker         /* deblocking off */
1195*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1196*495ae853SAndroid Build Coastguard Worker 
1197*495ae853SAndroid Build Coastguard Worker         /* disabled intra inter gating in Inter slices */
1198*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_inter_gate = 0;
1199*495ae853SAndroid Build Coastguard Worker     }
1200*495ae853SAndroid Build Coastguard Worker     else if (ps_cfg->u4_enc_speed_preset == IVE_NORMAL)
1201*495ae853SAndroid Build Coastguard Worker     {/* normal */
1202*495ae853SAndroid Build Coastguard Worker         /* enable diamond search */
1203*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_me_speed_preset = DMND_SRCH;
1204*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_fast_sad = 0;
1205*495ae853SAndroid Build Coastguard Worker 
1206*495ae853SAndroid Build Coastguard Worker         /* disable intra 4x4 */
1207*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_intra_4x4 = 1;
1208*495ae853SAndroid Build Coastguard Worker 
1209*495ae853SAndroid Build Coastguard Worker         /* sub pel off */
1210*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_hpel = 1;
1211*495ae853SAndroid Build Coastguard Worker 
1212*495ae853SAndroid Build Coastguard Worker         /* deblocking off */
1213*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1214*495ae853SAndroid Build Coastguard Worker 
1215*495ae853SAndroid Build Coastguard Worker         /* disabled intra inter gating in Inter slices */
1216*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_inter_gate = 0;
1217*495ae853SAndroid Build Coastguard Worker     }
1218*495ae853SAndroid Build Coastguard Worker     else if (ps_cfg->u4_enc_speed_preset == IVE_FAST)
1219*495ae853SAndroid Build Coastguard Worker     {/* fast */
1220*495ae853SAndroid Build Coastguard Worker          /* enable diamond search */
1221*495ae853SAndroid Build Coastguard Worker          ps_cfg->u4_me_speed_preset = DMND_SRCH;
1222*495ae853SAndroid Build Coastguard Worker          ps_cfg->u4_enable_fast_sad = 0;
1223*495ae853SAndroid Build Coastguard Worker 
1224*495ae853SAndroid Build Coastguard Worker          /* disable intra 4x4 */
1225*495ae853SAndroid Build Coastguard Worker          ps_cfg->u4_enable_intra_4x4 = 0;
1226*495ae853SAndroid Build Coastguard Worker 
1227*495ae853SAndroid Build Coastguard Worker          /* sub pel off */
1228*495ae853SAndroid Build Coastguard Worker          ps_cfg->u4_enable_hpel = 1;
1229*495ae853SAndroid Build Coastguard Worker 
1230*495ae853SAndroid Build Coastguard Worker          /* deblocking off */
1231*495ae853SAndroid Build Coastguard Worker          ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1232*495ae853SAndroid Build Coastguard Worker 
1233*495ae853SAndroid Build Coastguard Worker          /* disabled intra inter gating in Inter slices */
1234*495ae853SAndroid Build Coastguard Worker          ps_codec->u4_inter_gate = 1;
1235*495ae853SAndroid Build Coastguard Worker      }
1236*495ae853SAndroid Build Coastguard Worker     else if (ps_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED)
1237*495ae853SAndroid Build Coastguard Worker     {/* high speed */
1238*495ae853SAndroid Build Coastguard Worker         /* enable diamond search */
1239*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_me_speed_preset = DMND_SRCH;
1240*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_fast_sad = 0;
1241*495ae853SAndroid Build Coastguard Worker 
1242*495ae853SAndroid Build Coastguard Worker         /* disable intra 4x4 */
1243*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_intra_4x4 = 0;
1244*495ae853SAndroid Build Coastguard Worker 
1245*495ae853SAndroid Build Coastguard Worker         /* sub pel off */
1246*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_hpel = 0;
1247*495ae853SAndroid Build Coastguard Worker 
1248*495ae853SAndroid Build Coastguard Worker         /* deblocking off */
1249*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
1250*495ae853SAndroid Build Coastguard Worker 
1251*495ae853SAndroid Build Coastguard Worker         /* disabled intra inter gating in Inter slices */
1252*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_inter_gate = 0;
1253*495ae853SAndroid Build Coastguard Worker     }
1254*495ae853SAndroid Build Coastguard Worker     else if (ps_cfg->u4_enc_speed_preset == IVE_FASTEST)
1255*495ae853SAndroid Build Coastguard Worker     {/* fastest */
1256*495ae853SAndroid Build Coastguard Worker         /* enable diamond search */
1257*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_me_speed_preset = DMND_SRCH;
1258*495ae853SAndroid Build Coastguard Worker 
1259*495ae853SAndroid Build Coastguard Worker         /* disable intra 4x4 */
1260*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_intra_4x4 = 0;
1261*495ae853SAndroid Build Coastguard Worker 
1262*495ae853SAndroid Build Coastguard Worker         /* sub pel off */
1263*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_enable_hpel = 0;
1264*495ae853SAndroid Build Coastguard Worker 
1265*495ae853SAndroid Build Coastguard Worker         /* deblocking off */
1266*495ae853SAndroid Build Coastguard Worker         ps_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
1267*495ae853SAndroid Build Coastguard Worker 
1268*495ae853SAndroid Build Coastguard Worker         /* disabled intra inter gating in Inter slices */
1269*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_inter_gate = 1;
1270*495ae853SAndroid Build Coastguard Worker     }
1271*495ae853SAndroid Build Coastguard Worker }
1272*495ae853SAndroid Build Coastguard Worker 
1273*495ae853SAndroid Build Coastguard Worker /**
1274*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1275*495ae853SAndroid Build Coastguard Worker *
1276*495ae853SAndroid Build Coastguard Worker * @brief
1277*495ae853SAndroid Build Coastguard Worker *  Codec level initializations
1278*495ae853SAndroid Build Coastguard Worker *
1279*495ae853SAndroid Build Coastguard Worker * @par Description:
1280*495ae853SAndroid Build Coastguard Worker *  Initializes the codec with parameters that needs to be set before encoding
1281*495ae853SAndroid Build Coastguard Worker *  first frame
1282*495ae853SAndroid Build Coastguard Worker *
1283*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
1284*495ae853SAndroid Build Coastguard Worker *  Pointer to codec context
1285*495ae853SAndroid Build Coastguard Worker *
1286*495ae853SAndroid Build Coastguard Worker * @param[in] ps_inp_buf
1287*495ae853SAndroid Build Coastguard Worker *  Pointer to input buffer context
1288*495ae853SAndroid Build Coastguard Worker *
1289*495ae853SAndroid Build Coastguard Worker * @returns  error_status
1290*495ae853SAndroid Build Coastguard Worker *
1291*495ae853SAndroid Build Coastguard Worker * @remarks
1292*495ae853SAndroid Build Coastguard Worker *
1293*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1294*495ae853SAndroid Build Coastguard Worker */
ih264e_codec_init(codec_t * ps_codec)1295*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec)
1296*495ae853SAndroid Build Coastguard Worker {
1297*495ae853SAndroid Build Coastguard Worker     /********************************************************************
1298*495ae853SAndroid Build Coastguard Worker      *                     INITIALIZE CODEC CONTEXT                     *
1299*495ae853SAndroid Build Coastguard Worker      ********************************************************************/
1300*495ae853SAndroid Build Coastguard Worker     /* encoder presets */
1301*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_enc_speed_preset != IVE_CONFIG)
1302*495ae853SAndroid Build Coastguard Worker     {
1303*495ae853SAndroid Build Coastguard Worker         ih264e_speed_preset_side_effects(ps_codec);
1304*495ae853SAndroid Build Coastguard Worker     }
1305*495ae853SAndroid Build Coastguard Worker 
1306*495ae853SAndroid Build Coastguard Worker     /*****************************************************************
1307*495ae853SAndroid Build Coastguard Worker      * Initialize AIR inside codec
1308*495ae853SAndroid Build Coastguard Worker      *****************************************************************/
1309*495ae853SAndroid Build Coastguard Worker     if (IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
1310*495ae853SAndroid Build Coastguard Worker     {
1311*495ae853SAndroid Build Coastguard Worker         ih264e_init_air_map(ps_codec);
1312*495ae853SAndroid Build Coastguard Worker 
1313*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_air_pic_cnt = -1;
1314*495ae853SAndroid Build Coastguard Worker     }
1315*495ae853SAndroid Build Coastguard Worker 
1316*495ae853SAndroid Build Coastguard Worker     /*****************************************************************/
1317*495ae853SAndroid Build Coastguard Worker     /*                    Initialize Intra Cost Map                  */
1318*495ae853SAndroid Build Coastguard Worker     /*****************************************************************/
1319*495ae853SAndroid Build Coastguard Worker     memset(ps_codec->pi4_mb_intra_cost, 0, ps_codec->s_cfg.i4_wd_mbs *
1320*495ae853SAndroid Build Coastguard Worker            ps_codec->s_cfg.i4_ht_mbs * sizeof(*ps_codec->pi4_mb_intra_cost));
1321*495ae853SAndroid Build Coastguard Worker 
1322*495ae853SAndroid Build Coastguard Worker     /****************************************************/
1323*495ae853SAndroid Build Coastguard Worker     /*           INITIALIZE RATE CONTROL                */
1324*495ae853SAndroid Build Coastguard Worker     /****************************************************/
1325*495ae853SAndroid Build Coastguard Worker     {
1326*495ae853SAndroid Build Coastguard Worker         /* init qp */
1327*495ae853SAndroid Build Coastguard Worker         UWORD8 au1_init_qp[MAX_PIC_TYPE];
1328*495ae853SAndroid Build Coastguard Worker 
1329*495ae853SAndroid Build Coastguard Worker         /* min max qp */
1330*495ae853SAndroid Build Coastguard Worker         UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
1331*495ae853SAndroid Build Coastguard Worker 
1332*495ae853SAndroid Build Coastguard Worker         /* init i,p,b qp */
1333*495ae853SAndroid Build Coastguard Worker         au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp];
1334*495ae853SAndroid Build Coastguard Worker         au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp];
1335*495ae853SAndroid Build Coastguard Worker         au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp];
1336*495ae853SAndroid Build Coastguard Worker 
1337*495ae853SAndroid Build Coastguard Worker         /* init min max qp */
1338*495ae853SAndroid Build Coastguard Worker         au1_min_max_qp[2 * I_PIC] =
1339*495ae853SAndroid Build Coastguard Worker                         gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min];
1340*495ae853SAndroid Build Coastguard Worker         au1_min_max_qp[2 * I_PIC + 1] =
1341*495ae853SAndroid Build Coastguard Worker                         gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max];
1342*495ae853SAndroid Build Coastguard Worker 
1343*495ae853SAndroid Build Coastguard Worker         au1_min_max_qp[2 * P_PIC] =
1344*495ae853SAndroid Build Coastguard Worker                         gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min];
1345*495ae853SAndroid Build Coastguard Worker         au1_min_max_qp[2 * P_PIC + 1] =
1346*495ae853SAndroid Build Coastguard Worker                         gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max];
1347*495ae853SAndroid Build Coastguard Worker 
1348*495ae853SAndroid Build Coastguard Worker         au1_min_max_qp[2 * B_PIC] =
1349*495ae853SAndroid Build Coastguard Worker                         gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min];
1350*495ae853SAndroid Build Coastguard Worker         au1_min_max_qp[2 * B_PIC + 1] =
1351*495ae853SAndroid Build Coastguard Worker                         gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max];
1352*495ae853SAndroid Build Coastguard Worker 
1353*495ae853SAndroid Build Coastguard Worker         /* get rc mode */
1354*495ae853SAndroid Build Coastguard Worker         switch (ps_codec->s_cfg.e_rc_mode)
1355*495ae853SAndroid Build Coastguard Worker         {
1356*495ae853SAndroid Build Coastguard Worker             case IVE_RC_STORAGE:
1357*495ae853SAndroid Build Coastguard Worker                 ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
1358*495ae853SAndroid Build Coastguard Worker                 break;
1359*495ae853SAndroid Build Coastguard Worker             case IVE_RC_CBR_NON_LOW_DELAY:
1360*495ae853SAndroid Build Coastguard Worker                 ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
1361*495ae853SAndroid Build Coastguard Worker                 break;
1362*495ae853SAndroid Build Coastguard Worker             case IVE_RC_CBR_LOW_DELAY:
1363*495ae853SAndroid Build Coastguard Worker                 ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
1364*495ae853SAndroid Build Coastguard Worker                 break;
1365*495ae853SAndroid Build Coastguard Worker             case IVE_RC_NONE:
1366*495ae853SAndroid Build Coastguard Worker                 ps_codec->s_rate_control.e_rc_type = CONST_QP;
1367*495ae853SAndroid Build Coastguard Worker                 break;
1368*495ae853SAndroid Build Coastguard Worker             default:
1369*495ae853SAndroid Build Coastguard Worker                 break;
1370*495ae853SAndroid Build Coastguard Worker         }
1371*495ae853SAndroid Build Coastguard Worker 
1372*495ae853SAndroid Build Coastguard Worker         /* init rate control */
1373*495ae853SAndroid Build Coastguard Worker         ih264e_rc_init(ps_codec->s_rate_control.pps_rate_control_api,
1374*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_rate_control.pps_frame_time,
1375*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_rate_control.pps_time_stamp,
1376*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_rate_control.pps_pd_frm_rate,
1377*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_max_framerate,
1378*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_src_frame_rate,
1379*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_tgt_frame_rate,
1380*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_rate_control.e_rc_type,
1381*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_target_bitrate,
1382*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_max_bitrate,
1383*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_vbv_buffer_delay,
1384*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_i_frm_interval,
1385*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp,
1386*495ae853SAndroid Build Coastguard Worker                        ps_codec->s_cfg.u4_num_bframes + 2 , au1_min_max_qp,
1387*495ae853SAndroid Build Coastguard Worker                        MAX(ps_codec->s_cfg.u4_max_level,
1388*495ae853SAndroid Build Coastguard Worker                                (UWORD32)ih264e_get_min_level(ps_codec->s_cfg.u4_max_wd, ps_codec->s_cfg.u4_max_ht)));
1389*495ae853SAndroid Build Coastguard Worker     }
1390*495ae853SAndroid Build Coastguard Worker 
1391*495ae853SAndroid Build Coastguard Worker     /* recon stride */
1392*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_rec_strd = ALIGN16(ps_codec->s_cfg.u4_max_wd) + PAD_WD;
1393*495ae853SAndroid Build Coastguard Worker 
1394*495ae853SAndroid Build Coastguard Worker     /* max ref and reorder cnt */
1395*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_ref_buf_cnt = ps_codec->s_cfg.u4_max_ref_cnt
1396*495ae853SAndroid Build Coastguard Worker                     + ps_codec->s_cfg.u4_max_reorder_cnt;
1397*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_ref_buf_cnt += MAX_CTXT_SETS;
1398*495ae853SAndroid Build Coastguard Worker 
1399*495ae853SAndroid Build Coastguard Worker     DEBUG_HISTOGRAM_INIT();
1400*495ae853SAndroid Build Coastguard Worker 
1401*495ae853SAndroid Build Coastguard Worker     /* Init dependecy vars */
1402*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_last_inp_buff_received = 0;
1403*495ae853SAndroid Build Coastguard Worker 
1404*495ae853SAndroid Build Coastguard Worker     /* At codec start no IDR is pending */
1405*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_pending_idr_flag = 0;
1406*495ae853SAndroid Build Coastguard Worker 
1407*495ae853SAndroid Build Coastguard Worker     return IH264E_SUCCESS;
1408*495ae853SAndroid Build Coastguard Worker }
1409*495ae853SAndroid Build Coastguard Worker 
1410*495ae853SAndroid Build Coastguard Worker /**
1411*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1412*495ae853SAndroid Build Coastguard Worker *
1413*495ae853SAndroid Build Coastguard Worker * @brief
1414*495ae853SAndroid Build Coastguard Worker *  Picture level initializations
1415*495ae853SAndroid Build Coastguard Worker *
1416*495ae853SAndroid Build Coastguard Worker * @par Description:
1417*495ae853SAndroid Build Coastguard Worker *  Before beginning to encode the frame, the current function initializes all
1418*495ae853SAndroid Build Coastguard Worker *  the ctxts (proc, entropy, me, ...) basing on the input configured params.
1419*495ae853SAndroid Build Coastguard Worker *  It locates space for storing recon in the encoder picture buffer set, fetches
1420*495ae853SAndroid Build Coastguard Worker *  reference frame from encoder picture buffer set. Calls RC pre-enc to get
1421*495ae853SAndroid Build Coastguard Worker *  qp and pic type for the current frame. Queues proc jobs so that
1422*495ae853SAndroid Build Coastguard Worker *  the other threads can begin encoding. In brief, this function sets up the
1423*495ae853SAndroid Build Coastguard Worker *  tone for the entire encoder.
1424*495ae853SAndroid Build Coastguard Worker *
1425*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
1426*495ae853SAndroid Build Coastguard Worker *  Pointer to codec context
1427*495ae853SAndroid Build Coastguard Worker *
1428*495ae853SAndroid Build Coastguard Worker * @param[in] ps_inp_buf
1429*495ae853SAndroid Build Coastguard Worker *  Pointer to input buffer context
1430*495ae853SAndroid Build Coastguard Worker *
1431*495ae853SAndroid Build Coastguard Worker * @returns  error_status
1432*495ae853SAndroid Build Coastguard Worker *
1433*495ae853SAndroid Build Coastguard Worker * @remarks
1434*495ae853SAndroid Build Coastguard Worker *
1435*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1436*495ae853SAndroid Build Coastguard Worker */
ih264e_pic_init(codec_t * ps_codec,inp_buf_t * ps_inp_buf)1437*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf)
1438*495ae853SAndroid Build Coastguard Worker {
1439*495ae853SAndroid Build Coastguard Worker     /* error status */
1440*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
1441*495ae853SAndroid Build Coastguard Worker     IH264_ERROR_T ret = IH264_SUCCESS;
1442*495ae853SAndroid Build Coastguard Worker 
1443*495ae853SAndroid Build Coastguard Worker     /* mv buff bank */
1444*495ae853SAndroid Build Coastguard Worker     mv_buf_t *ps_mv_buf = NULL;
1445*495ae853SAndroid Build Coastguard Worker     WORD32 cur_mv_bank_buf_id;
1446*495ae853SAndroid Build Coastguard Worker 
1447*495ae853SAndroid Build Coastguard Worker     /* recon buffer set */
1448*495ae853SAndroid Build Coastguard Worker     pic_buf_t *ps_cur_pic;
1449*495ae853SAndroid Build Coastguard Worker     WORD32 cur_pic_buf_id;
1450*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
1451*495ae853SAndroid Build Coastguard Worker 
1452*495ae853SAndroid Build Coastguard Worker     /* ref buffer set */
1453*495ae853SAndroid Build Coastguard Worker     pic_buf_t *aps_ref_pic[MAX_REF_PIC_CNT] = {NULL, NULL};
1454*495ae853SAndroid Build Coastguard Worker     mv_buf_t *aps_mv_buf[MAX_REF_PIC_CNT] = {NULL, NULL};
1455*495ae853SAndroid Build Coastguard Worker     WORD32 ref_set_id;
1456*495ae853SAndroid Build Coastguard Worker 
1457*495ae853SAndroid Build Coastguard Worker     /* pic time stamp */
1458*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
1459*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
1460*495ae853SAndroid Build Coastguard Worker 
1461*495ae853SAndroid Build Coastguard Worker     /* indices to access curr/prev frame info */
1462*495ae853SAndroid Build Coastguard Worker     WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
1463*495ae853SAndroid Build Coastguard Worker 
1464*495ae853SAndroid Build Coastguard Worker     /* curr pic type */
1465*495ae853SAndroid Build Coastguard Worker     PIC_TYPE_T *pic_type = &ps_codec->pic_type;
1466*495ae853SAndroid Build Coastguard Worker 
1467*495ae853SAndroid Build Coastguard Worker     /* Diamond search Iteration Max Cnt */
1468*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_num_layers =
1469*495ae853SAndroid Build Coastguard Worker                     (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST) ?
1470*495ae853SAndroid Build Coastguard Worker                                     (NUM_LAYERS >> 2) : NUM_LAYERS;
1471*495ae853SAndroid Build Coastguard Worker 
1472*495ae853SAndroid Build Coastguard Worker     /* enable fast sad */
1473*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_enable_fast_sad = ps_codec->s_cfg.u4_enable_fast_sad;
1474*495ae853SAndroid Build Coastguard Worker 
1475*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1476*495ae853SAndroid Build Coastguard Worker     /*                     INITIALIZE CODEC CONTEXT                     */
1477*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1478*495ae853SAndroid Build Coastguard Worker     /* slice_type */
1479*495ae853SAndroid Build Coastguard Worker     if ((PIC_I == *pic_type) || (PIC_IDR == *pic_type))
1480*495ae853SAndroid Build Coastguard Worker     {
1481*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_slice_type = ISLICE;
1482*495ae853SAndroid Build Coastguard Worker     }
1483*495ae853SAndroid Build Coastguard Worker     else if (PIC_P == *pic_type)
1484*495ae853SAndroid Build Coastguard Worker     {
1485*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_slice_type = PSLICE;
1486*495ae853SAndroid Build Coastguard Worker     }
1487*495ae853SAndroid Build Coastguard Worker     else if(PIC_B == *pic_type)
1488*495ae853SAndroid Build Coastguard Worker     {
1489*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_slice_type = BSLICE;
1490*495ae853SAndroid Build Coastguard Worker     }
1491*495ae853SAndroid Build Coastguard Worker 
1492*495ae853SAndroid Build Coastguard Worker 
1493*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
1494*495ae853SAndroid Build Coastguard Worker      * Set up variables for sending frame number, poc and reference
1495*495ae853SAndroid Build Coastguard Worker      *   a) Set up alt ref too
1496*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
1497*495ae853SAndroid Build Coastguard Worker 
1498*495ae853SAndroid Build Coastguard Worker     /* Check and set if the current frame is reference or not */
1499*495ae853SAndroid Build Coastguard Worker     ps_codec->u4_is_curr_frm_ref = 0;
1500*495ae853SAndroid Build Coastguard Worker 
1501*495ae853SAndroid Build Coastguard Worker     /* This frame is reference if its not a B pic, pending approval from alt ref */
1502*495ae853SAndroid Build Coastguard Worker     ps_codec->u4_is_curr_frm_ref = (*pic_type != PIC_B);
1503*495ae853SAndroid Build Coastguard Worker 
1504*495ae853SAndroid Build Coastguard Worker     /* In case if its a P pic, we will decide according to alt ref also */
1505*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_enable_alt_ref && (*pic_type == PIC_P)
1506*495ae853SAndroid Build Coastguard Worker                     && (ps_codec->i4_pic_cnt
1507*495ae853SAndroid Build Coastguard Worker                                     % (ps_codec->s_cfg.u4_enable_alt_ref + 1)))
1508*495ae853SAndroid Build Coastguard Worker     {
1509*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_is_curr_frm_ref = 0;
1510*495ae853SAndroid Build Coastguard Worker     }
1511*495ae853SAndroid Build Coastguard Worker 
1512*495ae853SAndroid Build Coastguard Worker     /*
1513*495ae853SAndroid Build Coastguard Worker      * Override everything in case of IDR
1514*495ae853SAndroid Build Coastguard Worker      * Note that in case of IDR, at this point ps_codec->u4_is_curr_frm_ref must
1515*495ae853SAndroid Build Coastguard Worker      * be 1
1516*495ae853SAndroid Build Coastguard Worker      */
1517*495ae853SAndroid Build Coastguard Worker 
1518*495ae853SAndroid Build Coastguard Worker     /* is this an IDR pic */
1519*495ae853SAndroid Build Coastguard Worker     ps_codec->u4_is_idr = 0;
1520*495ae853SAndroid Build Coastguard Worker 
1521*495ae853SAndroid Build Coastguard Worker     if (PIC_IDR == *pic_type)
1522*495ae853SAndroid Build Coastguard Worker     {
1523*495ae853SAndroid Build Coastguard Worker         /* set idr flag */
1524*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_is_idr = 1;
1525*495ae853SAndroid Build Coastguard Worker 
1526*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_restore_frame_num = ps_codec->i4_frame_num;
1527*495ae853SAndroid Build Coastguard Worker         /* reset frame num */
1528*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_frame_num = 0;
1529*495ae853SAndroid Build Coastguard Worker 
1530*495ae853SAndroid Build Coastguard Worker         /* idr_pic_id */
1531*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_idr_pic_id++;
1532*495ae853SAndroid Build Coastguard Worker     }
1533*495ae853SAndroid Build Coastguard Worker 
1534*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
1535*495ae853SAndroid Build Coastguard Worker      * Set up Deblock
1536*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
1537*495ae853SAndroid Build Coastguard Worker 
1538*495ae853SAndroid Build Coastguard Worker     /* set deblock disable flags based on disable deblock level */
1539*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_disable_deblk_pic = 1;
1540*495ae853SAndroid Build Coastguard Worker 
1541*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_0)
1542*495ae853SAndroid Build Coastguard Worker     {
1543*495ae853SAndroid Build Coastguard Worker         /* enable deblocking */
1544*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_disable_deblk_pic = 0;
1545*495ae853SAndroid Build Coastguard Worker     }
1546*495ae853SAndroid Build Coastguard Worker     else if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_2)
1547*495ae853SAndroid Build Coastguard Worker     {
1548*495ae853SAndroid Build Coastguard Worker         /* enable deblocking after a period of frames */
1549*495ae853SAndroid Build Coastguard Worker         if (ps_codec->i4_disable_deblk_pic_cnt == DISABLE_DEBLOCK_INTERVAL
1550*495ae853SAndroid Build Coastguard Worker                         || ps_codec->i4_slice_type == ISLICE)
1551*495ae853SAndroid Build Coastguard Worker         {
1552*495ae853SAndroid Build Coastguard Worker             ps_codec->i4_disable_deblk_pic = 0;
1553*495ae853SAndroid Build Coastguard Worker         }
1554*495ae853SAndroid Build Coastguard Worker     }
1555*495ae853SAndroid Build Coastguard Worker     else if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_3)
1556*495ae853SAndroid Build Coastguard Worker     {
1557*495ae853SAndroid Build Coastguard Worker         if (ps_codec->i4_slice_type == ISLICE)
1558*495ae853SAndroid Build Coastguard Worker         {
1559*495ae853SAndroid Build Coastguard Worker             ps_codec->i4_disable_deblk_pic = 0;
1560*495ae853SAndroid Build Coastguard Worker         }
1561*495ae853SAndroid Build Coastguard Worker     }
1562*495ae853SAndroid Build Coastguard Worker 
1563*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_disable_deblk_pic)
1564*495ae853SAndroid Build Coastguard Worker     {
1565*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_disable_deblk_pic_cnt++;
1566*495ae853SAndroid Build Coastguard Worker     }
1567*495ae853SAndroid Build Coastguard Worker     else
1568*495ae853SAndroid Build Coastguard Worker     {
1569*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_disable_deblk_pic_cnt = 0;
1570*495ae853SAndroid Build Coastguard Worker     }
1571*495ae853SAndroid Build Coastguard Worker 
1572*495ae853SAndroid Build Coastguard Worker     /* In slice mode - lets not deblk mb edges that lie along slice boundaries */
1573*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_disable_deblk_pic == 0)
1574*495ae853SAndroid Build Coastguard Worker     {
1575*495ae853SAndroid Build Coastguard Worker         if (ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
1576*495ae853SAndroid Build Coastguard Worker         {
1577*495ae853SAndroid Build Coastguard Worker             ps_codec->i4_disable_deblk_pic = 2;
1578*495ae853SAndroid Build Coastguard Worker         }
1579*495ae853SAndroid Build Coastguard Worker     }
1580*495ae853SAndroid Build Coastguard Worker 
1581*495ae853SAndroid Build Coastguard Worker     /* error status */
1582*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_error_code = IH264E_SUCCESS;
1583*495ae853SAndroid Build Coastguard Worker 
1584*495ae853SAndroid Build Coastguard Worker     /* populate header */
1585*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_gen_header)
1586*495ae853SAndroid Build Coastguard Worker     {
1587*495ae853SAndroid Build Coastguard Worker         /* sps */
1588*495ae853SAndroid Build Coastguard Worker         sps_t *ps_sps = NULL;
1589*495ae853SAndroid Build Coastguard Worker 
1590*495ae853SAndroid Build Coastguard Worker         /* pps */
1591*495ae853SAndroid Build Coastguard Worker         pps_t *ps_pps = NULL;
1592*495ae853SAndroid Build Coastguard Worker 
1593*495ae853SAndroid Build Coastguard Worker         /*ps_codec->i4_pps_id ++;*/
1594*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_pps_id %= MAX_PPS_CNT;
1595*495ae853SAndroid Build Coastguard Worker 
1596*495ae853SAndroid Build Coastguard Worker         /*ps_codec->i4_sps_id ++;*/
1597*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_sps_id %= MAX_SPS_CNT;
1598*495ae853SAndroid Build Coastguard Worker 
1599*495ae853SAndroid Build Coastguard Worker         /* populate sps header */
1600*495ae853SAndroid Build Coastguard Worker         ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id;
1601*495ae853SAndroid Build Coastguard Worker         ih264e_populate_sps(ps_codec, ps_sps);
1602*495ae853SAndroid Build Coastguard Worker 
1603*495ae853SAndroid Build Coastguard Worker         /* populate pps header */
1604*495ae853SAndroid Build Coastguard Worker         ps_pps = ps_codec->ps_pps_base + ps_codec->i4_pps_id;
1605*495ae853SAndroid Build Coastguard Worker         ih264e_populate_pps(ps_codec, ps_pps);
1606*495ae853SAndroid Build Coastguard Worker     }
1607*495ae853SAndroid Build Coastguard Worker 
1608*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
1609*495ae853SAndroid Build Coastguard Worker      *  Reference and MV bank Buffer Manager
1610*495ae853SAndroid Build Coastguard Worker      *  Here we will
1611*495ae853SAndroid Build Coastguard Worker      *      1) Find the correct ref pics for the current frame
1612*495ae853SAndroid Build Coastguard Worker      *      2) Free the ref pic that is not going to be used anywhere
1613*495ae853SAndroid Build Coastguard Worker      *      3) Find a free buff from the list and assign it as the recon of
1614*495ae853SAndroid Build Coastguard Worker      *         current frame
1615*495ae853SAndroid Build Coastguard Worker      *
1616*495ae853SAndroid Build Coastguard Worker      *  1) Finding correct ref pic
1617*495ae853SAndroid Build Coastguard Worker      *      All pics needed for future are arranged in a picture list called
1618*495ae853SAndroid Build Coastguard Worker      *      ps_codec->as_ref_set. Each picture in this will have a pic buffer and
1619*495ae853SAndroid Build Coastguard Worker      *      MV buffer that is marked appropriately as BUF_MGR_REF, BUF_MGR_IO or
1620*495ae853SAndroid Build Coastguard Worker      *      BUF_MGR_CODEC. Also the pic_cnt and poc will also be present.
1621*495ae853SAndroid Build Coastguard Worker      *      Hence to find the ref pic we will loop through the list and find
1622*495ae853SAndroid Build Coastguard Worker      *      2 pictures with maximum i4_pic_cnt .
1623*495ae853SAndroid Build Coastguard Worker      *
1624*495ae853SAndroid Build Coastguard Worker      *      note that i4_pic_cnt == -1 is used to filter uninit ref pics.
1625*495ae853SAndroid Build Coastguard Worker      *      Now since we only have max two ref pics, we will always find max 2
1626*495ae853SAndroid Build Coastguard Worker      *      ref pics.
1627*495ae853SAndroid Build Coastguard Worker      *
1628*495ae853SAndroid Build Coastguard Worker      *  2), 3) Self explanatory
1629*495ae853SAndroid Build Coastguard Worker      ***************************************************************************/
1630*495ae853SAndroid Build Coastguard Worker     {
1631*495ae853SAndroid Build Coastguard Worker         /* Search for buffs with maximum pic cnt */
1632*495ae853SAndroid Build Coastguard Worker 
1633*495ae853SAndroid Build Coastguard Worker         WORD32 max_pic_cnt[] = { -1, -1 };
1634*495ae853SAndroid Build Coastguard Worker 
1635*495ae853SAndroid Build Coastguard Worker         mv_buf_t *ps_mv_buf_to_free[] = { NULL, NULL };
1636*495ae853SAndroid Build Coastguard Worker 
1637*495ae853SAndroid Build Coastguard Worker         /* temp var */
1638*495ae853SAndroid Build Coastguard Worker         WORD32 i, buf_status;
1639*495ae853SAndroid Build Coastguard Worker 
1640*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
1641*495ae853SAndroid Build Coastguard Worker         {
1642*495ae853SAndroid Build Coastguard Worker             if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
1643*495ae853SAndroid Build Coastguard Worker                 continue;
1644*495ae853SAndroid Build Coastguard Worker 
1645*495ae853SAndroid Build Coastguard Worker             buf_status = ih264_buf_mgr_get_status(
1646*495ae853SAndroid Build Coastguard Worker                             ps_codec->pv_ref_buf_mgr,
1647*495ae853SAndroid Build Coastguard Worker                             ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
1648*495ae853SAndroid Build Coastguard Worker 
1649*495ae853SAndroid Build Coastguard Worker             /* Ideally we should look for buffer status of MV BUFF also. But since
1650*495ae853SAndroid Build Coastguard Worker              * the correponding MV buffs also will be at the same state. It dosent
1651*495ae853SAndroid Build Coastguard Worker              * matter as of now. But the check will make the logic better */
1652*495ae853SAndroid Build Coastguard Worker             if ((max_pic_cnt[0] < ps_codec->as_ref_set[i].i4_pic_cnt)
1653*495ae853SAndroid Build Coastguard Worker                             && (buf_status & BUF_MGR_REF))
1654*495ae853SAndroid Build Coastguard Worker             {
1655*495ae853SAndroid Build Coastguard Worker                 if (max_pic_cnt[1] < ps_codec->as_ref_set[i].i4_pic_cnt)
1656*495ae853SAndroid Build Coastguard Worker                 {
1657*495ae853SAndroid Build Coastguard Worker                     max_pic_cnt[0] = max_pic_cnt[1];
1658*495ae853SAndroid Build Coastguard Worker                     aps_ref_pic[0] = aps_ref_pic[1];
1659*495ae853SAndroid Build Coastguard Worker                     aps_mv_buf[0] = aps_mv_buf[1];
1660*495ae853SAndroid Build Coastguard Worker 
1661*495ae853SAndroid Build Coastguard Worker                     ps_mv_buf_to_free[0] = ps_mv_buf_to_free[1];
1662*495ae853SAndroid Build Coastguard Worker 
1663*495ae853SAndroid Build Coastguard Worker                     max_pic_cnt[1] = ps_codec->as_ref_set[i].i4_pic_cnt;
1664*495ae853SAndroid Build Coastguard Worker                     aps_ref_pic[1] = ps_codec->as_ref_set[i].ps_pic_buf;
1665*495ae853SAndroid Build Coastguard Worker                     aps_mv_buf[1] = ps_codec->as_ref_set[i].ps_mv_buf;
1666*495ae853SAndroid Build Coastguard Worker                     ps_mv_buf_to_free[1] = ps_codec->as_ref_set[i].ps_mv_buf;
1667*495ae853SAndroid Build Coastguard Worker 
1668*495ae853SAndroid Build Coastguard Worker                 }
1669*495ae853SAndroid Build Coastguard Worker                 else
1670*495ae853SAndroid Build Coastguard Worker                 {
1671*495ae853SAndroid Build Coastguard Worker                     max_pic_cnt[0] = ps_codec->as_ref_set[i].i4_pic_cnt;
1672*495ae853SAndroid Build Coastguard Worker                     aps_ref_pic[0] = ps_codec->as_ref_set[i].ps_pic_buf;
1673*495ae853SAndroid Build Coastguard Worker                     aps_mv_buf[0] = ps_codec->as_ref_set[i].ps_mv_buf;
1674*495ae853SAndroid Build Coastguard Worker                     ps_mv_buf_to_free[0] = ps_codec->as_ref_set[i].ps_mv_buf;
1675*495ae853SAndroid Build Coastguard Worker                 }
1676*495ae853SAndroid Build Coastguard Worker             }
1677*495ae853SAndroid Build Coastguard Worker         }
1678*495ae853SAndroid Build Coastguard Worker 
1679*495ae853SAndroid Build Coastguard Worker         /*
1680*495ae853SAndroid Build Coastguard Worker          * Now if the current picture is I or P, we discard the back ref pic and
1681*495ae853SAndroid Build Coastguard Worker          * assign forward ref as backward ref
1682*495ae853SAndroid Build Coastguard Worker          */
1683*495ae853SAndroid Build Coastguard Worker         if (*pic_type != PIC_B)
1684*495ae853SAndroid Build Coastguard Worker         {
1685*495ae853SAndroid Build Coastguard Worker             if (ps_mv_buf_to_free[0])
1686*495ae853SAndroid Build Coastguard Worker             {
1687*495ae853SAndroid Build Coastguard Worker                 /* release this frame from reference list */
1688*495ae853SAndroid Build Coastguard Worker                 ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr,
1689*495ae853SAndroid Build Coastguard Worker                                       ps_mv_buf_to_free[0]->i4_buf_id,
1690*495ae853SAndroid Build Coastguard Worker                                       BUF_MGR_REF);
1691*495ae853SAndroid Build Coastguard Worker 
1692*495ae853SAndroid Build Coastguard Worker                 ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
1693*495ae853SAndroid Build Coastguard Worker                                       aps_ref_pic[0]->i4_buf_id, BUF_MGR_REF);
1694*495ae853SAndroid Build Coastguard Worker             }
1695*495ae853SAndroid Build Coastguard Worker 
1696*495ae853SAndroid Build Coastguard Worker             max_pic_cnt[0] = max_pic_cnt[1];
1697*495ae853SAndroid Build Coastguard Worker             aps_ref_pic[0] = aps_ref_pic[1];
1698*495ae853SAndroid Build Coastguard Worker             aps_mv_buf[0] = aps_mv_buf[1];
1699*495ae853SAndroid Build Coastguard Worker 
1700*495ae853SAndroid Build Coastguard Worker             /* Dummy */
1701*495ae853SAndroid Build Coastguard Worker             max_pic_cnt[1] = -1;
1702*495ae853SAndroid Build Coastguard Worker         }
1703*495ae853SAndroid Build Coastguard Worker 
1704*495ae853SAndroid Build Coastguard Worker         /*
1705*495ae853SAndroid Build Coastguard Worker          * Mark all reference pic with unused buffers to be free
1706*495ae853SAndroid Build Coastguard Worker          * We need this step since each one, ie ref, recon io etc only unset their
1707*495ae853SAndroid Build Coastguard Worker          * respective flags. Hence we need to combine togather and mark the ref set
1708*495ae853SAndroid Build Coastguard Worker          * accordingly
1709*495ae853SAndroid Build Coastguard Worker          */
1710*495ae853SAndroid Build Coastguard Worker         ref_set_id = -1;
1711*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
1712*495ae853SAndroid Build Coastguard Worker         {
1713*495ae853SAndroid Build Coastguard Worker             if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
1714*495ae853SAndroid Build Coastguard Worker             {
1715*495ae853SAndroid Build Coastguard Worker                 ref_set_id = i;
1716*495ae853SAndroid Build Coastguard Worker                 continue;
1717*495ae853SAndroid Build Coastguard Worker             }
1718*495ae853SAndroid Build Coastguard Worker 
1719*495ae853SAndroid Build Coastguard Worker             buf_status = ih264_buf_mgr_get_status(
1720*495ae853SAndroid Build Coastguard Worker                             ps_codec->pv_ref_buf_mgr,
1721*495ae853SAndroid Build Coastguard Worker                             ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
1722*495ae853SAndroid Build Coastguard Worker 
1723*495ae853SAndroid Build Coastguard Worker             if ((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
1724*495ae853SAndroid Build Coastguard Worker             {
1725*495ae853SAndroid Build Coastguard Worker                 ps_codec->as_ref_set[i].i4_pic_cnt = -1;
1726*495ae853SAndroid Build Coastguard Worker                 ps_codec->as_ref_set[i].i4_poc = 32768;
1727*495ae853SAndroid Build Coastguard Worker 
1728*495ae853SAndroid Build Coastguard Worker                 ref_set_id = i;
1729*495ae853SAndroid Build Coastguard Worker             }
1730*495ae853SAndroid Build Coastguard Worker         }
1731*495ae853SAndroid Build Coastguard Worker         /* An asssert failure here means we donot have any free buffs */
1732*495ae853SAndroid Build Coastguard Worker         ASSERT(ref_set_id >= 0);
1733*495ae853SAndroid Build Coastguard Worker     }
1734*495ae853SAndroid Build Coastguard Worker 
1735*495ae853SAndroid Build Coastguard Worker     {
1736*495ae853SAndroid Build Coastguard Worker         /*****************************************************************/
1737*495ae853SAndroid Build Coastguard Worker         /* Get free MV Bank to hold current picture's motion vector data */
1738*495ae853SAndroid Build Coastguard Worker         /* If there are no free buffers then return with an error code.  */
1739*495ae853SAndroid Build Coastguard Worker         /* If the buffer is to be freed by another thread, change the    */
1740*495ae853SAndroid Build Coastguard Worker         /* following to call thread yield and wait for buffer to be freed*/
1741*495ae853SAndroid Build Coastguard Worker         /*****************************************************************/
1742*495ae853SAndroid Build Coastguard Worker         ps_mv_buf = (mv_buf_t *) ih264_buf_mgr_get_next_free(
1743*495ae853SAndroid Build Coastguard Worker                         (buf_mgr_t *) ps_codec->pv_mv_buf_mgr,
1744*495ae853SAndroid Build Coastguard Worker                         &cur_mv_bank_buf_id);
1745*495ae853SAndroid Build Coastguard Worker 
1746*495ae853SAndroid Build Coastguard Worker         if (NULL == ps_mv_buf)
1747*495ae853SAndroid Build Coastguard Worker         {
1748*495ae853SAndroid Build Coastguard Worker             return IH264E_NO_FREE_MVBANK;
1749*495ae853SAndroid Build Coastguard Worker         }
1750*495ae853SAndroid Build Coastguard Worker 
1751*495ae853SAndroid Build Coastguard Worker         /* mark the buffer as needed for reference if the curr pic is available for ref */
1752*495ae853SAndroid Build Coastguard Worker         if (ps_codec->u4_is_curr_frm_ref)
1753*495ae853SAndroid Build Coastguard Worker         {
1754*495ae853SAndroid Build Coastguard Worker             ih264_buf_mgr_set_status(ps_codec->pv_mv_buf_mgr,
1755*495ae853SAndroid Build Coastguard Worker                                      cur_mv_bank_buf_id, BUF_MGR_REF);
1756*495ae853SAndroid Build Coastguard Worker         }
1757*495ae853SAndroid Build Coastguard Worker 
1758*495ae853SAndroid Build Coastguard Worker         /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
1759*495ae853SAndroid Build Coastguard Worker          * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
1760*495ae853SAndroid Build Coastguard Worker          * and getting a buffer id to free
1761*495ae853SAndroid Build Coastguard Worker          */
1762*495ae853SAndroid Build Coastguard Worker         ps_mv_buf->i4_abs_poc = ps_codec->i4_abs_pic_order_cnt;
1763*495ae853SAndroid Build Coastguard Worker         ps_mv_buf->i4_buf_id = cur_mv_bank_buf_id;
1764*495ae853SAndroid Build Coastguard Worker     }
1765*495ae853SAndroid Build Coastguard Worker 
1766*495ae853SAndroid Build Coastguard Worker     {
1767*495ae853SAndroid Build Coastguard Worker         /*****************************************************************/
1768*495ae853SAndroid Build Coastguard Worker         /* Get free pic buf to hold current picture's recon data         */
1769*495ae853SAndroid Build Coastguard Worker         /* If there are no free buffers then return with an error code.  */
1770*495ae853SAndroid Build Coastguard Worker         /* If the buffer is to be freed by another thread, change the    */
1771*495ae853SAndroid Build Coastguard Worker         /* following to call thread yield and wait for buffer to be freed*/
1772*495ae853SAndroid Build Coastguard Worker         /*****************************************************************/
1773*495ae853SAndroid Build Coastguard Worker         ps_cur_pic = (pic_buf_t *) ih264_buf_mgr_get_next_free(
1774*495ae853SAndroid Build Coastguard Worker                         (buf_mgr_t *) ps_codec->pv_ref_buf_mgr,
1775*495ae853SAndroid Build Coastguard Worker                         &cur_pic_buf_id);
1776*495ae853SAndroid Build Coastguard Worker 
1777*495ae853SAndroid Build Coastguard Worker         if (NULL == ps_cur_pic)
1778*495ae853SAndroid Build Coastguard Worker         {
1779*495ae853SAndroid Build Coastguard Worker             return IH264E_NO_FREE_PICBUF;
1780*495ae853SAndroid Build Coastguard Worker         }
1781*495ae853SAndroid Build Coastguard Worker 
1782*495ae853SAndroid Build Coastguard Worker         /* mark the buffer as needed for reference if the curr pic is available for ref */
1783*495ae853SAndroid Build Coastguard Worker         if (ps_codec->u4_is_curr_frm_ref)
1784*495ae853SAndroid Build Coastguard Worker         {
1785*495ae853SAndroid Build Coastguard Worker             ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id,
1786*495ae853SAndroid Build Coastguard Worker                                      BUF_MGR_REF);
1787*495ae853SAndroid Build Coastguard Worker         }
1788*495ae853SAndroid Build Coastguard Worker 
1789*495ae853SAndroid Build Coastguard Worker         /* Mark the current buffer as needed for IO if recon is enabled */
1790*495ae853SAndroid Build Coastguard Worker         if (1 == ps_codec->s_cfg.u4_enable_recon)
1791*495ae853SAndroid Build Coastguard Worker         {
1792*495ae853SAndroid Build Coastguard Worker             ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id,
1793*495ae853SAndroid Build Coastguard Worker                                      BUF_MGR_IO);
1794*495ae853SAndroid Build Coastguard Worker         }
1795*495ae853SAndroid Build Coastguard Worker 
1796*495ae853SAndroid Build Coastguard Worker         /* Associate input timestamp with current buffer */
1797*495ae853SAndroid Build Coastguard Worker         ps_cur_pic->u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
1798*495ae853SAndroid Build Coastguard Worker         ps_cur_pic->u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
1799*495ae853SAndroid Build Coastguard Worker 
1800*495ae853SAndroid Build Coastguard Worker         ps_cur_pic->i4_abs_poc = ps_codec->i4_poc;
1801*495ae853SAndroid Build Coastguard Worker         ps_cur_pic->i4_poc_lsb = ps_codec->i4_pic_order_cnt_lsb;
1802*495ae853SAndroid Build Coastguard Worker 
1803*495ae853SAndroid Build Coastguard Worker         ps_cur_pic->i4_buf_id = cur_pic_buf_id;
1804*495ae853SAndroid Build Coastguard Worker 
1805*495ae853SAndroid Build Coastguard Worker         pu1_cur_pic_luma = ps_cur_pic->pu1_luma;
1806*495ae853SAndroid Build Coastguard Worker         pu1_cur_pic_chroma = ps_cur_pic->pu1_chroma;
1807*495ae853SAndroid Build Coastguard Worker     }
1808*495ae853SAndroid Build Coastguard Worker 
1809*495ae853SAndroid Build Coastguard Worker     /*
1810*495ae853SAndroid Build Coastguard Worker      * Add the current picture to ref list independent of the fact that it is used
1811*495ae853SAndroid Build Coastguard Worker      * as reference or not. This is because, now recon is not in sync with output
1812*495ae853SAndroid Build Coastguard Worker      * hence we may need the current recon after some delay. By adding it to ref list
1813*495ae853SAndroid Build Coastguard Worker      * we can retrieve the recon any time we want. The information that it is used
1814*495ae853SAndroid Build Coastguard Worker      * for ref can still be found by checking the buffer status of pic buf.
1815*495ae853SAndroid Build Coastguard Worker      */
1816*495ae853SAndroid Build Coastguard Worker     {
1817*495ae853SAndroid Build Coastguard Worker         ps_codec->as_ref_set[ref_set_id].i4_pic_cnt = ps_codec->i4_pic_cnt;
1818*495ae853SAndroid Build Coastguard Worker         ps_codec->as_ref_set[ref_set_id].i4_poc = ps_codec->i4_poc;
1819*495ae853SAndroid Build Coastguard Worker         ps_codec->as_ref_set[ref_set_id].ps_mv_buf = ps_mv_buf;
1820*495ae853SAndroid Build Coastguard Worker         ps_codec->as_ref_set[ref_set_id].ps_pic_buf = ps_cur_pic;
1821*495ae853SAndroid Build Coastguard Worker     }
1822*495ae853SAndroid Build Coastguard Worker 
1823*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1824*495ae853SAndroid Build Coastguard Worker     /*                     INITIALIZE PROCESS CONTEXT                   */
1825*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1826*495ae853SAndroid Build Coastguard Worker     {
1827*495ae853SAndroid Build Coastguard Worker         /* temp var */
1828*495ae853SAndroid Build Coastguard Worker         WORD32 i, j = 0;
1829*495ae853SAndroid Build Coastguard Worker 
1830*495ae853SAndroid Build Coastguard Worker         /* curr proc ctxt */
1831*495ae853SAndroid Build Coastguard Worker         process_ctxt_t *ps_proc = NULL;
1832*495ae853SAndroid Build Coastguard Worker 
1833*495ae853SAndroid Build Coastguard Worker         j = ctxt_sel * MAX_PROCESS_THREADS;
1834*495ae853SAndroid Build Coastguard Worker 
1835*495ae853SAndroid Build Coastguard Worker         /* begin init */
1836*495ae853SAndroid Build Coastguard Worker         for (i = j; i < (j + MAX_PROCESS_THREADS); i++)
1837*495ae853SAndroid Build Coastguard Worker         {
1838*495ae853SAndroid Build Coastguard Worker             ps_proc = &ps_codec->as_process[i];
1839*495ae853SAndroid Build Coastguard Worker 
1840*495ae853SAndroid Build Coastguard Worker             /* luma src buffer */
1841*495ae853SAndroid Build Coastguard Worker             if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE)
1842*495ae853SAndroid Build Coastguard Worker             {
1843*495ae853SAndroid Build Coastguard Worker                 ps_proc->pu1_src_buf_luma_base = ps_codec->pu1_y_csc_buf_base;
1844*495ae853SAndroid Build Coastguard Worker             }
1845*495ae853SAndroid Build Coastguard Worker             else
1846*495ae853SAndroid Build Coastguard Worker             {
1847*495ae853SAndroid Build Coastguard Worker                 ps_proc->pu1_src_buf_luma_base =
1848*495ae853SAndroid Build Coastguard Worker                                 ps_inp_buf->s_raw_buf.apv_bufs[0];
1849*495ae853SAndroid Build Coastguard Worker             }
1850*495ae853SAndroid Build Coastguard Worker 
1851*495ae853SAndroid Build Coastguard Worker             /* chroma src buffer */
1852*495ae853SAndroid Build Coastguard Worker             if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE
1853*495ae853SAndroid Build Coastguard Worker                             || ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420P)
1854*495ae853SAndroid Build Coastguard Worker             {
1855*495ae853SAndroid Build Coastguard Worker                 ps_proc->pu1_src_buf_chroma_base =
1856*495ae853SAndroid Build Coastguard Worker                                 ps_codec->pu1_uv_csc_buf_base;
1857*495ae853SAndroid Build Coastguard Worker             }
1858*495ae853SAndroid Build Coastguard Worker             else
1859*495ae853SAndroid Build Coastguard Worker             {
1860*495ae853SAndroid Build Coastguard Worker                 ps_proc->pu1_src_buf_chroma_base =
1861*495ae853SAndroid Build Coastguard Worker                                 ps_inp_buf->s_raw_buf.apv_bufs[1];
1862*495ae853SAndroid Build Coastguard Worker             }
1863*495ae853SAndroid Build Coastguard Worker 
1864*495ae853SAndroid Build Coastguard Worker             /* luma rec buffer */
1865*495ae853SAndroid Build Coastguard Worker             ps_proc->pu1_rec_buf_luma_base = pu1_cur_pic_luma;
1866*495ae853SAndroid Build Coastguard Worker 
1867*495ae853SAndroid Build Coastguard Worker             /* chroma rec buffer */
1868*495ae853SAndroid Build Coastguard Worker             ps_proc->pu1_rec_buf_chroma_base = pu1_cur_pic_chroma;
1869*495ae853SAndroid Build Coastguard Worker 
1870*495ae853SAndroid Build Coastguard Worker             /* rec stride */
1871*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_rec_strd = ps_codec->i4_rec_strd;
1872*495ae853SAndroid Build Coastguard Worker 
1873*495ae853SAndroid Build Coastguard Worker             /* frame num */
1874*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_frame_num = ps_codec->i4_frame_num;
1875*495ae853SAndroid Build Coastguard Worker 
1876*495ae853SAndroid Build Coastguard Worker             /* is idr */
1877*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_is_idr = ps_codec->u4_is_idr;
1878*495ae853SAndroid Build Coastguard Worker 
1879*495ae853SAndroid Build Coastguard Worker             /* idr pic id */
1880*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_idr_pic_id = ps_codec->i4_idr_pic_id;
1881*495ae853SAndroid Build Coastguard Worker 
1882*495ae853SAndroid Build Coastguard Worker             /* slice_type */
1883*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_slice_type = ps_codec->i4_slice_type;
1884*495ae853SAndroid Build Coastguard Worker 
1885*495ae853SAndroid Build Coastguard Worker             /* Input width in mbs */
1886*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_wd_mbs = ps_codec->s_cfg.i4_wd_mbs;
1887*495ae853SAndroid Build Coastguard Worker 
1888*495ae853SAndroid Build Coastguard Worker             /* Input height in mbs */
1889*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_ht_mbs = ps_codec->s_cfg.i4_ht_mbs;
1890*495ae853SAndroid Build Coastguard Worker 
1891*495ae853SAndroid Build Coastguard Worker             /* Half x plane offset from pic buf */
1892*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_half_x_offset = 0;
1893*495ae853SAndroid Build Coastguard Worker 
1894*495ae853SAndroid Build Coastguard Worker             /* Half y plane offset from half x plane */
1895*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_half_y_offset = 0;
1896*495ae853SAndroid Build Coastguard Worker 
1897*495ae853SAndroid Build Coastguard Worker             /* Half x plane offset from half y plane */
1898*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_half_xy_offset = 0;
1899*495ae853SAndroid Build Coastguard Worker 
1900*495ae853SAndroid Build Coastguard Worker             /* top row syntax elements */
1901*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_top_row_mb_syntax_ele =
1902*495ae853SAndroid Build Coastguard Worker                             ps_proc->ps_top_row_mb_syntax_ele_base;
1903*495ae853SAndroid Build Coastguard Worker 
1904*495ae853SAndroid Build Coastguard Worker             ps_proc->pu1_top_mb_intra_modes =
1905*495ae853SAndroid Build Coastguard Worker                             ps_proc->pu1_top_mb_intra_modes_base;
1906*495ae853SAndroid Build Coastguard Worker 
1907*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_top_row_pu = ps_proc->ps_top_row_pu_base;
1908*495ae853SAndroid Build Coastguard Worker 
1909*495ae853SAndroid Build Coastguard Worker             /* initialize quant params */
1910*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_frame_qp = ps_codec->u4_frame_qp;
1911*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_mb_qp = ps_codec->u4_frame_qp;
1912*495ae853SAndroid Build Coastguard Worker             ih264e_init_quant_params(ps_proc, ps_proc->u4_frame_qp);
1913*495ae853SAndroid Build Coastguard Worker 
1914*495ae853SAndroid Build Coastguard Worker             /* previous mb qp*/
1915*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_mb_qp_prev = ps_proc->u4_frame_qp;
1916*495ae853SAndroid Build Coastguard Worker 
1917*495ae853SAndroid Build Coastguard Worker             /* Reset frame info */
1918*495ae853SAndroid Build Coastguard Worker             memset(&ps_proc->s_frame_info, 0, sizeof(frame_info_t));
1919*495ae853SAndroid Build Coastguard Worker 
1920*495ae853SAndroid Build Coastguard Worker             /* initialize proc, deblk and ME map */
1921*495ae853SAndroid Build Coastguard Worker             if (i == j)
1922*495ae853SAndroid Build Coastguard Worker             {
1923*495ae853SAndroid Build Coastguard Worker                 /* row '-1' */
1924*495ae853SAndroid Build Coastguard Worker                 memset(ps_proc->pu1_proc_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1925*495ae853SAndroid Build Coastguard Worker                 /* row 0 to ht in mbs */
1926*495ae853SAndroid Build Coastguard Worker                 memset(ps_proc->pu1_proc_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1927*495ae853SAndroid Build Coastguard Worker 
1928*495ae853SAndroid Build Coastguard Worker                 /* row '-1' */
1929*495ae853SAndroid Build Coastguard Worker                 memset(ps_proc->pu1_deblk_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1930*495ae853SAndroid Build Coastguard Worker                 /* row 0 to ht in mbs */
1931*495ae853SAndroid Build Coastguard Worker                 memset(ps_proc->pu1_deblk_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1932*495ae853SAndroid Build Coastguard Worker 
1933*495ae853SAndroid Build Coastguard Worker                 /* row '-1' */
1934*495ae853SAndroid Build Coastguard Worker                 memset(ps_proc->pu1_me_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1935*495ae853SAndroid Build Coastguard Worker                 /* row 0 to ht in mbs */
1936*495ae853SAndroid Build Coastguard Worker                 memset(ps_proc->pu1_me_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1937*495ae853SAndroid Build Coastguard Worker 
1938*495ae853SAndroid Build Coastguard Worker                 /* at the start of air refresh period, reset intra coded map */
1939*495ae853SAndroid Build Coastguard Worker                 if (IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
1940*495ae853SAndroid Build Coastguard Worker                 {
1941*495ae853SAndroid Build Coastguard Worker                     ps_codec->i4_air_pic_cnt = (ps_codec->i4_air_pic_cnt + 1)
1942*495ae853SAndroid Build Coastguard Worker                                     % ps_codec->s_cfg.u4_air_refresh_period;
1943*495ae853SAndroid Build Coastguard Worker 
1944*495ae853SAndroid Build Coastguard Worker                     if (!ps_codec->i4_air_pic_cnt)
1945*495ae853SAndroid Build Coastguard Worker                     {
1946*495ae853SAndroid Build Coastguard Worker                         memset(ps_proc->pu1_is_intra_coded, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1947*495ae853SAndroid Build Coastguard Worker                     }
1948*495ae853SAndroid Build Coastguard Worker                 }
1949*495ae853SAndroid Build Coastguard Worker             }
1950*495ae853SAndroid Build Coastguard Worker 
1951*495ae853SAndroid Build Coastguard Worker             /* deblock level */
1952*495ae853SAndroid Build Coastguard Worker             ps_proc->u4_disable_deblock_level = ps_codec->i4_disable_deblk_pic;
1953*495ae853SAndroid Build Coastguard Worker 
1954*495ae853SAndroid Build Coastguard Worker             /* slice index map */
1955*495ae853SAndroid Build Coastguard Worker             /* no slice */
1956*495ae853SAndroid Build Coastguard Worker             if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_NONE)
1957*495ae853SAndroid Build Coastguard Worker             {
1958*495ae853SAndroid Build Coastguard Worker                 memset(ps_proc->pu1_slice_idx, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1959*495ae853SAndroid Build Coastguard Worker             }
1960*495ae853SAndroid Build Coastguard Worker             /* generate slices for every 'n' rows, 'n' is given through slice param */
1961*495ae853SAndroid Build Coastguard Worker             else if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
1962*495ae853SAndroid Build Coastguard Worker             {
1963*495ae853SAndroid Build Coastguard Worker                 /* slice idx map */
1964*495ae853SAndroid Build Coastguard Worker                 UWORD8 *pu1_slice_idx = ps_proc->pu1_slice_idx;
1965*495ae853SAndroid Build Coastguard Worker 
1966*495ae853SAndroid Build Coastguard Worker                 /* temp var */
1967*495ae853SAndroid Build Coastguard Worker                 WORD32 i4_mb_y = 0, slice_idx = 0, cnt;
1968*495ae853SAndroid Build Coastguard Worker 
1969*495ae853SAndroid Build Coastguard Worker                 while (i4_mb_y < ps_proc->i4_ht_mbs)
1970*495ae853SAndroid Build Coastguard Worker                 {
1971*495ae853SAndroid Build Coastguard Worker                     if (i4_mb_y +(WORD32)ps_codec->s_cfg.u4_slice_param < ps_proc->i4_ht_mbs)
1972*495ae853SAndroid Build Coastguard Worker                     {
1973*495ae853SAndroid Build Coastguard Worker                         cnt = ps_codec->s_cfg.u4_slice_param * ps_proc->i4_wd_mbs;
1974*495ae853SAndroid Build Coastguard Worker                         i4_mb_y += ps_codec->s_cfg.u4_slice_param;
1975*495ae853SAndroid Build Coastguard Worker                     }
1976*495ae853SAndroid Build Coastguard Worker                     else
1977*495ae853SAndroid Build Coastguard Worker                     {
1978*495ae853SAndroid Build Coastguard Worker                         cnt = (ps_proc->i4_ht_mbs - i4_mb_y) * ps_proc->i4_wd_mbs;
1979*495ae853SAndroid Build Coastguard Worker                         i4_mb_y += (ps_proc->i4_ht_mbs - i4_mb_y);
1980*495ae853SAndroid Build Coastguard Worker                     }
1981*495ae853SAndroid Build Coastguard Worker                     memset(pu1_slice_idx, slice_idx, cnt);
1982*495ae853SAndroid Build Coastguard Worker                     slice_idx++;
1983*495ae853SAndroid Build Coastguard Worker                     pu1_slice_idx += cnt;
1984*495ae853SAndroid Build Coastguard Worker                 }
1985*495ae853SAndroid Build Coastguard Worker             }
1986*495ae853SAndroid Build Coastguard Worker 
1987*495ae853SAndroid Build Coastguard Worker             /* Current MV Bank's buffer ID */
1988*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1989*495ae853SAndroid Build Coastguard Worker 
1990*495ae853SAndroid Build Coastguard Worker             /* Pointer to current picture buffer structure */
1991*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_cur_pic = ps_cur_pic;
1992*495ae853SAndroid Build Coastguard Worker 
1993*495ae853SAndroid Build Coastguard Worker             /* Pointer to current pictures mv buffers */
1994*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_cur_mv_buf = ps_mv_buf;
1995*495ae853SAndroid Build Coastguard Worker 
1996*495ae853SAndroid Build Coastguard Worker             /*
1997*495ae853SAndroid Build Coastguard Worker              * pointer to ref picture
1998*495ae853SAndroid Build Coastguard Worker              * 0    : Temporal back reference
1999*495ae853SAndroid Build Coastguard Worker              * 1    : Temporal forward reference
2000*495ae853SAndroid Build Coastguard Worker              */
2001*495ae853SAndroid Build Coastguard Worker             ps_proc->aps_ref_pic[PRED_L0] = aps_ref_pic[PRED_L0];
2002*495ae853SAndroid Build Coastguard Worker             ps_proc->aps_ref_pic[PRED_L1] = aps_ref_pic[PRED_L1];
2003*495ae853SAndroid Build Coastguard Worker             if (ps_codec->pic_type == PIC_B)
2004*495ae853SAndroid Build Coastguard Worker             {
2005*495ae853SAndroid Build Coastguard Worker                 ps_proc->aps_mv_buf[PRED_L0] = aps_mv_buf[PRED_L0];
2006*495ae853SAndroid Build Coastguard Worker                 ps_proc->aps_mv_buf[PRED_L1] = aps_mv_buf[PRED_L1];
2007*495ae853SAndroid Build Coastguard Worker             }
2008*495ae853SAndroid Build Coastguard Worker             else
2009*495ae853SAndroid Build Coastguard Worker             {
2010*495ae853SAndroid Build Coastguard Worker                 /*
2011*495ae853SAndroid Build Coastguard Worker                  * Else is dummy since for non B pic we does not need this
2012*495ae853SAndroid Build Coastguard Worker                  * But an assignment here will help in not having a segfault
2013*495ae853SAndroid Build Coastguard Worker                  * when we calcualte colpic in P slices
2014*495ae853SAndroid Build Coastguard Worker                  */
2015*495ae853SAndroid Build Coastguard Worker                 ps_proc->aps_mv_buf[PRED_L0] = ps_mv_buf;
2016*495ae853SAndroid Build Coastguard Worker                 ps_proc->aps_mv_buf[PRED_L1] = ps_mv_buf;
2017*495ae853SAndroid Build Coastguard Worker             }
2018*495ae853SAndroid Build Coastguard Worker 
2019*495ae853SAndroid Build Coastguard Worker             if ((*pic_type != PIC_IDR) && (*pic_type != PIC_I))
2020*495ae853SAndroid Build Coastguard Worker             {
2021*495ae853SAndroid Build Coastguard Worker                 /* temporal back an forward  ref pointer luma and chroma */
2022*495ae853SAndroid Build Coastguard Worker                 ps_proc->apu1_ref_buf_luma_base[PRED_L0] = aps_ref_pic[PRED_L0]->pu1_luma;
2023*495ae853SAndroid Build Coastguard Worker                 ps_proc->apu1_ref_buf_chroma_base[PRED_L0] = aps_ref_pic[PRED_L0]->pu1_chroma;
2024*495ae853SAndroid Build Coastguard Worker 
2025*495ae853SAndroid Build Coastguard Worker                 ps_proc->apu1_ref_buf_luma_base[PRED_L1] = aps_ref_pic[PRED_L1]->pu1_luma;
2026*495ae853SAndroid Build Coastguard Worker                 ps_proc->apu1_ref_buf_chroma_base[PRED_L1] = aps_ref_pic[PRED_L1]->pu1_chroma;
2027*495ae853SAndroid Build Coastguard Worker             }
2028*495ae853SAndroid Build Coastguard Worker 
2029*495ae853SAndroid Build Coastguard Worker             /* Structure for current input buffer */
2030*495ae853SAndroid Build Coastguard Worker             ps_proc->s_inp_buf = *ps_inp_buf;
2031*495ae853SAndroid Build Coastguard Worker 
2032*495ae853SAndroid Build Coastguard Worker             /* Number of encode frame API calls made */
2033*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_encode_api_call_cnt = ps_codec->i4_encode_api_call_cnt;
2034*495ae853SAndroid Build Coastguard Worker 
2035*495ae853SAndroid Build Coastguard Worker             /* Current Picture count */
2036*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_pic_cnt = ps_codec->i4_pic_cnt;
2037*495ae853SAndroid Build Coastguard Worker 
2038*495ae853SAndroid Build Coastguard Worker             /* error status */
2039*495ae853SAndroid Build Coastguard Worker             ps_proc->i4_error_code = 0;
2040*495ae853SAndroid Build Coastguard Worker 
2041*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2042*495ae853SAndroid Build Coastguard Worker             /*                     INITIALIZE ENTROPY CONTEXT                   */
2043*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2044*495ae853SAndroid Build Coastguard Worker             {
2045*495ae853SAndroid Build Coastguard Worker                 entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
2046*495ae853SAndroid Build Coastguard Worker 
2047*495ae853SAndroid Build Coastguard Worker                 /* start of frame */
2048*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i4_sof = 0;
2049*495ae853SAndroid Build Coastguard Worker 
2050*495ae853SAndroid Build Coastguard Worker                 /* end of frame */
2051*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i4_eof = 0;
2052*495ae853SAndroid Build Coastguard Worker 
2053*495ae853SAndroid Build Coastguard Worker                 /* generate header */
2054*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i4_gen_header = ps_codec->i4_gen_header;
2055*495ae853SAndroid Build Coastguard Worker 
2056*495ae853SAndroid Build Coastguard Worker                 /* sps ref_set_id */
2057*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_sps_id = ps_codec->i4_sps_id;
2058*495ae853SAndroid Build Coastguard Worker 
2059*495ae853SAndroid Build Coastguard Worker                 /* sps base */
2060*495ae853SAndroid Build Coastguard Worker                 ps_entropy->ps_sps_base = ps_codec->ps_sps_base;
2061*495ae853SAndroid Build Coastguard Worker 
2062*495ae853SAndroid Build Coastguard Worker                 /* sps id */
2063*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_pps_id = ps_codec->i4_pps_id;
2064*495ae853SAndroid Build Coastguard Worker 
2065*495ae853SAndroid Build Coastguard Worker                 /* sps base */
2066*495ae853SAndroid Build Coastguard Worker                 ps_entropy->ps_pps_base = ps_codec->ps_pps_base;
2067*495ae853SAndroid Build Coastguard Worker 
2068*495ae853SAndroid Build Coastguard Worker                 /* slice map */
2069*495ae853SAndroid Build Coastguard Worker                 ps_entropy->pu1_slice_idx = ps_proc->pu1_slice_idx;
2070*495ae853SAndroid Build Coastguard Worker 
2071*495ae853SAndroid Build Coastguard Worker                 /* slice hdr base */
2072*495ae853SAndroid Build Coastguard Worker                 ps_entropy->ps_slice_hdr_base = ps_proc->ps_slice_hdr_base;
2073*495ae853SAndroid Build Coastguard Worker 
2074*495ae853SAndroid Build Coastguard Worker                 /* Abs poc */
2075*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i4_abs_pic_order_cnt = ps_proc->ps_codec->i4_poc;
2076*495ae853SAndroid Build Coastguard Worker 
2077*495ae853SAndroid Build Coastguard Worker                 /* initialize entropy map */
2078*495ae853SAndroid Build Coastguard Worker                 if (i == j)
2079*495ae853SAndroid Build Coastguard Worker                 {
2080*495ae853SAndroid Build Coastguard Worker                     /* row '-1' */
2081*495ae853SAndroid Build Coastguard Worker                     memset(ps_entropy->pu1_entropy_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
2082*495ae853SAndroid Build Coastguard Worker                     /* row 0 to ht in mbs */
2083*495ae853SAndroid Build Coastguard Worker                     memset(ps_entropy->pu1_entropy_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
2084*495ae853SAndroid Build Coastguard Worker 
2085*495ae853SAndroid Build Coastguard Worker                     /* intialize cabac tables */
2086*495ae853SAndroid Build Coastguard Worker                     ih264e_init_cabac_table(ps_entropy);
2087*495ae853SAndroid Build Coastguard Worker                 }
2088*495ae853SAndroid Build Coastguard Worker 
2089*495ae853SAndroid Build Coastguard Worker                 /* wd in mbs */
2090*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i4_wd_mbs = ps_proc->i4_wd_mbs;
2091*495ae853SAndroid Build Coastguard Worker 
2092*495ae853SAndroid Build Coastguard Worker                 /* ht in mbs */
2093*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i4_ht_mbs = ps_proc->i4_ht_mbs;
2094*495ae853SAndroid Build Coastguard Worker 
2095*495ae853SAndroid Build Coastguard Worker                 /* transform_8x8_mode_flag */
2096*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i1_transform_8x8_mode_flag = 0;
2097*495ae853SAndroid Build Coastguard Worker 
2098*495ae853SAndroid Build Coastguard Worker                 /* entropy_coding_mode_flag */
2099*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u1_entropy_coding_mode_flag =
2100*495ae853SAndroid Build Coastguard Worker                                 ps_codec->s_cfg.u4_entropy_coding_mode;
2101*495ae853SAndroid Build Coastguard Worker 
2102*495ae853SAndroid Build Coastguard Worker                 /* error code */
2103*495ae853SAndroid Build Coastguard Worker                 ps_entropy->i4_error_code = IH264E_SUCCESS;
2104*495ae853SAndroid Build Coastguard Worker 
2105*495ae853SAndroid Build Coastguard Worker                 /* mb skip run */
2106*495ae853SAndroid Build Coastguard Worker                 *(ps_proc->s_entropy.pi4_mb_skip_run) = 0;
2107*495ae853SAndroid Build Coastguard Worker 
2108*495ae853SAndroid Build Coastguard Worker                 /* last frame to encode */
2109*495ae853SAndroid Build Coastguard Worker                 ps_proc->s_entropy.u4_is_last = ps_inp_buf->u4_is_last;
2110*495ae853SAndroid Build Coastguard Worker 
2111*495ae853SAndroid Build Coastguard Worker                 /* Current Picture count */
2112*495ae853SAndroid Build Coastguard Worker                 ps_proc->s_entropy.i4_pic_cnt = ps_codec->i4_pic_cnt;
2113*495ae853SAndroid Build Coastguard Worker 
2114*495ae853SAndroid Build Coastguard Worker                 /* time stamps */
2115*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_timestamp_low = u4_timestamp_low;
2116*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_timestamp_high = u4_timestamp_high;
2117*495ae853SAndroid Build Coastguard Worker 
2118*495ae853SAndroid Build Coastguard Worker                 /* init frame statistics */
2119*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_header_bits[MB_TYPE_INTRA] = 0;
2120*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_header_bits[MB_TYPE_INTER] = 0;
2121*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_residue_bits[MB_TYPE_INTRA] = 0;
2122*495ae853SAndroid Build Coastguard Worker                 ps_entropy->u4_residue_bits[MB_TYPE_INTER] = 0;
2123*495ae853SAndroid Build Coastguard Worker             }
2124*495ae853SAndroid Build Coastguard Worker 
2125*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2126*495ae853SAndroid Build Coastguard Worker             /*                     INITIALIZE DEBLOCK CONTEXT                   */
2127*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2128*495ae853SAndroid Build Coastguard Worker             {
2129*495ae853SAndroid Build Coastguard Worker                 /* deblk ctxt */
2130*495ae853SAndroid Build Coastguard Worker                 deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
2131*495ae853SAndroid Build Coastguard Worker 
2132*495ae853SAndroid Build Coastguard Worker                 /* slice idx map */
2133*495ae853SAndroid Build Coastguard Worker                 ps_deblk->pu1_slice_idx = ps_proc->pu1_slice_idx;
2134*495ae853SAndroid Build Coastguard Worker             }
2135*495ae853SAndroid Build Coastguard Worker 
2136*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2137*495ae853SAndroid Build Coastguard Worker             /*                     INITIALIZE ME CONTEXT                        */
2138*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2139*495ae853SAndroid Build Coastguard Worker             {
2140*495ae853SAndroid Build Coastguard Worker                 /* me ctxt */
2141*495ae853SAndroid Build Coastguard Worker                 me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2142*495ae853SAndroid Build Coastguard Worker 
2143*495ae853SAndroid Build Coastguard Worker                 /* srch range x */
2144*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->ai2_srch_boundaries[0] =
2145*495ae853SAndroid Build Coastguard Worker                                 ps_codec->s_cfg.u4_srch_rng_x;
2146*495ae853SAndroid Build Coastguard Worker 
2147*495ae853SAndroid Build Coastguard Worker                 /* srch range y */
2148*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->ai2_srch_boundaries[1] =
2149*495ae853SAndroid Build Coastguard Worker                                 ps_codec->s_cfg.u4_srch_rng_y;
2150*495ae853SAndroid Build Coastguard Worker 
2151*495ae853SAndroid Build Coastguard Worker                 /* rec stride */
2152*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->i4_rec_strd = ps_codec->i4_rec_strd;
2153*495ae853SAndroid Build Coastguard Worker 
2154*495ae853SAndroid Build Coastguard Worker                 /* Half x plane offset from pic buf */
2155*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_half_x_offset = ps_proc->u4_half_x_offset;
2156*495ae853SAndroid Build Coastguard Worker 
2157*495ae853SAndroid Build Coastguard Worker                 /* Half y plane offset from half x plane */
2158*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_half_y_offset = ps_proc->u4_half_y_offset;
2159*495ae853SAndroid Build Coastguard Worker 
2160*495ae853SAndroid Build Coastguard Worker                 /* Half x plane offset from half y plane */
2161*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_half_xy_offset = ps_proc->u4_half_xy_offset;
2162*495ae853SAndroid Build Coastguard Worker 
2163*495ae853SAndroid Build Coastguard Worker                 /* enable fast sad */
2164*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_enable_fast_sad = u4_enable_fast_sad;
2165*495ae853SAndroid Build Coastguard Worker 
2166*495ae853SAndroid Build Coastguard Worker                 /* half pel */
2167*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_enable_hpel = ps_codec->s_cfg.u4_enable_hpel;
2168*495ae853SAndroid Build Coastguard Worker 
2169*495ae853SAndroid Build Coastguard Worker                 /* Diamond search Iteration Max Cnt */
2170*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_num_layers = u4_num_layers;
2171*495ae853SAndroid Build Coastguard Worker 
2172*495ae853SAndroid Build Coastguard Worker                 /* me speed preset */
2173*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_me_speed_preset =
2174*495ae853SAndroid Build Coastguard Worker                                 ps_codec->s_cfg.u4_me_speed_preset;
2175*495ae853SAndroid Build Coastguard Worker 
2176*495ae853SAndroid Build Coastguard Worker                 /* qp */
2177*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u1_mb_qp = ps_codec->u4_frame_qp;
2178*495ae853SAndroid Build Coastguard Worker 
2179*495ae853SAndroid Build Coastguard Worker                 if ((i == j) && (0 == ps_codec->i4_poc))
2180*495ae853SAndroid Build Coastguard Worker                 {
2181*495ae853SAndroid Build Coastguard Worker                     /* init mv bits tables */
2182*495ae853SAndroid Build Coastguard Worker                     ih264e_init_mv_bits(ps_me_ctxt);
2183*495ae853SAndroid Build Coastguard Worker                 }
2184*495ae853SAndroid Build Coastguard Worker             }
2185*495ae853SAndroid Build Coastguard Worker 
2186*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_ngbr_avbl = &(ps_proc->s_ngbr_avbl);
2187*495ae853SAndroid Build Coastguard Worker 
2188*495ae853SAndroid Build Coastguard Worker         }
2189*495ae853SAndroid Build Coastguard Worker 
2190*495ae853SAndroid Build Coastguard Worker         /* reset encoder header */
2191*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_gen_header = 0;
2192*495ae853SAndroid Build Coastguard Worker     }
2193*495ae853SAndroid Build Coastguard Worker 
2194*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
2195*495ae853SAndroid Build Coastguard Worker     /*                       ADD JOBS TO THE QUEUE                      */
2196*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
2197*495ae853SAndroid Build Coastguard Worker     {
2198*495ae853SAndroid Build Coastguard Worker         /* job structures */
2199*495ae853SAndroid Build Coastguard Worker         job_t s_job;
2200*495ae853SAndroid Build Coastguard Worker 
2201*495ae853SAndroid Build Coastguard Worker         /* temp var */
2202*495ae853SAndroid Build Coastguard Worker         WORD32 i;
2203*495ae853SAndroid Build Coastguard Worker 
2204*495ae853SAndroid Build Coastguard Worker         /* job class */
2205*495ae853SAndroid Build Coastguard Worker         s_job.i4_cmd = CMD_PROCESS;
2206*495ae853SAndroid Build Coastguard Worker 
2207*495ae853SAndroid Build Coastguard Worker         /* number of mbs to be processed in the current job */
2208*495ae853SAndroid Build Coastguard Worker         s_job.i2_mb_cnt = ps_codec->s_cfg.i4_wd_mbs;
2209*495ae853SAndroid Build Coastguard Worker 
2210*495ae853SAndroid Build Coastguard Worker         /* job start index x */
2211*495ae853SAndroid Build Coastguard Worker         s_job.i2_mb_x = 0;
2212*495ae853SAndroid Build Coastguard Worker 
2213*495ae853SAndroid Build Coastguard Worker         /* proc base idx */
2214*495ae853SAndroid Build Coastguard Worker         s_job.i2_proc_base_idx = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
2215*495ae853SAndroid Build Coastguard Worker 
2216*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < (WORD32)ps_codec->s_cfg.i4_ht_mbs; i++)
2217*495ae853SAndroid Build Coastguard Worker         {
2218*495ae853SAndroid Build Coastguard Worker             /* job start index y */
2219*495ae853SAndroid Build Coastguard Worker             s_job.i2_mb_y = i;
2220*495ae853SAndroid Build Coastguard Worker 
2221*495ae853SAndroid Build Coastguard Worker             /* queue the job */
2222*495ae853SAndroid Build Coastguard Worker             ret = ih264_list_queue(ps_codec->pv_proc_jobq, &s_job, 1);
2223*495ae853SAndroid Build Coastguard Worker             if (ret != IH264_SUCCESS)
2224*495ae853SAndroid Build Coastguard Worker             {
2225*495ae853SAndroid Build Coastguard Worker                 return IH264E_FAIL;
2226*495ae853SAndroid Build Coastguard Worker             }
2227*495ae853SAndroid Build Coastguard Worker         }
2228*495ae853SAndroid Build Coastguard Worker 
2229*495ae853SAndroid Build Coastguard Worker         /* Once all the jobs are queued, terminate the queue */
2230*495ae853SAndroid Build Coastguard Worker         /* Since the threads are created and deleted in each call, terminating
2231*495ae853SAndroid Build Coastguard Worker         here is not an issue */
2232*495ae853SAndroid Build Coastguard Worker         ih264_list_terminate(ps_codec->pv_proc_jobq);
2233*495ae853SAndroid Build Coastguard Worker     }
2234*495ae853SAndroid Build Coastguard Worker 
2235*495ae853SAndroid Build Coastguard Worker     return error_status;
2236*495ae853SAndroid Build Coastguard Worker }
2237*495ae853SAndroid Build Coastguard Worker 
2238*495ae853SAndroid Build Coastguard Worker /**
2239*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2240*495ae853SAndroid Build Coastguard Worker *
2241*495ae853SAndroid Build Coastguard Worker * @brief
2242*495ae853SAndroid Build Coastguard Worker *  Calculate the per-pic and global PSNR
2243*495ae853SAndroid Build Coastguard Worker *
2244*495ae853SAndroid Build Coastguard Worker * @par Description:
2245*495ae853SAndroid Build Coastguard Worker *  This function takes the source and recon luma/chroma buffer pointers from the
2246*495ae853SAndroid Build Coastguard Worker *  codec context and calculates the per-pic and global PSNR for the current encoding
2247*495ae853SAndroid Build Coastguard Worker *  frame.
2248*495ae853SAndroid Build Coastguard Worker *
2249*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
2250*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
2251*495ae853SAndroid Build Coastguard Worker *
2252*495ae853SAndroid Build Coastguard Worker * @returns  none
2253*495ae853SAndroid Build Coastguard Worker *
2254*495ae853SAndroid Build Coastguard Worker * @remarks
2255*495ae853SAndroid Build Coastguard Worker *
2256*495ae853SAndroid Build Coastguard Worker *
2257*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2258*495ae853SAndroid Build Coastguard Worker */
ih264e_compute_quality_stats(process_ctxt_t * ps_proc)2259*495ae853SAndroid Build Coastguard Worker void ih264e_compute_quality_stats(process_ctxt_t *ps_proc)
2260*495ae853SAndroid Build Coastguard Worker {
2261*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
2262*495ae853SAndroid Build Coastguard Worker     WORD32 wd = ps_codec->s_cfg.u4_wd;
2263*495ae853SAndroid Build Coastguard Worker     WORD32 ht = ps_codec->s_cfg.u4_ht;
2264*495ae853SAndroid Build Coastguard Worker     WORD32 disp_wd = ps_codec->s_cfg.u4_disp_wd;
2265*495ae853SAndroid Build Coastguard Worker     WORD32 disp_ht = ps_codec->s_cfg.u4_disp_ht;
2266*495ae853SAndroid Build Coastguard Worker     WORD32 src_strds = ps_proc->i4_src_strd;
2267*495ae853SAndroid Build Coastguard Worker     WORD32 rec_strds = ps_proc->i4_rec_strd;
2268*495ae853SAndroid Build Coastguard Worker     quality_stats_t *ps_pic_quality_stats = NULL;
2269*495ae853SAndroid Build Coastguard Worker     double sum_squared_error[3] = {0.0, 0.0, 0.0};
2270*495ae853SAndroid Build Coastguard Worker     double total_samples[3];
2271*495ae853SAndroid Build Coastguard Worker     WORD32 i;
2272*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
2273*495ae853SAndroid Build Coastguard Worker     {
2274*495ae853SAndroid Build Coastguard Worker         if (ps_codec->as_ref_set[i].i4_pic_cnt != -1 &&
2275*495ae853SAndroid Build Coastguard Worker             ps_codec->as_ref_set[i].i4_poc == ps_codec->i4_poc)
2276*495ae853SAndroid Build Coastguard Worker         {
2277*495ae853SAndroid Build Coastguard Worker             ps_pic_quality_stats = &ps_codec->as_ref_set[i].s_pic_quality_stats;
2278*495ae853SAndroid Build Coastguard Worker             break;
2279*495ae853SAndroid Build Coastguard Worker         }
2280*495ae853SAndroid Build Coastguard Worker     }
2281*495ae853SAndroid Build Coastguard Worker 
2282*495ae853SAndroid Build Coastguard Worker     if(ps_pic_quality_stats == NULL) return;
2283*495ae853SAndroid Build Coastguard Worker 
2284*495ae853SAndroid Build Coastguard Worker     get_sse(
2285*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_src_buf_luma_base, ps_proc->pu1_rec_buf_luma_base,
2286*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_src_buf_chroma_base, ps_proc->pu1_rec_buf_chroma_base,
2287*495ae853SAndroid Build Coastguard Worker         src_strds, rec_strds, wd, ht, sum_squared_error);
2288*495ae853SAndroid Build Coastguard Worker 
2289*495ae853SAndroid Build Coastguard Worker     total_samples[0] = disp_wd * disp_ht;
2290*495ae853SAndroid Build Coastguard Worker     total_samples[1] = total_samples[2] = total_samples[0] / 4;
2291*495ae853SAndroid Build Coastguard Worker 
2292*495ae853SAndroid Build Coastguard Worker     ps_pic_quality_stats->total_frames = 1;
2293*495ae853SAndroid Build Coastguard Worker     ps_codec->s_global_quality_stats.total_frames += 1;
2294*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < 3; i++)
2295*495ae853SAndroid Build Coastguard Worker     {
2296*495ae853SAndroid Build Coastguard Worker         double psnr = sse_to_psnr(total_samples[i], sum_squared_error[i]);
2297*495ae853SAndroid Build Coastguard Worker         ps_pic_quality_stats->total_samples[i] = total_samples[i];
2298*495ae853SAndroid Build Coastguard Worker         ps_pic_quality_stats->total_sse[i] = sum_squared_error[i];
2299*495ae853SAndroid Build Coastguard Worker         ps_pic_quality_stats->global_psnr[i] = ps_pic_quality_stats->avg_psnr[i] =
2300*495ae853SAndroid Build Coastguard Worker             ps_pic_quality_stats->total_psnr[i] = psnr;
2301*495ae853SAndroid Build Coastguard Worker         ps_codec->s_global_quality_stats.total_sse[i] += sum_squared_error[i];
2302*495ae853SAndroid Build Coastguard Worker         ps_codec->s_global_quality_stats.global_psnr[i] =
2303*495ae853SAndroid Build Coastguard Worker             sse_to_psnr(ps_codec->s_global_quality_stats.total_samples[i],
2304*495ae853SAndroid Build Coastguard Worker                 ps_codec->s_global_quality_stats.total_sse[i]);
2305*495ae853SAndroid Build Coastguard Worker         ps_codec->s_global_quality_stats.total_psnr[i] += psnr;
2306*495ae853SAndroid Build Coastguard Worker         ps_codec->s_global_quality_stats.avg_psnr[i] =
2307*495ae853SAndroid Build Coastguard Worker             ps_codec->s_global_quality_stats.total_psnr[i] /
2308*495ae853SAndroid Build Coastguard Worker                 ps_codec->s_global_quality_stats.total_frames;
2309*495ae853SAndroid Build Coastguard Worker     }
2310*495ae853SAndroid Build Coastguard Worker }
2311*495ae853SAndroid Build Coastguard Worker 
2312