• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 
21 /**
22 ******************************************************************************
23 * @file
24 *  ihevce_lap_interface.c
25 *
26 * @brief
27 *  This file contains function definitions related to look-ahead processing
28 *
29 * @author
30 *  ittiam
31 *
32 * @par List of Functions:
33 *
34 ******************************************************************************
35 */
36 
37 /*****************************************************************************/
38 /* File Includes                                                             */
39 /*****************************************************************************/
40 
41 /* System Include Files */
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <assert.h>
46 
47 /* User Include Files */
48 #include "ihevc_typedefs.h"
49 #include "itt_video_api.h"
50 #include "ihevce_api.h"
51 
52 #include "rc_cntrl_param.h"
53 #include "rc_frame_info_collector.h"
54 #include "rc_look_ahead_params.h"
55 
56 #include "ihevc_defs.h"
57 #include "ihevc_macros.h"
58 #include "ihevc_debug.h"
59 #include "ihevc_structs.h"
60 #include "ihevc_platform_macros.h"
61 #include "ihevc_deblk.h"
62 #include "ihevc_itrans_recon.h"
63 #include "ihevc_chroma_itrans_recon.h"
64 #include "ihevc_chroma_intra_pred.h"
65 #include "ihevc_intra_pred.h"
66 #include "ihevc_inter_pred.h"
67 #include "ihevc_mem_fns.h"
68 #include "ihevc_padding.h"
69 #include "ihevc_weighted_pred.h"
70 #include "ihevc_sao.h"
71 #include "ihevc_resi_trans.h"
72 #include "ihevc_quant_iquant_ssd.h"
73 #include "ihevc_cabac_tables.h"
74 
75 #include "ihevce_defs.h"
76 #include "ihevce_api.h"
77 #include "ihevce_hle_interface.h"
78 #include "ihevce_hle_q_func.h"
79 #include "ihevce_lap_enc_structs.h"
80 #include "ihevce_lap_interface.h"
81 #include "ihevce_lap_structs.h"
82 #include "ihevce_multi_thrd_structs.h"
83 #include "ihevce_function_selector.h"
84 #include "ihevce_me_common_defs.h"
85 #include "ihevce_enc_structs.h"
86 #include "ihevce_rc_enc_structs.h"
87 #include "ihevce_rc_interface.h"
88 #include "ihevce_buffer_que_interface.h"
89 
90 /*****************************************************************************/
91 /* Globals                                                                   */
92 /*****************************************************************************/
93 WORD32 gau1_order_insert_pic_type[MAX_TEMPORAL_LAYERS][8] = {
94     { P_PIC, B_PIC, P_PIC, B_PIC, P_PIC, B_PIC, P_PIC, B_PIC },
95     { P_PIC, B_PIC, B1_PIC, B1_PIC, P_PIC, B_PIC, B1_PIC, B1_PIC },
96     { P_PIC, B_PIC, B1_PIC, B2_PIC, B2_PIC, B1_PIC, B2_PIC, B2_PIC },
97 };
98 
99 UWORD8 gau1_use_by_cur_pic_flag[MAX_REF_PICS] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
100 
101 /*****************************************************************************/
102 /* Function Definitions                                                      */
103 /*****************************************************************************/
104 
105 /*!
106 ************************************************************************
107 * \brief
108 *    return number of records used by LAP
109 *
110 ************************************************************************
111 */
ihevce_lap_get_num_mem_recs(void)112 WORD32 ihevce_lap_get_num_mem_recs(void)
113 {
114     return (NUM_LAP_MEM_RECS);
115 }
116 
117 /*!
118 ************************************************************************
119 * @brief
120 *    return each record attributes of LAP
121 ************************************************************************
122 */
ihevce_lap_get_mem_recs(iv_mem_rec_t * ps_mem_tab,WORD32 i4_mem_space)123 WORD32 ihevce_lap_get_mem_recs(iv_mem_rec_t *ps_mem_tab, WORD32 i4_mem_space)
124 {
125     /* number of NODE memory */
126     WORD32 max_nodes = MAX_SUB_GOP_SIZE - 1;
127 
128     ps_mem_tab[LAP_CTXT].i4_mem_size = sizeof(lap_struct_t);
129     ps_mem_tab[LAP_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
130     ps_mem_tab[LAP_CTXT].i4_mem_alignment = 8;
131 
132     /* Node memory for 2 sub-gops*/
133     ps_mem_tab[LAP_NODE_MEM].i4_mem_size = (max_nodes * sizeof(ihevce_encode_node_t));
134 
135     ps_mem_tab[LAP_NODE_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
136 
137     ps_mem_tab[LAP_NODE_MEM].i4_mem_alignment = 8;
138 
139     return (NUM_LAP_MEM_RECS);
140 }
141 
142 /*!
143 ************************************************************************
144 * @brief
145 *    Init LAP structure
146 ************************************************************************
147 */
ihevce_lap_init(iv_mem_rec_t * ps_mem_tab,ihevce_lap_static_params_t * ps_lap_params,ihevce_static_cfg_params_t * ps_static_cfg_prms)148 void *ihevce_lap_init(
149     iv_mem_rec_t *ps_mem_tab,
150     ihevce_lap_static_params_t *ps_lap_params,
151     ihevce_static_cfg_params_t *ps_static_cfg_prms)
152 {
153     WORD32 i4_src_interlace_field;
154     WORD32 i4_max_temporal_layers;
155     ihevce_encode_node_t *ps_encode_node_struct;
156     lap_struct_t *ps_lap_struct = (lap_struct_t *)ps_mem_tab[LAP_CTXT].pv_base;
157     ihevce_lap_static_params_t *ps_lap_static_params = &ps_lap_struct->s_lap_static_params;
158     ps_lap_struct->aps_encode_node[0] = (ihevce_encode_node_t *)ps_mem_tab[LAP_NODE_MEM].pv_base;
159 
160     memcpy(
161         &ps_lap_struct->s_static_cfg_params,
162         ps_static_cfg_prms,
163         sizeof(ihevce_static_cfg_params_t));
164     memmove(ps_lap_static_params, ps_lap_params, sizeof(ihevce_lap_static_params_t));
165     ps_lap_static_params->e_arch_type = ps_static_cfg_prms->e_arch_type;
166 
167     /* Set the array to zero */
168     memset(&ps_lap_struct->ai4_capture_order_poc[0], 0, MAX_NUM_ENC_NODES * sizeof(WORD32));
169     memset(&ps_lap_struct->ai4_encode_order_poc[0], 0, MAX_NUM_ENC_NODES * sizeof(WORD32));
170     memset(&ps_lap_struct->ref_poc_array[0], 0xFF, sizeof(ps_lap_struct->ref_poc_array));
171     memset(&ps_lap_struct->ai4_pic_type_to_be_removed, 0, NUM_LAP2_LOOK_AHEAD * sizeof(WORD32));
172     memset(&ps_lap_struct->ai4_num_buffer[0], 0, sizeof(ps_lap_struct->ai4_num_buffer));
173 
174     ps_lap_struct->i4_curr_poc = 0;
175     ps_lap_struct->i4_cra_poc = 0;
176 
177     i4_max_temporal_layers = ps_lap_static_params->i4_max_temporal_layers;
178     i4_src_interlace_field = ps_lap_static_params->i4_src_interlace_field;
179     ps_lap_struct->i4_max_idr_period =
180         ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period;
181     ps_lap_struct->i4_min_idr_period =
182         ps_static_cfg_prms->s_coding_tools_prms.i4_min_closed_gop_period;
183     ps_lap_struct->i4_max_cra_period =
184         ps_static_cfg_prms->s_coding_tools_prms.i4_max_cra_open_gop_period;
185     ps_lap_struct->i4_max_i_period =
186         ps_static_cfg_prms->s_coding_tools_prms.i4_max_i_open_gop_period;
187     ps_lap_struct->i4_idr_counter = 0;
188     ps_lap_struct->i4_cra_counter = 0;
189     ps_lap_struct->i4_i_counter = 0;
190     ps_lap_struct->i4_idr_gop_num = -1;
191     ps_lap_struct->i4_curr_ref_pics = 0;
192     ps_lap_struct->i4_display_num = 0;
193     ps_lap_struct->i4_num_frm_type_decided = 0;
194     ps_lap_struct->i4_next_start_ctr = 0;
195     ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_IDR;
196 
197     ps_lap_struct->i4_enable_logo = ps_lap_static_params->i4_enable_logo;
198     ps_lap_struct->i4_cra_i_pic_flag = 0;
199     ps_lap_struct->i4_force_end_flag = 0;
200     ps_lap_struct->i4_sub_gop_size = (1 << i4_max_temporal_layers);
201     ps_lap_struct->i4_sub_gop_size_idr =
202         ps_lap_struct->i4_sub_gop_size + (i4_max_temporal_layers > 0);
203 
204     ps_lap_struct->i4_is_all_i_pic_in_seq = 0;
205 
206     if(ps_lap_struct->i4_max_idr_period == 1 || ps_lap_struct->i4_max_cra_period == 1 ||
207        ps_lap_struct->i4_max_i_period == 1)
208     {
209         ps_lap_struct->i4_is_all_i_pic_in_seq = 1;
210     }
211 
212     if(1 == i4_src_interlace_field && (!ps_lap_struct->i4_is_all_i_pic_in_seq))
213     {
214         ps_lap_struct->i4_sub_gop_size <<= 1;
215         ps_lap_struct->i4_sub_gop_size_idr <<= 1;
216     }
217 
218     ps_lap_struct->i4_fixed_open_gop_period = 1;
219     ps_lap_struct->i4_fixed_i_period = 1;
220 
221     if(ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period <=
222        ps_lap_struct->i4_sub_gop_size)
223     {
224         ps_lap_struct->i4_min_idr_period =
225             ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period;
226     }
227     if(ps_lap_struct->i4_max_idr_period)
228     {
229         if(ps_lap_struct->i4_max_cra_period)
230         {
231             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_cra_period;
232         }
233         else if(ps_lap_struct->i4_max_i_period)
234         {
235             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_i_period;
236         }
237         else
238         {
239             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_idr_period;
240         }
241     }
242     else
243     {
244         if(ps_lap_struct->i4_max_i_period)
245         {
246             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_i_period;
247         }
248         else if(ps_lap_struct->i4_max_cra_period)
249         {
250             ps_lap_struct->i4_gop_period = ps_lap_struct->i4_max_cra_period;
251         }
252     }
253 
254     if(!ps_lap_struct->i4_max_i_period)
255     {
256         ps_lap_struct->i4_max_i_period =
257             2 * MAX(ps_lap_struct->i4_max_idr_period, ps_lap_struct->i4_max_cra_period);
258     }
259 
260     ps_lap_struct->i4_no_back_to_back_i_avoidance = 0;
261 
262     /*Infinite GOP case*/
263     if(!ps_lap_struct->i4_gop_period)
264     {
265         /*max signed 32 bit value which will be ~ 414 days considering 60frames/fields per second*/
266         ps_lap_struct->i4_max_i_period = 0x7fffffff;
267         ps_lap_struct->i4_gop_period =
268             (INFINITE_GOP_CDR_TIME_S * (ps_static_cfg_prms->s_src_prms.i4_frm_rate_num /
269                                         ps_static_cfg_prms->s_src_prms.i4_frm_rate_denom));
270     }
271 
272     if(ps_lap_struct->i4_gop_period < (2 * ps_lap_struct->i4_sub_gop_size))
273     {
274         ps_lap_struct->i4_no_back_to_back_i_avoidance = 1;
275     }
276 
277     ps_lap_struct->i4_rc_lap_period =
278         ps_static_cfg_prms->s_lap_prms.i4_rc_look_ahead_pics + MIN_L1_L0_STAGGER_NON_SEQ;
279     ps_lap_struct->pv_prev_inp_buf = NULL;
280     ps_lap_struct->i4_buf_deq_idx = 0;
281     ps_lap_struct->i4_deq_idx = 0;
282     ps_lap_struct->i4_enq_idx = 0;
283     ps_lap_struct->i4_lap2_counter = 0;
284     ps_lap_struct->i4_dyn_sub_gop_size = ps_lap_struct->i4_sub_gop_size;
285     ps_lap_struct->i4_buf_enq_idx = 0;
286     ps_lap_struct->i4_lap_out_idx = 0;
287     ps_lap_struct->i4_capture_idx = 0;
288     ps_lap_struct->i4_idr_flag = 1;
289     ps_lap_struct->i4_num_bufs_encode_order = 0;
290     ps_lap_struct->end_flag = 0;
291     ps_lap_struct->i4_immediate_idr_case = 0;
292     ps_lap_struct->i4_max_buf_in_enc_order = 0;
293     ps_lap_struct->i4_end_flag_pic_idx = 0;
294     memset(
295         &ps_lap_struct->api4_encode_order_array[0],
296         0,
297         sizeof(ihevce_lap_enc_buf_t *) * MAX_NUM_ENC_NODES);
298     ps_lap_struct->i4_sub_gop_pic_idx = 0;
299     ps_lap_struct->i4_force_idr_pos = 0;
300     ps_lap_struct->i4_num_dummy_pic = 0;
301     ps_lap_struct->i4_lap_encode_idx = 0;
302     ps_lap_struct->i4_deq_lap_buf = 0;
303     ps_lap_struct->i4_sub_gop_end = 0;
304 
305     {
306         WORD32 node_offset, curr_layer;
307         WORD32 i;
308         /*intialization of aps_lap_inp_buf*/
309         for(i = 0; i < MAX_QUEUE_LENGTH; i++)
310         {
311             ps_lap_struct->aps_lap_inp_buf[i] = NULL;
312         }
313 
314         /* init capture order and encode order pointer */
315         ps_lap_struct->pi4_capture_poc_ptr = &ps_lap_struct->ai4_capture_order_poc[0];
316         ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0];
317 
318         /* init all the buffer status to default values */
319         ps_encode_node_struct = ps_lap_struct->aps_encode_node[0];
320 
321         ps_encode_node_struct->pv_left_node = NULL;
322         ps_encode_node_struct->pv_right_node = NULL;
323 
324         /* Initialise the tree */
325         node_offset = 1;
326         curr_layer = 0;
327         ihevce_populate_tree_nodes(
328             ps_encode_node_struct,
329             ps_encode_node_struct,
330             &node_offset,
331             curr_layer,
332             ps_lap_static_params->i4_max_temporal_layers);
333     }
334 
335     ps_mem_tab += NUM_LAP_MEM_RECS;
336 
337     return ((void *)ps_lap_struct);
338 }
339 
340 /*!
341 ******************************************************************************
342 * \if Function name : ihevce_populate_tree_nodes \endif
343 *
344 * \brief
345 *    LAP populate nodes function
346 *
347 * \param[in] encode_parent_node_t node pointer to base
348 *            encode_node_t        node pointer to current buffer
349 *            loop_count                layer count
350 *            hier_layer           total layers
351 * \return
352 *    None
353 *
354 * \author
355 *  Ittiam
356 *
357 *****************************************************************************
358 */
ihevce_populate_tree_nodes(ihevce_encode_node_t * encode_parent_node_t,ihevce_encode_node_t * encode_node_t,WORD32 * loop_count,WORD32 layer,WORD32 hier_layer)359 void ihevce_populate_tree_nodes(
360     ihevce_encode_node_t *encode_parent_node_t,
361     ihevce_encode_node_t *encode_node_t,
362     WORD32 *loop_count,
363     WORD32 layer,
364     WORD32 hier_layer)
365 {
366     /* If only I/P pictures, return NULL from the child nodes*/
367     if(hier_layer == 0)
368     {
369         encode_node_t->pv_left_node = NULL;
370         encode_node_t->pv_right_node = NULL;
371         return;
372     }
373     if(layer == hier_layer)
374         return;
375 
376     layer = layer + 1;
377 
378     /* If the layers are not exhausted */
379     if(layer < hier_layer)
380     {
381         encode_node_t->pv_left_node = encode_parent_node_t + (*loop_count);
382         encode_node_t->pv_right_node = encode_parent_node_t + (*loop_count + 1);
383         (*loop_count) = (*loop_count) + 2;
384     }
385     else
386     {
387         encode_node_t->pv_left_node = NULL;
388         encode_node_t->pv_right_node = NULL;
389     }
390 
391     /* Populate Left tree nodes */
392     ihevce_populate_tree_nodes(
393         encode_parent_node_t,
394         (ihevce_encode_node_t *)encode_node_t->pv_left_node,
395         loop_count,
396         layer,
397         hier_layer);
398 
399     /* Populate right tree nodes */
400     ihevce_populate_tree_nodes(
401         encode_parent_node_t,
402         (ihevce_encode_node_t *)encode_node_t->pv_right_node,
403         loop_count,
404         layer,
405         hier_layer);
406 }
407 
408 /*!
409 ************************************************************************
410 * \brief
411 *    pad input when its dimensions are not aligned to LCU size
412 ************************************************************************
413 */
ihevce_lap_pad_input_bufs(ihevce_lap_enc_buf_t * ps_curr_inp,WORD32 align_pic_wd,WORD32 align_pic_ht)414 void ihevce_lap_pad_input_bufs(
415     ihevce_lap_enc_buf_t *ps_curr_inp, WORD32 align_pic_wd, WORD32 align_pic_ht)
416 {
417     /* local variables */
418     WORD32 ctr_horz, ctr_vert;
419 
420     /* ------- Horizontal Right Padding ------ */
421     if(align_pic_wd != ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd)
422     {
423         UWORD8 *pu1_inp;
424         UWORD16 *pu2_inp;
425         WORD32 pad_wd;
426         WORD32 pad_ht;
427 
428         /* ------------- LUMA ----------------------------- */
429         /* derive the pointers and dimensions to be padded */
430         pad_ht = ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht;
431         pad_wd = align_pic_wd - ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
432         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf;
433         pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
434 
435         /* loops for padding the right region for entire pic */
436         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
437         {
438             for(ctr_horz = 0; ctr_horz < pad_wd; ctr_horz++)
439             {
440                 /* last pixel is replicated */
441                 pu1_inp[ctr_horz] = pu1_inp[-1];
442             }
443 
444             /* row level increments */
445             pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
446         }
447 
448         /* ------------- CHROMA ---------------------------- */
449         /* derive the pointers and dimensions to be padded */
450         pad_ht = ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
451         pad_wd = align_pic_wd - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd;
452         pad_wd >>= 1;
453         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf;
454         pu2_inp = (UWORD16 *)(pu1_inp + ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd);
455 
456         /* loops for padding the right region for entire pic */
457         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
458         {
459             for(ctr_horz = 0; ctr_horz < pad_wd; ctr_horz++)
460             {
461                 /* last pixel is replicated, cb and cr pixel interleaved */
462                 pu2_inp[ctr_horz] = pu2_inp[-1];
463             }
464 
465             /* row level increments */
466             pu2_inp += (ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd >> 1);
467         }
468     }
469 
470     /* ------- Vertical Bottom Padding ------ */
471     if(align_pic_ht != ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht)
472     {
473         UWORD8 *pu1_inp, *pu1_src;
474         WORD32 pad_ht;
475 
476         /* ------------- LUMA ----------------------------- */
477         /* derive the pointers and dimensions to be padded */
478         pad_ht = align_pic_ht - ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht;
479         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf;
480         pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
481                    ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
482 
483         /* get the pointer of last row */
484         pu1_src = pu1_inp - ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
485 
486         /* loops for padding the bottom region for entire row */
487         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
488         {
489             /* copy the eniter orw including horz padd region */
490             memcpy(pu1_inp, pu1_src, align_pic_wd);
491 
492             /* row level increments */
493             pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_y_strd;
494         }
495 
496         /* ------------- CHROMA ----------------------------- */
497         /* derive the pointers and dimensions to be padded */
498         pad_ht = (align_pic_ht >> 1) - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
499         pu1_inp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf;
500         pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht *
501                    ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd;
502 
503         /* get the pointer of last row */
504         pu1_src = pu1_inp - ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd;
505 
506         /* loops for padding the bottom region for entire row */
507         for(ctr_vert = 0; ctr_vert < pad_ht; ctr_vert++)
508         {
509             /* copy the eniter orw including horz padd region */
510             memcpy(pu1_inp, pu1_src, align_pic_wd);
511 
512             /* row level increments */
513             pu1_inp += ps_curr_inp->s_lap_out.s_input_buf.i4_uv_strd;
514         }
515     }
516     return;
517 }
518 
519 /*!
520 ************************************************************************
521 * \brief
522 *    check for last inp buf
523 ************************************************************************
524 */
ihevce_check_last_inp_buf(WORD32 * pi4_cmd_buf)525 WORD32 ihevce_check_last_inp_buf(WORD32 *pi4_cmd_buf)
526 {
527     WORD32 cmd = (*pi4_cmd_buf) & (IHEVCE_COMMANDS_TAG_MASK);
528 
529     if(IHEVCE_SYNCH_API_FLUSH_TAG == cmd)
530         return 1;
531     return 0;
532 }
533 
534 /*!
535 ************************************************************************
536 * \brief
537 *    lap parse sync commands
538 ************************************************************************
539 */
ihevce_lap_parse_sync_cmd(ihevce_hle_ctxt_t * ps_hle_ctxt,ihevce_static_cfg_params_t * ps_static_cfg_prms,WORD32 * pi4_cmd_buf,ihevce_lap_enc_buf_t * ps_lap_inp_buf,WORD32 * pi4_flush_check,WORD32 * pi4_force_idr_check)540 void ihevce_lap_parse_sync_cmd(
541     ihevce_hle_ctxt_t *ps_hle_ctxt,
542     ihevce_static_cfg_params_t *ps_static_cfg_prms,
543     WORD32 *pi4_cmd_buf,
544     ihevce_lap_enc_buf_t *ps_lap_inp_buf,
545     WORD32 *pi4_flush_check,
546     WORD32 *pi4_force_idr_check)
547 {
548     WORD32 *pi4_tag_parse = pi4_cmd_buf;
549     WORD32 i4_cmd_size = ps_lap_inp_buf->s_input_buf.i4_cmd_buf_size;
550     WORD32 i4_buf_id = ps_lap_inp_buf->s_input_buf.i4_buf_id;
551     UWORD32 u4_num_sei = 0;
552     WORD32 i4_end_flag = 0;
553 
554     while(i4_cmd_size >= 4)
555     {
556         switch((*pi4_tag_parse) & (IHEVCE_COMMANDS_TAG_MASK))
557         {
558         case IHEVCE_SYNCH_API_FLUSH_TAG:
559             if(i4_cmd_size < 8 || pi4_tag_parse[1])
560             {
561                 ps_hle_ctxt->ihevce_cmds_error_report(
562                     ps_hle_ctxt->pv_cmd_err_cb_handle,
563                     IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO,
564                     1,
565                     i4_buf_id);
566                 return;
567             }
568             (*pi4_flush_check) = 1;
569             pi4_tag_parse += 2;
570             i4_cmd_size -= 8;
571             u4_num_sei++;
572             break;
573         case IHEVCE_SYNCH_API_FORCE_IDR_TAG:
574             if(i4_cmd_size < 8 || pi4_tag_parse[1])
575             {
576                 ps_hle_ctxt->ihevce_cmds_error_report(
577                     ps_hle_ctxt->pv_cmd_err_cb_handle,
578                     IHEVCE_SYNCH_ERR_LENGTH_NOT_ZERO,
579                     1,
580                     i4_buf_id);
581                 return;
582             }
583             (*pi4_force_idr_check) = 1;
584             pi4_tag_parse += 2;
585             i4_cmd_size -= 8;
586             u4_num_sei++;
587             break;
588         case IHEVCE_SYNCH_API_END_TAG:
589             i4_end_flag = 1;
590             i4_cmd_size -= 4;
591             break;
592         default:
593             ps_hle_ctxt->ihevce_cmds_error_report(
594                 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_TLV_ERROR, 1, i4_buf_id);
595             i4_end_flag = 1;
596         }
597         if(i4_end_flag)
598             break;
599     }
600     if(u4_num_sei > MAX_NUMBER_OF_SEI_PAYLOAD)  //Checking for max number of SEI messages.
601         ps_hle_ctxt->ihevce_cmds_error_report(
602             ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_TOO_MANY_SEI_MSG, 1, i4_buf_id);
603 
604     if(!i4_end_flag)
605         ps_hle_ctxt->ihevce_cmds_error_report(
606             ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_SYNCH_ERR_NO_END_TAG, 1, i4_buf_id);
607 }
608 
609 /*!
610 ************************************************************************
611 * \brief
612 *    lap parse Async commands
613 ************************************************************************
614 */
ihevce_lap_parse_async_cmd(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_cmd_buf,WORD32 i4_length,WORD32 i4_buf_id,WORD32 * pi4_num_set_bitrate_cmds,ihevce_dyn_config_prms_t * ps_dyn_br)615 void ihevce_lap_parse_async_cmd(
616     ihevce_hle_ctxt_t *ps_hle_ctxt,
617     WORD32 *pi4_cmd_buf,
618     WORD32 i4_length,
619     WORD32 i4_buf_id,
620     WORD32 *pi4_num_set_bitrate_cmds,
621     ihevce_dyn_config_prms_t *ps_dyn_br)
622 {
623     WORD32 i4_end_flag = 0;
624     WORD32 *pi4_tag_parse = pi4_cmd_buf;
625 
626     while(i4_length >= 4)
627     {
628         switch(*pi4_tag_parse)
629         {
630         case IHEVCE_ASYNCH_API_SETBITRATE_TAG:
631             if(i4_length < (8 + sizeof(ihevce_dyn_config_prms_t)) ||
632                pi4_tag_parse[1] != sizeof(ihevce_dyn_config_prms_t))
633             {
634                 ps_hle_ctxt->ihevce_cmds_error_report(
635                     ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_BR_NOT_BYTE, 1, i4_buf_id);
636                 return;
637             }
638             memcpy(
639                 (void *)ps_dyn_br, (void *)(pi4_tag_parse + 2), sizeof(ihevce_dyn_config_prms_t));
640             pi4_tag_parse += (2 + (sizeof(ihevce_dyn_config_prms_t) >> 2));
641             i4_length -= (8 + sizeof(ihevce_dyn_config_prms_t));
642             *pi4_num_set_bitrate_cmds += 1;
643             ps_dyn_br++;
644             break;
645         case IHEVCE_ASYNCH_API_END_TAG:
646             i4_end_flag = 1;
647             i4_length -= 4;
648             break;
649         default:
650             ps_hle_ctxt->ihevce_cmds_error_report(
651                 ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_TLV_ERROR, 1, i4_buf_id);
652             i4_end_flag = 1;
653         }
654         if(i4_end_flag)
655             break;
656     }
657     if(!i4_end_flag)
658         ps_hle_ctxt->ihevce_cmds_error_report(
659             ps_hle_ctxt->pv_cmd_err_cb_handle, IHEVCE_ASYNCH_ERR_NO_END_TAG, 1, i4_buf_id);
660 }
661 
662 /*!
663 ************************************************************************
664 * \brief
665 *    ref pics weight offset calculation
666 ************************************************************************
667 */
ref_pics_weight_offset_calc(ihevce_lap_output_params_t * ps_lap_out,lap_struct_t * ps_lap_struct)668 void ref_pics_weight_offset_calc(ihevce_lap_output_params_t *ps_lap_out, lap_struct_t *ps_lap_struct)
669 {
670     WORD32 i, j;
671     WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array;
672     WORD32 ai4_delta_poc[MAX_REF_PICS];
673     WORD32 ref_poc_arr_sort[MAX_REF_PICS];
674 
675     /* Default weighted pred parameters populated for  now */
676     ps_lap_out->i4_log2_luma_wght_denom = DENOM_DEFAULT;
677     ps_lap_out->i4_log2_chroma_wght_denom = DENOM_DEFAULT;
678 
679     /* sort the ref_poc_array based on delta as
680      * in case weighted pred dup pics are inserted and it should consider
681      * the neighbors first for prediction than farthest */
682     for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++)
683     {
684         ai4_delta_poc[i] = ref_poc_array[i] - ps_lap_out->i4_poc;
685     }
686 
687     for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++)
688     {
689         WORD32 i4_min, temp;
690         i4_min = i;
691         for(j = i; j < ps_lap_struct->i4_curr_ref_pics; j++)
692         {
693             if(abs(ai4_delta_poc[j]) <= abs(ai4_delta_poc[i4_min]))
694             {
695                 i4_min = j;
696             }
697         }
698         temp = ai4_delta_poc[i];
699         ai4_delta_poc[i] = ai4_delta_poc[i4_min];
700         ai4_delta_poc[i4_min] = temp;
701         ref_poc_arr_sort[i] = ai4_delta_poc[i] + ps_lap_out->i4_poc;
702     }
703 
704     for(i = 0; i < ps_lap_struct->i4_curr_ref_pics; i++)
705     {
706         ps_lap_out->as_ref_pics[i].i4_ref_pic_delta_poc = ref_poc_arr_sort[i] - ps_lap_out->i4_poc;
707         ASSERT(ps_lap_out->as_ref_pics[i].i4_ref_pic_delta_poc);
708 
709         /* Enable flag for the reference pics to be used by curr pic */
710         ps_lap_out->as_ref_pics[i].i4_used_by_cur_pic_flag = gau1_use_by_cur_pic_flag[i];
711 
712         /* Currently no weighted prediction offset added */
713         ps_lap_out->as_ref_pics[i].i4_num_duplicate_entries_in_ref_list = 1;
714     }
715     return;
716 }
717 
718 /*!
719 ************************************************************************
720 * \brief
721 *    ref b picture population
722 ************************************************************************
723 */
ref_b_pic_population(WORD32 curr_layer,ihevce_lap_enc_buf_t * ps_lap_inp,lap_struct_t * ps_lap_struct)724 void ref_b_pic_population(
725     WORD32 curr_layer, ihevce_lap_enc_buf_t *ps_lap_inp, lap_struct_t *ps_lap_struct)
726 {
727     ihevce_lap_output_params_t *ps_lap_out = &ps_lap_inp->s_lap_out;
728     WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array;
729     WORD32 *p_ref_poc_array = ref_poc_array;
730     WORD32 i4_interlace_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
731     WORD32 i4_max_ref_pics = ps_lap_struct->s_lap_static_params.i4_max_reference_frames;
732     WORD32 max_temporal_layers = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
733 
734     /* LAP output structure */
735     ps_lap_out->i4_poc = ps_lap_struct->pi4_encode_poc_ptr[0];
736     ps_lap_out->i4_idr_gop_num = ps_lap_struct->i4_idr_gop_num;
737     ps_lap_out->i4_assoc_IRAP_poc = ps_lap_struct->i4_assoc_IRAP_poc;
738     ps_lap_out->i4_temporal_lyr_id = curr_layer;
739     ps_lap_out->i4_pic_type = IV_B_FRAME;
740 
741     if((ps_lap_out->i4_poc > ps_lap_struct->i4_cra_poc) &&
742        (ref_poc_array[0] < ps_lap_struct->i4_cra_poc) && ps_lap_struct->i4_cra_i_pic_flag)
743     {
744         ref_poc_array[0] = ps_lap_struct->i4_cra_poc;
745         ps_lap_struct->i4_curr_ref_pics = 1;
746     }
747 
748     ps_lap_out->i4_num_ref_pics = ps_lap_struct->i4_curr_ref_pics;
749 
750     /* Default: Cur pic is ref pic*/
751     ps_lap_out->i4_is_ref_pic = 1;
752 
753     if(1 == i4_interlace_field)
754     {
755         WORD32 i4_bottom_field = ps_lap_inp->s_input_buf.i4_bottom_field;
756         WORD32 first_field = (ps_lap_inp->s_input_buf.i4_topfield_first ^ i4_bottom_field);
757 
758         /*If current pic is top field B picture and is present in top hierarchical layer */
759         /* Dereference the curr pic */
760         if(ps_lap_out->i4_temporal_lyr_id == max_temporal_layers)
761         {
762             if(0 == first_field)
763                 ps_lap_out->i4_is_ref_pic = 0;
764             else
765                 ps_lap_out->i4_is_ref_pic = 2;
766         }
767     }
768     else
769     {
770         /*If progressive B picture and is present in top hierarchical layer */
771         if(ps_lap_out->i4_temporal_lyr_id >= max_temporal_layers)
772         {
773             ps_lap_out->i4_temporal_lyr_id = max_temporal_layers;
774             ps_lap_out->i4_is_ref_pic = 0;
775         }
776     }
777 
778     ref_pics_weight_offset_calc(ps_lap_out, ps_lap_struct);
779 
780     /* Updating number of current reference Pictures for the Given Picture */
781     /* If the current frame is n-layer B frame, donot increment*/
782     if(ps_lap_struct->i4_curr_ref_pics < i4_max_ref_pics)
783     {
784         if(ps_lap_out->i4_is_ref_pic)
785         {
786             ps_lap_struct->i4_curr_ref_pics++;
787         }
788     }
789 
790     /* Arrange the reference array in ascending order */
791     {
792         WORD32 i, j, temp;
793         for(i = 0; i < (ps_lap_struct->i4_curr_ref_pics - 1); i++)
794         {
795             for(j = i + 1; j < ps_lap_struct->i4_curr_ref_pics; j++)
796             {
797                 if(ref_poc_array[i] > ref_poc_array[j])
798                 {
799                     temp = ref_poc_array[i];
800                     ref_poc_array[i] = ref_poc_array[j];
801                     ref_poc_array[j] = temp;
802                 }
803             }
804         }
805     }
806 
807     {
808         WORD32 ref = ps_lap_out->i4_poc;
809         if(ps_lap_out->i4_is_ref_pic && ref > *p_ref_poc_array)
810         {
811             *p_ref_poc_array = ref;
812         }
813     }
814 
815     return;
816 }
817 
818 /*!
819 ************************************************************************
820 * \brief
821 *    ref i/p pic population
822 ************************************************************************
823 */
ref_pic_population(ihevce_lap_enc_buf_t * ps_lap_inp,lap_struct_t * ps_lap_struct)824 void ref_pic_population(ihevce_lap_enc_buf_t *ps_lap_inp, lap_struct_t *ps_lap_struct)
825 {
826     ihevce_lap_output_params_t *ps_lap_out = &ps_lap_inp->s_lap_out;
827     WORD32 *ref_poc_array = ps_lap_struct->ref_poc_array;
828     WORD32 *p_ref_poc_array = ref_poc_array;
829     WORD32 i4_max_ref_pics = ps_lap_struct->s_lap_static_params.i4_max_reference_frames;
830 
831     /* Update the POC position */
832     ps_lap_out->i4_poc = ps_lap_struct->pi4_encode_poc_ptr[0];
833 
834     /* picture after CRA can't refer pic before CRA*/
835     if((ps_lap_out->i4_poc > ps_lap_struct->i4_cra_poc) &&
836        (ref_poc_array[0] <= ps_lap_struct->i4_cra_poc) && ps_lap_struct->i4_cra_i_pic_flag)
837     {
838         ref_poc_array[0] = ps_lap_struct->i4_cra_poc;
839         ps_lap_struct->i4_curr_ref_pics = 1;
840     }
841 
842     /* For every IDR period, set pic type as IDR frame and reset reference POC array to 0*/
843     if(IV_IDR_FRAME == ps_lap_out->i4_pic_type)
844     {
845         ps_lap_struct->i4_idr_gop_num++;
846         ps_lap_struct->i4_curr_ref_pics = 0;
847         ps_lap_out->i4_num_ref_pics = 0;
848         ps_lap_struct->i4_cra_i_pic_flag = 1;
849         ps_lap_struct->i4_cra_poc = ps_lap_out->i4_poc;
850 
851         memset(ps_lap_struct->ref_poc_array, 0xFF, sizeof(WORD32) * MAX_REF_PICS);
852     }
853     else if(IV_I_FRAME == ps_lap_out->i4_pic_type)
854     {
855         /* For the I-frames after CRA Frame, no pictures should be referenced */
856         if((1 == ps_lap_struct->i4_cra_i_pic_flag) && ps_lap_out->i4_is_cra_pic)
857         {
858             ps_lap_struct->i4_curr_ref_pics = 0;
859             ps_lap_out->i4_num_ref_pics = 0;
860         }
861         ps_lap_struct->i4_cra_poc = ps_lap_out->i4_poc;
862         ps_lap_struct->i4_cra_i_pic_flag = ps_lap_out->i4_is_cra_pic;
863     }
864     else if(IV_P_FRAME == ps_lap_out->i4_pic_type)
865     {
866         /* If the current POC is the P POC after CRA I POC */
867         if(1 == ps_lap_struct->i4_cra_i_pic_flag)
868         {
869             ps_lap_struct->i4_curr_ref_pics = 1;
870             ps_lap_struct->i4_cra_i_pic_flag = 0;
871         }
872     }
873 
874     if(ps_lap_out->i4_pic_type == IV_IDR_FRAME ||
875        (ps_lap_out->i4_pic_type == IV_I_FRAME && ps_lap_out->i4_is_cra_pic))
876     {
877         ps_lap_struct->i4_assoc_IRAP_poc = ps_lap_out->i4_poc;
878     }
879 
880     /*Update ps_lap_out*/
881     ps_lap_out->i4_idr_gop_num = ps_lap_struct->i4_idr_gop_num;
882     ps_lap_out->i4_is_ref_pic = 1;
883     ps_lap_out->i4_assoc_IRAP_poc = ps_lap_struct->i4_assoc_IRAP_poc;
884 
885     /* Reference POCS */
886     ps_lap_out->i4_num_ref_pics = ps_lap_struct->i4_curr_ref_pics;
887 
888     /* I and P frames are always mapped to layer zero*/
889     ps_lap_out->i4_temporal_lyr_id = 0;
890 
891     ref_pics_weight_offset_calc(ps_lap_out, ps_lap_struct);
892 
893     if(ps_lap_struct->i4_curr_ref_pics < i4_max_ref_pics)
894     {
895         if(ps_lap_out->i4_is_ref_pic)
896         {
897             ps_lap_struct->i4_curr_ref_pics++;
898         }
899     }
900 
901     /* Arrange the reference array in ascending order */
902     {
903         WORD32 i, j, temp;
904         for(i = 0; i < (ps_lap_struct->i4_curr_ref_pics - 1); i++)
905         {
906             for(j = i + 1; j < (ps_lap_struct->i4_curr_ref_pics); j++)
907             {
908                 if(ref_poc_array[i] > ref_poc_array[j])
909                 {
910                     temp = ref_poc_array[i];
911                     ref_poc_array[i] = ref_poc_array[j];
912                     ref_poc_array[j] = temp;
913                 }
914             }
915         }
916     }
917 
918     {
919         /* add the current pictute at the start of the reference queue */
920         /*For I and P pictures, all the previous frames are reference frames */
921         /* If the current ref POC is greater than the least POC in reference array*/
922         /* Then fill the reference array */
923 
924         WORD32 ref = ps_lap_out->i4_poc;
925 
926         if(ps_lap_out->i4_is_ref_pic && ref > *p_ref_poc_array)
927         {
928             *p_ref_poc_array = ref;
929         }
930     }
931 
932     return;
933 }
934 
935 /*!
936 ************************************************************************
937 * \brief
938 *    determine next sub-gop state
939 ************************************************************************
940 */
ihevce_determine_next_sub_gop_state(lap_struct_t * ps_lap_struct)941 void ihevce_determine_next_sub_gop_state(lap_struct_t *ps_lap_struct)
942 {
943     WORD32 i4_num_b_frames = -1;
944     WORD32 i4_sd = ps_lap_struct->i4_sub_gop_size;
945     WORD32 i4_sd_idr = ps_lap_struct->i4_sub_gop_size_idr;
946     WORD32 i4_Midr = ps_lap_struct->i4_max_idr_period;
947     WORD32 i4_midr = ps_lap_struct->i4_min_idr_period;
948     WORD32 i4_Mcra = ps_lap_struct->i4_max_cra_period;
949     WORD32 i4_Mi = ps_lap_struct->i4_max_i_period;
950     WORD32 i4_Cd = ps_lap_struct->i4_idr_counter;
951     WORD32 i4_Cc = ps_lap_struct->i4_cra_counter;
952     WORD32 i4_Ci = ps_lap_struct->i4_i_counter;
953 
954     if(ps_lap_struct->i4_force_idr_pos)
955     {
956         ps_lap_struct->i4_num_frm_type_decided = 1;
957         ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_IDR;
958         ps_lap_struct->i4_idr_counter = 0;
959         ps_lap_struct->i4_cra_counter = 0;
960         ps_lap_struct->i4_i_counter = 0;
961         ps_lap_struct->i4_force_idr_pos = 0;
962         ps_lap_struct->i4_sub_gop_pic_idx = 0;
963     }
964 
965     if(i4_Midr)
966         ASSERT(i4_Cd < i4_Midr);
967 
968     if(i4_Mcra)
969         ASSERT(i4_Cc < i4_Mcra);
970 
971     if(i4_Mi)
972         ASSERT(i4_Ci < i4_Mi);
973 
974     /*if all are i pictures */
975     if((i4_Midr == 1) || (i4_Mcra == 1) || (i4_Mi == 1))
976     {
977         ps_lap_struct->i4_num_frm_type_decided = 1;
978         if((i4_Midr == 1) || ((i4_Cd + i4_sd) == i4_Midr))
979         {
980             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_IDR;
981             ps_lap_struct->i4_idr_counter = 0;
982             ps_lap_struct->i4_cra_counter = 0;
983             ps_lap_struct->i4_i_counter = 0;
984         }
985         else if((i4_Mcra == 1) || ((i4_Cc + i4_sd) == i4_Mcra))
986         {
987             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_CRA;
988             ps_lap_struct->i4_idr_counter += 1;
989             ps_lap_struct->i4_cra_counter = 0;
990             ps_lap_struct->i4_i_counter = 0;
991         }
992         else
993         {
994             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_I;
995             ps_lap_struct->i4_idr_counter += 1;
996             ps_lap_struct->i4_cra_counter += 1;
997             ps_lap_struct->i4_i_counter = 0;
998         }
999         return;
1000     }
1001 
1002     if((i4_Cd + i4_sd_idr >= i4_Midr) && i4_Midr)
1003     {
1004         /*if idr falls already on sub-gop aligned w.r.t Midr or if strict idr use case*/
1005         if(i4_sd_idr != i4_sd)
1006         {
1007             i4_num_b_frames = i4_Midr - i4_Cd - 2;
1008             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
1009             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
1010             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 2] = PIC_TYPE_IDR;
1011             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 2;
1012             ps_lap_struct->i4_idr_counter = 0;
1013             ps_lap_struct->i4_cra_counter = 0;
1014             ps_lap_struct->i4_i_counter = 0;
1015         }
1016         else
1017         {
1018             i4_num_b_frames = 0;
1019             ps_lap_struct->ai1_pic_type[1] = PIC_TYPE_IDR;
1020             ps_lap_struct->i4_num_frm_type_decided = 1;
1021             ps_lap_struct->i4_idr_counter = 0;
1022             ps_lap_struct->i4_cra_counter = 0;
1023             ps_lap_struct->i4_i_counter = 0;
1024         }
1025     }
1026     /*if next sub gop is going to have CRA as Cc reaches Mcra*/
1027     else if(((i4_Cc + i4_sd) >= i4_Mcra) && i4_Mcra)
1028     {
1029         if(((i4_Cc + i4_sd) == i4_Mcra) || (1 == ps_lap_struct->i4_fixed_open_gop_period))
1030         {
1031             i4_num_b_frames = i4_Mcra - i4_Cc - 1;
1032             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
1033             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_CRA;
1034             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
1035             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
1036             ps_lap_struct->i4_cra_counter = 0;
1037             ps_lap_struct->i4_i_counter = 0;
1038         }
1039         else
1040         {
1041             ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_CRA;
1042             i4_num_b_frames = i4_sd - 1;
1043             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
1044             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
1045             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
1046             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
1047             ps_lap_struct->i4_cra_counter = ps_lap_struct->i4_num_frm_type_decided;
1048             ps_lap_struct->i4_i_counter = ps_lap_struct->i4_num_frm_type_decided;
1049         }
1050     }
1051     /*if next sub gop is going to have I_slice as Ci reaches Mi*/
1052     else if((i4_Ci + i4_sd >= i4_Mi) && i4_Mi)
1053     {
1054         if(((i4_Ci + i4_sd) == i4_Mi) || (1 == ps_lap_struct->i4_fixed_i_period))
1055         {
1056             i4_num_b_frames = i4_Mi - i4_Ci - 1;
1057             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
1058             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_I;
1059             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
1060             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
1061             ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided;
1062             ps_lap_struct->i4_i_counter = 0;
1063         }
1064         else
1065         {
1066             ps_lap_struct->ai1_pic_type[0] = PIC_TYPE_I;
1067             i4_num_b_frames = i4_sd - 1;
1068             memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
1069             ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
1070             ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
1071             ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
1072             ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided;
1073             ps_lap_struct->i4_i_counter = ps_lap_struct->i4_num_frm_type_decided;
1074         }
1075     }
1076     /* if next sub-gop is not going to be idr,cra,I*/
1077     else
1078     {
1079         i4_num_b_frames = i4_sd - 1;
1080         memset(&ps_lap_struct->ai1_pic_type[1], PIC_TYPE_B, i4_num_b_frames);
1081         ps_lap_struct->ai1_pic_type[i4_num_b_frames + 1] = PIC_TYPE_P;
1082         ps_lap_struct->i4_num_frm_type_decided = i4_num_b_frames + 1;
1083         ps_lap_struct->i4_idr_counter += ps_lap_struct->i4_num_frm_type_decided;
1084         ps_lap_struct->i4_cra_counter += ps_lap_struct->i4_num_frm_type_decided;
1085         ps_lap_struct->i4_i_counter += ps_lap_struct->i4_num_frm_type_decided;
1086     }
1087     ASSERT(i4_num_b_frames != -1);
1088 
1089     return;
1090 }
1091 
1092 /*!
1093 ************************************************************************
1094 * \brief
1095 *    assign pic type to input buf
1096 ************************************************************************
1097 */
ihevce_assign_pic_type(lap_struct_t * ps_lap_struct,ihevce_lap_enc_buf_t * ps_lap_inp_buf)1098 void ihevce_assign_pic_type(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_inp_buf)
1099 {
1100     WORD8 pic_type = ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr];
1101 
1102     switch(pic_type)
1103     {
1104     case PIC_TYPE_I:
1105     {
1106         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_I_FRAME;
1107         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
1108         ps_lap_inp_buf->s_lap_out.i4_is_I_in_any_field = 1;
1109         break;
1110     }
1111     case PIC_TYPE_P:
1112     {
1113         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_P_FRAME;
1114         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
1115         break;
1116     }
1117     case PIC_TYPE_B:
1118     {
1119         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_B_FRAME;
1120         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
1121         break;
1122     }
1123     case PIC_TYPE_IDR:
1124     {
1125         ps_lap_struct->i4_curr_poc = 0;
1126         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_IDR_FRAME;
1127         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 0;
1128         break;
1129     }
1130     case PIC_TYPE_CRA:
1131     {
1132         ps_lap_inp_buf->s_lap_out.i4_pic_type = IV_I_FRAME;
1133         ps_lap_inp_buf->s_lap_out.i4_is_I_in_any_field = 1;
1134         ps_lap_inp_buf->s_lap_out.i4_is_cra_pic = 1;
1135         break;
1136     }
1137     default:
1138         ASSERT(0);
1139     }
1140     return;
1141 }
1142 
1143 /*!
1144 ************************************************************************
1145 * \brief
1146 *    capture order traversal nodes
1147 ************************************************************************
1148 */
ihevce_encode_order_traversal_nodes(ihevce_encode_node_t * encode_node_t,ihevce_lap_enc_buf_t ** encode_order,WORD32 * loop_count,WORD32 curr_layer,lap_struct_t * ps_lap_struct)1149 void ihevce_encode_order_traversal_nodes(
1150     ihevce_encode_node_t *encode_node_t,
1151     ihevce_lap_enc_buf_t **encode_order,
1152     WORD32 *loop_count,
1153     WORD32 curr_layer,
1154     lap_struct_t *ps_lap_struct)
1155 {
1156     if(encode_node_t == NULL)
1157         return;
1158 
1159     encode_order[*loop_count] = (ihevce_lap_enc_buf_t *)encode_node_t->ps_lap_top_buff;
1160 
1161     if(encode_order[*loop_count] != NULL)
1162     {
1163         ihevce_lap_enc_buf_t *ps_lap_inp;
1164 
1165         ps_lap_struct->pi4_encode_poc_ptr[0] = encode_node_t->data;
1166         ref_b_pic_population(curr_layer, encode_order[*loop_count], ps_lap_struct);
1167 
1168         ps_lap_inp = (ihevce_lap_enc_buf_t *)encode_order[*loop_count];
1169         ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
1170 
1171         ps_lap_struct->pi4_encode_poc_ptr++;
1172     }
1173 
1174     (*loop_count) = (*loop_count) + 1;
1175 
1176     /* Pre-order Left-node traversal*/
1177     ihevce_encode_order_traversal_nodes(
1178         (ihevce_encode_node_t *)encode_node_t->pv_left_node,
1179         encode_order,
1180         loop_count,
1181         curr_layer + 1,
1182         ps_lap_struct);
1183 
1184     /* Pre-order Right-node traversal*/
1185     ihevce_encode_order_traversal_nodes(
1186         (ihevce_encode_node_t *)encode_node_t->pv_right_node,
1187         encode_order,
1188         loop_count,
1189         curr_layer + 1,
1190         ps_lap_struct);
1191 }
1192 
1193 /*!
1194 ************************************************************************
1195 * \brief
1196 *    capture order traversal nodes
1197 ************************************************************************
1198 */
ihevce_capture_order_traversal_nodes(ihevce_encode_node_t * encode_node_t,ihevce_lap_enc_buf_t ** api4_capture_order_array,WORD32 * capture_order_poc_array,WORD32 * loop_count,WORD32 i4_interlace_field)1199 void ihevce_capture_order_traversal_nodes(
1200     ihevce_encode_node_t *encode_node_t,
1201     ihevce_lap_enc_buf_t **api4_capture_order_array,
1202     WORD32 *capture_order_poc_array,
1203     WORD32 *loop_count,
1204     WORD32 i4_interlace_field)
1205 {
1206     if(encode_node_t == NULL)
1207         return;
1208 
1209     /* Inorder Insertion for the left-child node */
1210     ihevce_capture_order_traversal_nodes(
1211         (ihevce_encode_node_t *)encode_node_t->pv_left_node,
1212         api4_capture_order_array,
1213         capture_order_poc_array,
1214         loop_count,
1215         i4_interlace_field);
1216 
1217     if(i4_interlace_field)
1218     {
1219         encode_node_t->ps_lap_top_buff =
1220             (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count];
1221         encode_node_t->data = capture_order_poc_array[*loop_count];
1222         encode_node_t->ps_lap_bottom_buff =
1223             (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count + 1];
1224     }
1225     else
1226     {
1227         encode_node_t->ps_lap_top_buff =
1228             (ihevce_lap_enc_buf_t *)api4_capture_order_array[*loop_count];
1229         encode_node_t->data = capture_order_poc_array[*loop_count];
1230     }
1231     if(i4_interlace_field)
1232         (*loop_count) = (*loop_count) + 2;
1233     else
1234         (*loop_count) = (*loop_count) + 1;
1235 
1236     /* Inorder Insertion for the right-child node */
1237     ihevce_capture_order_traversal_nodes(
1238         (ihevce_encode_node_t *)encode_node_t->pv_right_node,
1239         api4_capture_order_array,
1240         capture_order_poc_array,
1241         loop_count,
1242         i4_interlace_field);
1243 }
1244 
1245 /*!
1246 ************************************************************************
1247 * \brief
1248 *    I/P pic population
1249 ************************************************************************
1250 */
ihevce_ip_pic_population(ihevce_encode_node_t * ps_encode_node,lap_struct_t * ps_lap_struct,WORD32 i4_first_gop)1251 void ihevce_ip_pic_population(
1252     ihevce_encode_node_t *ps_encode_node, lap_struct_t *ps_lap_struct, WORD32 i4_first_gop)
1253 {
1254     ihevce_lap_enc_buf_t *ps_lap_inp = NULL;
1255     WORD32 hier_layer = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
1256     WORD32 sub_gop_size = ps_lap_struct->i4_dyn_sub_gop_size;
1257     ihevce_lap_enc_buf_t **api4_capture_order_array = ps_lap_struct->api4_capture_order_array;
1258     ihevce_lap_enc_buf_t **api4_encode_order_array = ps_lap_struct->api4_encode_order_array;
1259     WORD32 *ai4_capture_order_poc = ps_lap_struct->pi4_capture_poc_ptr;
1260 
1261     /* Populate the encode order POC dependent on IDR frames and Interlace Field*/
1262     if(1 == ps_lap_struct->i4_idr_flag)
1263     {
1264         if(i4_first_gop)
1265         {
1266             api4_encode_order_array[0] = api4_capture_order_array[0];
1267 
1268             if(api4_encode_order_array[0] != NULL)
1269             {
1270                 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[0];
1271                 ref_pic_population(api4_encode_order_array[0], ps_lap_struct);
1272 
1273                 ps_lap_inp = api4_encode_order_array[0];
1274                 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
1275 
1276                 ps_lap_struct->pi4_encode_poc_ptr++;
1277             }
1278 
1279             if(ps_lap_struct->i4_immediate_idr_case != 1)
1280             {
1281                 api4_encode_order_array[1] = api4_capture_order_array[sub_gop_size];
1282 
1283                 if(api4_encode_order_array[1] != NULL)
1284                 {
1285                     ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size];
1286                     ref_pic_population(api4_encode_order_array[1], ps_lap_struct);
1287 
1288                     ps_lap_inp = api4_encode_order_array[1];
1289                     ihevce_rc_populate_common_params(
1290                         &ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
1291 
1292                     ps_lap_struct->pi4_encode_poc_ptr++;
1293                 }
1294             }
1295         }
1296         else
1297         {
1298             api4_encode_order_array[0] = api4_capture_order_array[sub_gop_size - 1];
1299 
1300             if(api4_encode_order_array[0] != NULL)
1301             {
1302                 ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size - 1];
1303                 ref_pic_population(api4_encode_order_array[0], ps_lap_struct);
1304 
1305                 ps_lap_inp = api4_encode_order_array[0];
1306                 ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
1307 
1308                 ps_lap_struct->pi4_encode_poc_ptr++;
1309             }
1310         }
1311     }
1312     else
1313     {
1314         api4_encode_order_array[0] = api4_capture_order_array[sub_gop_size - 1];
1315 
1316         if(api4_encode_order_array[0] != NULL)
1317         {
1318             ps_lap_struct->pi4_encode_poc_ptr[0] = ai4_capture_order_poc[sub_gop_size - 1];
1319             ref_pic_population(api4_encode_order_array[0], ps_lap_struct);
1320 
1321             ps_lap_inp = api4_encode_order_array[0];
1322             ihevce_rc_populate_common_params(&ps_lap_inp->s_lap_out, &ps_lap_inp->s_rc_lap_out);
1323 
1324             ps_lap_struct->pi4_encode_poc_ptr++;
1325         }
1326     }
1327     return;
1328 }
1329 
1330 /*!
1331 ************************************************************************
1332 * \brief
1333 *    B pic population
1334 ************************************************************************
1335 */
ihevce_b_pic_population(ihevce_encode_node_t * ps_encode_node,lap_struct_t * ps_lap_struct)1336 void ihevce_b_pic_population(ihevce_encode_node_t *ps_encode_node, lap_struct_t *ps_lap_struct)
1337 {
1338     WORD32 interlace_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
1339     ihevce_lap_enc_buf_t **api4_encode_order_array = ps_lap_struct->api4_encode_order_array;
1340     WORD32 *capture_order_poc_array = ps_lap_struct->pi4_capture_poc_ptr;
1341     WORD32 loop_count = 0;
1342 
1343     /* encoder_order offset changed dependent on IDR and Interlace Field */
1344     if(ps_lap_struct->i4_idr_flag)
1345         loop_count = 1 + interlace_field;
1346 
1347     /* Inorder Insertion of POC in tree, for capture order */
1348     ihevce_capture_order_traversal_nodes(
1349         ps_encode_node,
1350         &ps_lap_struct->api4_capture_order_array[0],
1351         capture_order_poc_array,
1352         &loop_count,
1353         interlace_field);
1354 
1355     /* encoder_order offset changed dependent on IDR and Interlace Field */
1356     /* If the gop_size is multiple of CRA period , decrement loop count */
1357     if(ps_lap_struct->i4_idr_flag)
1358         loop_count = 2 + (interlace_field * 2);
1359     else
1360         loop_count = 1 + interlace_field;
1361 
1362     /* Pre-order traversal of the tree to get encode-order POCs*/
1363     ihevce_encode_order_traversal_nodes(
1364         ps_encode_node, api4_encode_order_array, &loop_count, 1, ps_lap_struct);
1365 
1366     return;
1367 }
1368 
1369 /*!
1370 ************************************************************************
1371 * \brief
1372 *    rc_update_model_control_by_lap_for_modified_sub_gop
1373 ************************************************************************
1374 */
rc_update_model_control_by_lap_for_modified_sub_gop(lap_struct_t * ps_lap_struct,ihevce_lap_enc_buf_t * ps_lap_out_buf)1375 void rc_update_model_control_by_lap_for_modified_sub_gop(
1376     lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf)
1377 {
1378     ihevce_lap_output_params_t *ps_lap_out = &ps_lap_out_buf->s_lap_out;
1379 
1380     /* model update flag for rc*/
1381     if(ps_lap_out->i4_pic_type == IV_P_FRAME)
1382     {
1383         WORD32 i4_loop = 0;
1384         WORD32 i4_min_delta_poc = 0x7FFFFFFF;
1385 
1386         for(i4_loop = 0; i4_loop < ps_lap_out->i4_num_ref_pics; i4_loop++)
1387         {
1388             if(i4_min_delta_poc > ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc))
1389             {
1390                 i4_min_delta_poc = ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc);
1391             }
1392         }
1393     }
1394 
1395     if(ps_lap_out->i4_pic_type == IV_B_FRAME)
1396     {
1397         WORD32 i4_loop = 0;
1398         WORD32 i4_min_delta_poc = 0x7FFFFFFF;
1399         WORD32 i4_min_delta_poc_for_b =
1400             (1 << ps_lap_struct->s_lap_static_params.i4_max_temporal_layers) /
1401             (ps_lap_out->i4_temporal_lyr_id + 1);
1402 
1403         for(i4_loop = 0; i4_loop < ps_lap_out->i4_num_ref_pics; i4_loop++)
1404         {
1405             if(i4_min_delta_poc > ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc))
1406             {
1407                 i4_min_delta_poc = ABS(ps_lap_out->as_ref_pics[i4_loop].i4_ref_pic_delta_poc);
1408             }
1409         }
1410     }
1411     return;
1412 }
1413 
1414 /*!
1415 ************************************************************************
1416 * \brief
1417 *    Update num of pic type for rc
1418 ************************************************************************
1419 */
update_rc_num_pic_type(lap_struct_t * ps_lap_struct,ihevce_lap_enc_buf_t * ps_lap_out_buf)1420 void update_rc_num_pic_type(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf)
1421 {
1422     WORD32 i4_field_flag = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
1423     rc_lap_out_params_t *ps_rc_lap_out = &ps_lap_out_buf->s_rc_lap_out;
1424 
1425     ps_lap_struct->i4_lap2_counter++;
1426 
1427     if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_I_FRAME ||
1428        ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME)
1429     {
1430         ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = I_PIC;
1431         GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
1432     }
1433     else if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_P_FRAME)
1434     {
1435         if(ps_lap_out_buf->s_lap_out.i4_first_field)
1436         {
1437             ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = P_PIC;
1438         }
1439         else
1440         {
1441             ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = P1_PIC;
1442         }
1443         GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
1444     }
1445     else if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_B_FRAME)
1446     {
1447         if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 1)
1448         {
1449             if(ps_lap_out_buf->s_lap_out.i4_first_field)
1450             {
1451                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B_PIC;
1452             }
1453             else
1454             {
1455                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = BB_PIC;
1456             }
1457             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
1458         }
1459         else if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 2)
1460         {
1461             if(ps_lap_out_buf->s_lap_out.i4_first_field)
1462             {
1463                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B1_PIC;
1464             }
1465             else
1466             {
1467                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B11_PIC;
1468             }
1469             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
1470         }
1471         else if(ps_lap_out_buf->s_lap_out.i4_temporal_lyr_id == 3)
1472         {
1473             if(ps_lap_out_buf->s_lap_out.i4_first_field)
1474             {
1475                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B2_PIC;
1476             }
1477             else
1478             {
1479                 ps_lap_struct->ai4_pic_type_to_be_removed[ps_lap_struct->i4_enq_idx] = B22_PIC;
1480             }
1481             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_enq_idx, 1, NUM_LAP2_LOOK_AHEAD);
1482         }
1483         else
1484         {
1485             ASSERT(0);
1486         }
1487     }
1488     else
1489     {
1490         ASSERT(0);
1491     }
1492 
1493     if(!ps_lap_struct->i4_rc_lap_period)
1494     {
1495         if(ps_lap_struct->i4_rc_lap_period < ps_lap_struct->i4_gop_period)
1496         {
1497             WORD32 i4_loop;
1498             WORD32 idx = 0;
1499             WORD32 i4_max_temporal_layer =
1500                 ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
1501 
1502             for(i4_loop = 0;
1503                 i4_loop < (ps_lap_struct->i4_gop_period - ps_lap_struct->i4_rc_lap_period);
1504                 i4_loop++)
1505             {
1506                 ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++;
1507 
1508                 if(i4_max_temporal_layer == 0)
1509                 {
1510                     if(ps_lap_struct->i4_is_all_i_pic_in_seq)
1511                     {
1512                         ps_rc_lap_out->ai4_num_pic_type[I_PIC]++;
1513                     }
1514                     else
1515                     {
1516                         /*second field*/
1517                         if((i4_loop & 1) && i4_field_flag)
1518                         {
1519                             ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++;
1520                         }
1521                         else
1522                         {
1523                             ps_rc_lap_out->ai4_num_pic_type[P_PIC]++;
1524                         }
1525                     }
1526                 }
1527                 else
1528                 {
1529                     ps_rc_lap_out->ai4_num_pic_type
1530                         [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++;
1531 
1532                     GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag));
1533                 }
1534             }
1535         }
1536     }
1537     else
1538     {
1539         ASSERT(ps_lap_struct->i4_lap2_counter <= ps_lap_struct->i4_rc_lap_period);
1540 
1541         if(ps_lap_struct->i4_lap2_counter == ps_lap_struct->i4_rc_lap_period)
1542         {
1543             WORD32 i4_loop, i4_period, i4_next_i_pic = 0;
1544             WORD32 i4_stop_count = 0;
1545             WORD32 i4_temp_deq = ps_lap_struct->i4_deq_idx;
1546             WORD32 i4_first_pic_type = ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq];
1547 
1548             if(ps_lap_struct->i4_rc_lap_period >= ps_lap_struct->i4_gop_period)
1549             {
1550                 i4_period = ps_lap_struct->i4_gop_period;
1551             }
1552             else
1553             {
1554                 i4_period = ps_lap_struct->i4_rc_lap_period;
1555             }
1556 
1557             for(i4_loop = 0; i4_loop < i4_period; i4_loop++)
1558             {
1559                 if(ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq] == I_PIC && i4_loop &&
1560                    i4_first_pic_type == I_PIC)
1561                 {
1562                     i4_stop_count = 1;
1563                 }
1564 
1565                 if(!i4_stop_count)
1566                 {
1567                     ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++;
1568                 }
1569 
1570                 ps_rc_lap_out
1571                     ->ai4_num_pic_type[ps_lap_struct->ai4_pic_type_to_be_removed[i4_temp_deq]]++;
1572 
1573                 GET_IDX_CIRCULAR_BUF(i4_temp_deq, 1, NUM_LAP2_LOOK_AHEAD);
1574             }
1575             if(ps_lap_struct->i4_rc_lap_period < ps_lap_struct->i4_gop_period)
1576             {
1577                 WORD32 i4_loop;
1578                 WORD32 idx = 0;
1579                 WORD32 i4_max_temporal_layer =
1580                     ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
1581 
1582                 for(i4_loop = 0;
1583                     i4_loop < (ps_lap_struct->i4_gop_period - ps_lap_struct->i4_rc_lap_period) &&
1584                     (!i4_next_i_pic);
1585                     i4_loop++)
1586                 {
1587                     if(!i4_stop_count)
1588                     {
1589                         ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead++;
1590                     }
1591 
1592                     if(i4_max_temporal_layer == 0)
1593                     {
1594                         if(ps_lap_struct->i4_is_all_i_pic_in_seq)
1595                         {
1596                             ps_rc_lap_out->ai4_num_pic_type[I_PIC]++;
1597                         }
1598                         else
1599                         {
1600                             /*second field*/
1601                             if((i4_loop & 1) && i4_field_flag)
1602                             {
1603                                 ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++;
1604                             }
1605                             else
1606                             {
1607                                 ps_rc_lap_out->ai4_num_pic_type[P_PIC]++;
1608                             }
1609                         }
1610                     }
1611                     else
1612                     {
1613                         ps_rc_lap_out->ai4_num_pic_type
1614                             [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++;
1615                         GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag));
1616                     }
1617                 }
1618             }
1619             /*remove one pic type*/
1620             GET_IDX_CIRCULAR_BUF(ps_lap_struct->i4_deq_idx, 1, NUM_LAP2_LOOK_AHEAD);
1621             ps_lap_struct->i4_lap2_counter--;
1622         }
1623     }
1624 
1625     {
1626         WORD32 i4_loop;
1627         WORD32 idx = 0;
1628         WORD32 i4_max_temporal_layer = ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
1629         WORD32 i4_num_pictype = 0;
1630 
1631         for(i4_loop = 0; i4_loop < MAX_PIC_TYPE; i4_loop++)
1632         {
1633             i4_num_pictype += ps_rc_lap_out->ai4_num_pic_type[i4_loop];
1634         }
1635 
1636         if(!i4_num_pictype)
1637         {
1638             ps_rc_lap_out->i4_next_sc_i_in_rc_look_ahead = ps_lap_struct->i4_gop_period;
1639 
1640             for(i4_loop = 0; i4_loop < (ps_lap_struct->i4_gop_period); i4_loop++)
1641             {
1642                 if(i4_max_temporal_layer == 0)
1643                 {
1644                     if(ps_lap_struct->i4_is_all_i_pic_in_seq)
1645                     {
1646                         ps_rc_lap_out->ai4_num_pic_type[I_PIC]++;
1647                     }
1648                     else
1649                     {
1650                         /*second field*/
1651                         if((i4_loop & 1) && i4_field_flag)
1652                         {
1653                             ps_rc_lap_out->ai4_num_pic_type[P1_PIC]++;
1654                         }
1655                         else
1656                         {
1657                             ps_rc_lap_out->ai4_num_pic_type[P_PIC]++;
1658                         }
1659                     }
1660                 }
1661                 else
1662                 {
1663                     ps_rc_lap_out->ai4_num_pic_type
1664                         [gau1_order_insert_pic_type[i4_max_temporal_layer - 1][idx]]++;
1665 
1666                     GET_IDX_CIRCULAR_BUF(idx, 1, (8 << i4_field_flag));
1667                 }
1668             }
1669         }
1670     }
1671     /*FOR RC : ensure  at least 1 I pic in the gop period at any case*/
1672     if(!ps_rc_lap_out->ai4_num_pic_type[I_PIC])
1673     {
1674         ASSERT(ps_rc_lap_out->ai4_num_pic_type[P_PIC]);
1675         ps_lap_out_buf->s_rc_lap_out.ai4_num_pic_type[P_PIC]--;
1676         ps_lap_out_buf->s_rc_lap_out.ai4_num_pic_type[I_PIC]++;
1677     }
1678     return;
1679 }
1680 
1681 /*!
1682 ************************************************************************
1683 * \brief
1684 *    pre rel lap output update
1685 ************************************************************************
1686 */
ihevce_pre_rel_lapout_update(lap_struct_t * ps_lap_struct,ihevce_lap_enc_buf_t * ps_lap_out_buf)1687 void ihevce_pre_rel_lapout_update(lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_lap_out_buf)
1688 {
1689     WORD32 i4_first_field = 1;
1690     WORD32 i4_field = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
1691 
1692     if(i4_field)
1693     {
1694         i4_first_field = ps_lap_out_buf->s_lap_out.i4_first_field;
1695     }
1696 
1697     ps_lap_out_buf->s_lap_out.i4_used = 0;
1698 
1699     rc_update_model_control_by_lap_for_modified_sub_gop(ps_lap_struct, ps_lap_out_buf);
1700     update_rc_num_pic_type(ps_lap_struct, ps_lap_out_buf);
1701 
1702     /* curr buf next is null, prev buf next is curr and prev buff equal to curr*/
1703 
1704     ps_lap_out_buf->s_rc_lap_out.ps_rc_lap_out_next_encode = NULL;
1705     if(ps_lap_struct->pv_prev_inp_buf != NULL &&
1706        ps_lap_struct->s_lap_static_params.s_lap_params.i4_rc_look_ahead_pics)
1707     {
1708         ((ihevce_lap_enc_buf_t *)ps_lap_struct->pv_prev_inp_buf)
1709             ->s_rc_lap_out.ps_rc_lap_out_next_encode = (void *)&ps_lap_out_buf->s_rc_lap_out;
1710     }
1711 
1712     ps_lap_struct->pv_prev_inp_buf = (void *)ps_lap_out_buf;
1713     ps_lap_out_buf->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene = 1;
1714 
1715     /*with force idr below check is not valid*/
1716 #if(!FORCE_IDR_TEST)
1717     if(ps_lap_struct->i4_max_idr_period == ps_lap_struct->i4_min_idr_period)
1718     {
1719         if(!ps_lap_out_buf->s_lap_out.i4_poc)
1720         {
1721             ASSERT(ps_lap_struct->i4_max_prev_poc == (ps_lap_struct->i4_max_idr_period - 1));
1722             ps_lap_struct->i4_max_prev_poc = 0;
1723         }
1724     }
1725 #endif
1726 
1727     /*assert if num of reference frame is zero in case of P or B frame*/
1728     if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_P_FRAME ||
1729        ps_lap_out_buf->s_lap_out.i4_pic_type == IV_B_FRAME)
1730     {
1731         ASSERT(ps_lap_out_buf->s_lap_out.i4_num_ref_pics != 0);
1732     }
1733 
1734     /*assert if poc = 0 and pictype is not an idr*/
1735     if(ps_lap_out_buf->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
1736        ps_lap_out_buf->s_lap_out.i4_poc == 0)
1737     {
1738         ASSERT(0);
1739     }
1740     if(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME &&
1741        ps_lap_out_buf->s_lap_out.i4_poc != 0)
1742     {
1743         ASSERT(0);
1744     }
1745     if(ps_lap_out_buf->s_lap_out.i4_poc < 0)
1746     {
1747         ASSERT(0);
1748     }
1749 
1750 #if(!FORCE_IDR_TEST)
1751     if((!ps_lap_struct->i4_max_idr_period) && ps_lap_out_buf->s_lap_out.i4_display_num != 0)
1752     {
1753         ASSERT(ps_lap_out_buf->s_lap_out.i4_pic_type != IV_IDR_FRAME);
1754     }
1755 #endif
1756     if(!ps_lap_struct->i4_max_cra_period)
1757     {
1758         ASSERT(ps_lap_out_buf->s_lap_out.i4_is_cra_pic != 1);
1759     }
1760 
1761     if(ps_lap_out_buf->s_lap_out.i4_force_idr_flag)
1762     {
1763         ASSERT(ps_lap_out_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME);
1764     }
1765     ps_lap_out_buf->s_lap_out.i4_curr_frm_qp = -1;
1766 }
1767 
1768 /*!
1769 ************************************************************************
1770 * \brief
1771 *    lap queue input
1772 ************************************************************************
1773 */
ihevce_lap_queue_input(lap_struct_t * ps_lap_struct,ihevce_lap_enc_buf_t * ps_input_lap_enc_buf,WORD32 * pi4_tree_num)1774 void ihevce_lap_queue_input(
1775     lap_struct_t *ps_lap_struct, ihevce_lap_enc_buf_t *ps_input_lap_enc_buf, WORD32 *pi4_tree_num)
1776 {
1777     ihevce_encode_node_t *ps_encode_node =
1778         (ihevce_encode_node_t *)ps_lap_struct->aps_encode_node[*pi4_tree_num];
1779 
1780     WORD32 i4_capture_idx = ps_lap_struct->i4_capture_idx;
1781 
1782     /* Static Lap parameters */
1783     ihevce_lap_static_params_t *ps_lap_static_params =
1784         (ihevce_lap_static_params_t *)&ps_lap_struct->s_lap_static_params;
1785 
1786     WORD32 hier_layer = ps_lap_static_params->i4_max_temporal_layers;
1787     WORD32 sub_gop_size = ps_lap_struct->i4_dyn_sub_gop_size;
1788 
1789     /* queue the current input in capture array */
1790     {
1791         WORD32 first_gop_flag;
1792 
1793         if(!i4_capture_idx)
1794         {
1795             memset(
1796                 &ps_lap_struct->api4_capture_order_array[0],
1797                 0,
1798                 sizeof(ihevce_lap_enc_buf_t *) * MAX_NUM_ENC_NODES);
1799         }
1800         ps_lap_struct->api4_capture_order_array[i4_capture_idx] = ps_input_lap_enc_buf;
1801 
1802         if(ps_input_lap_enc_buf != NULL)
1803         {
1804             if(ps_input_lap_enc_buf->s_lap_out.i4_end_flag == 1)
1805                 ps_lap_struct->i4_end_flag_pic_idx = i4_capture_idx;
1806             ps_lap_struct->ai4_capture_order_poc[i4_capture_idx] = ps_lap_struct->i4_curr_poc++;
1807         }
1808 
1809         if((1 == ps_lap_struct->i4_num_dummy_pic) && (ps_lap_struct->i4_sub_gop_end == 0))
1810         {
1811             ps_lap_struct->i4_sub_gop_end = i4_capture_idx - 1;
1812         }
1813         i4_capture_idx++;
1814 
1815         /* to take care of buffering 1 extra picture at start or at IDR interval*/
1816         if(!ps_lap_struct->i4_is_all_i_pic_in_seq)
1817         {
1818             if(ps_lap_static_params->i4_src_interlace_field && sub_gop_size <= 2)
1819             {
1820                 first_gop_flag = 0;
1821             }
1822             else
1823             {
1824                 first_gop_flag = ps_lap_struct->i4_idr_flag
1825                                  << ps_lap_static_params->i4_src_interlace_field;
1826             }
1827         }
1828         else
1829         {
1830             first_gop_flag = ps_lap_struct->i4_idr_flag;
1831         }
1832 
1833         /* For every IDR period, set idr_flag and reset POC value and gop_size to 0*/
1834         if(ps_input_lap_enc_buf != NULL)
1835         {
1836             if((!first_gop_flag) && (ps_input_lap_enc_buf->s_lap_out.i4_pic_type == IV_IDR_FRAME))
1837             {
1838                 ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0];
1839                 ps_lap_struct->i4_idr_flag = 1;
1840                 ps_lap_struct->i4_curr_poc = 0;
1841                 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 1] =
1842                     ps_lap_struct->i4_curr_poc++;
1843             }
1844         }
1845 
1846         if(first_gop_flag &&
1847            (ps_lap_struct->i4_is_all_i_pic_in_seq || ps_lap_struct->i4_immediate_idr_case))
1848         {
1849             sub_gop_size = 0;
1850         }
1851 
1852         if(!first_gop_flag && ps_lap_struct->i4_immediate_idr_case &&
1853            (i4_capture_idx != (sub_gop_size + first_gop_flag)))
1854         {
1855             sub_gop_size = 1 << ps_lap_static_params->i4_src_interlace_field;
1856             ps_lap_struct->i4_dyn_sub_gop_size = 1 << ps_lap_static_params->i4_src_interlace_field;
1857         }
1858 
1859         /* reset the queue idx end of every gop */
1860         if(i4_capture_idx == (sub_gop_size + first_gop_flag))
1861         {
1862             ps_lap_struct->pi4_encode_poc_ptr = &ps_lap_struct->ai4_encode_order_poc[0];
1863 
1864             if(ps_lap_struct->i4_end_flag_pic_idx && (1 != sub_gop_size))
1865             {
1866                 WORD32 i4_temp_poc = 0;
1867                 ihevce_lap_enc_buf_t *ps_temp_lap_enc_buf = NULL;
1868 
1869                 /*swap the lap enc buf and poc*/
1870                 ps_temp_lap_enc_buf =
1871                     ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx - 1];
1872                 ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx - 1] =
1873                     NULL;
1874                 ps_lap_struct->api4_capture_order_array[i4_capture_idx - 2] =
1875                     ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx];
1876 
1877                 if((i4_capture_idx - 2) != ps_lap_struct->i4_end_flag_pic_idx)
1878                     ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_end_flag_pic_idx] =
1879                         NULL;
1880 
1881                 ps_temp_lap_enc_buf->s_lap_out.i4_pic_type = IV_P_FRAME;
1882                 ps_lap_struct->api4_capture_order_array[i4_capture_idx - 1] = ps_temp_lap_enc_buf;
1883 
1884                 i4_temp_poc =
1885                     ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_end_flag_pic_idx - 1];
1886                 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 2] =
1887                     ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_end_flag_pic_idx];
1888 
1889                 ps_lap_struct->ai4_capture_order_poc[i4_capture_idx - 1] = i4_temp_poc;
1890             }
1891 
1892             if(ps_lap_struct->i4_num_dummy_pic)
1893             {
1894                 WORD32 pic_idx;
1895                 ihevce_lap_enc_buf_t *ps_temp_lap_enc_buf = NULL;
1896                 static const WORD32 subgop_temporal_layer3[8] = { 7, 3, 1, 0, 2, 5, 4, 6 };
1897                 static const WORD32 subgop_temporal_layer2[4] = { 3, 1, 0, 2 };
1898                 const WORD32 *subgop_pic_idx = (ps_lap_static_params->i4_max_temporal_layers == 2)
1899                                                    ? &subgop_temporal_layer2[0]
1900                                                    : &subgop_temporal_layer3[0];
1901                 WORD32 max_pic_count = ps_lap_struct->i4_sub_gop_end + 1;
1902 
1903                 for(pic_idx = 0; pic_idx < max_pic_count; pic_idx++)
1904                 {
1905                     WORD32 i4_temp_idx = ps_lap_static_params->i4_max_temporal_layers > 1
1906                                              ? subgop_pic_idx[pic_idx]
1907                                              : 1;
1908 
1909                     if(NULL == ps_lap_struct->api4_capture_order_array[i4_temp_idx])
1910                     {
1911                         ps_temp_lap_enc_buf =
1912                             ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_sub_gop_end];
1913                         if(pic_idx == 0)
1914                         {
1915                             ps_temp_lap_enc_buf->s_lap_out.i4_pic_type = IV_P_FRAME;
1916                         }
1917                         ps_lap_struct->api4_capture_order_array[i4_temp_idx] = ps_temp_lap_enc_buf;
1918                         ps_lap_struct->api4_capture_order_array[ps_lap_struct->i4_sub_gop_end] =
1919                             NULL;
1920 
1921                         ps_lap_struct->ai4_capture_order_poc[i4_temp_idx] =
1922                             ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_sub_gop_end];
1923                         ps_lap_struct->ai4_capture_order_poc[ps_lap_struct->i4_sub_gop_end] = 0;
1924                         ps_lap_struct->i4_sub_gop_end--;
1925                     }
1926                 }
1927                 ps_lap_struct->i4_sub_gop_end = 0;
1928             }
1929             i4_capture_idx = 0;
1930 
1931             /* add the number of pics in sub gop to the gop counter */
1932             /* Get reordered Buffer for encoder, wait till all sub-gop buffers are output */
1933 
1934             /* Popluate I/P pictures */
1935             ihevce_ip_pic_population(ps_encode_node, ps_lap_struct, first_gop_flag);
1936 
1937             /* For hierarchical layers, Populate B picture */
1938             if((hier_layer > 0) &&
1939                sub_gop_size > (1 << ps_lap_static_params->i4_src_interlace_field))
1940             {
1941                 ihevce_b_pic_population(ps_encode_node, ps_lap_struct);
1942             }
1943 
1944             ps_lap_struct->i4_num_bufs_encode_order = sub_gop_size + first_gop_flag;
1945 
1946             /* correction of encode order in case of multiple non reference B*/
1947             if(ps_lap_struct->i4_dyn_sub_gop_size > ps_lap_struct->i4_sub_gop_size)
1948             {
1949                 WORD32 i4_loop;
1950                 ihevce_lap_enc_buf_t *ps_lap_enc_buf, *ps_lap_enc_buf_tmp[MAX_NUM_ENC_NODES];
1951                 WORD32 i4_enc_cnt, i4_cap_cnt;
1952 
1953                 i4_cap_cnt = first_gop_flag;
1954                 i4_enc_cnt = 0;
1955 
1956                 for(i4_loop = 0; i4_loop < ps_lap_struct->i4_num_bufs_encode_order; i4_loop++)
1957                 {
1958                     ps_lap_enc_buf = ps_lap_struct->api4_encode_order_array[i4_loop];
1959 
1960                     if(ps_lap_enc_buf != NULL && !ps_lap_enc_buf->s_lap_out.i4_is_ref_pic &&
1961                        (ps_lap_enc_buf->s_lap_out.i4_temporal_lyr_id ==
1962                         ps_lap_struct->s_lap_static_params.i4_max_temporal_layers))
1963                     {
1964                         if(ps_lap_enc_buf != ps_lap_struct->api4_capture_order_array[i4_cap_cnt])
1965                         {
1966                             ps_lap_enc_buf_tmp[i4_enc_cnt] =
1967                                 ps_lap_struct->api4_capture_order_array[i4_cap_cnt];
1968                             i4_enc_cnt++;
1969                             i4_loop++;
1970                         }
1971                         i4_cap_cnt += 2;
1972                         ps_lap_enc_buf_tmp[i4_enc_cnt] = ps_lap_enc_buf;
1973                         i4_enc_cnt++;
1974                         ps_lap_enc_buf_tmp[i4_enc_cnt] =
1975                             ps_lap_struct->api4_capture_order_array[i4_cap_cnt];
1976                         i4_enc_cnt++;
1977                         i4_cap_cnt += 2;
1978                         i4_loop++;
1979                     }
1980                     else
1981                     {
1982                         ps_lap_enc_buf_tmp[i4_enc_cnt] = ps_lap_enc_buf;
1983                         i4_enc_cnt++;
1984                     }
1985                 }
1986                 for(i4_loop = 0; i4_loop < ps_lap_struct->i4_num_bufs_encode_order; i4_loop++)
1987                 {
1988                     ps_lap_struct->api4_encode_order_array[i4_loop] = ps_lap_enc_buf_tmp[i4_loop];
1989                 }
1990             }
1991 
1992             /* reset the IDR flag */
1993             ps_lap_struct->i4_idr_flag = 0;
1994             ps_lap_struct->i4_dyn_sub_gop_size = ps_lap_struct->i4_sub_gop_size;
1995 
1996             /*Copy encode array to lap output buf*/
1997             memcpy(
1998                 &ps_lap_struct->api4_lap_out_buf[ps_lap_struct->i4_lap_encode_idx],
1999                 &ps_lap_struct->api4_encode_order_array[0],
2000                 sizeof(ihevce_lap_enc_buf_t *) * ps_lap_struct->i4_num_bufs_encode_order);
2001 
2002             memset(
2003                 &ps_lap_struct->api4_encode_order_array[0],
2004                 0,
2005                 sizeof(ihevce_lap_enc_buf_t *) * ps_lap_struct->i4_num_bufs_encode_order);
2006 
2007             ps_lap_struct->ai4_num_buffer[ps_lap_struct->i4_lap_encode_idx] =
2008                 ps_lap_struct->i4_num_bufs_encode_order - ps_lap_struct->i4_num_dummy_pic;
2009 
2010             ps_lap_struct->i4_lap_encode_idx++;
2011             ps_lap_struct->i4_lap_encode_idx &= (MAX_SUBGOP_IN_ENCODE_QUEUE - 1);
2012         }
2013 
2014         /* store the capture index */
2015         ps_lap_struct->i4_capture_idx = i4_capture_idx;
2016         ps_lap_struct->i4_immediate_idr_case = 0;
2017     }
2018     return;
2019 }
2020 
2021 /*!
2022 ************************************************************************
2023 * \brief
2024 *    lap process
2025 ************************************************************************
2026 */
ihevce_lap_process(void * pv_interface_ctxt,ihevce_lap_enc_buf_t * ps_curr_inp)2027 ihevce_lap_enc_buf_t *ihevce_lap_process(void *pv_interface_ctxt, ihevce_lap_enc_buf_t *ps_curr_inp)
2028 {
2029     lap_intface_t *ps_lap_interface = (lap_intface_t *)pv_interface_ctxt;
2030     lap_struct_t *ps_lap_struct = (lap_struct_t *)ps_lap_interface->pv_lap_module_ctxt;
2031     ihevce_hle_ctxt_t *ps_hle_ctxt = (ihevce_hle_ctxt_t *)ps_lap_interface->pv_hle_ctxt;
2032     ihevce_lap_enc_buf_t *ps_lap_inp_buf = ps_curr_inp;
2033     ihevce_tgt_params_t *ps_tgt_params =
2034         &ps_lap_struct->s_static_cfg_params.s_tgt_lyr_prms.as_tgt_params[0];
2035     WORD32 i4_field_flag = ps_lap_struct->s_lap_static_params.i4_src_interlace_field;
2036     WORD32 i4_flush_check = 0;
2037     WORD32 i4_force_idr_check = 0;
2038     WORD32 i4_tree_num = 0;
2039     iv_input_ctrl_buffs_t *ps_ctrl_buf = NULL;
2040     WORD32 buf_id = 0;
2041     WORD32 i4_lap_window_size = 1 << ps_lap_struct->s_lap_static_params.i4_max_temporal_layers;
2042 
2043     ps_lap_interface->i4_ctrl_in_que_blocking_mode = BUFF_QUE_NON_BLOCKING_MODE;
2044 
2045     /* ----------- LAP processing ----------- */
2046     if(ps_lap_struct->end_flag != 1)
2047     {
2048         ASSERT(NULL != ps_curr_inp);
2049 
2050         /* ---------- get the filled control command buffer ------------ */
2051         ps_ctrl_buf = (iv_input_ctrl_buffs_t *)ihevce_q_get_filled_buff(
2052             ps_hle_ctxt->apv_enc_hdl[0],
2053             ps_lap_interface->i4_ctrl_in_que_id,
2054             &buf_id,
2055             ps_lap_interface->i4_ctrl_in_que_blocking_mode);
2056 
2057         /* ----------- check the command ---------------------- */
2058         if(NULL != ps_ctrl_buf)
2059         {
2060             /* check for async errors */
2061             ihevce_dyn_config_prms_t as_dyn_br[MAX_NUM_DYN_BITRATE_CMDS];
2062             WORD32 i4_num_set_bitrate_cmds = 0;
2063             WORD32 bitrt_ctr = 0;
2064 
2065             ihevce_lap_parse_async_cmd(
2066                 ps_hle_ctxt,
2067                 (WORD32 *)ps_ctrl_buf->pv_asynch_ctrl_bufs,
2068                 ps_ctrl_buf->i4_cmd_buf_size,
2069                 ps_ctrl_buf->i4_buf_id,
2070                 &i4_num_set_bitrate_cmds,
2071                 &as_dyn_br[0]);
2072 
2073             /* Call the call back function to register the new bitrate */
2074             for(bitrt_ctr = 0; bitrt_ctr < i4_num_set_bitrate_cmds; bitrt_ctr++)
2075             {
2076                 ps_lap_interface->ihevce_dyn_bitrate_cb(
2077                     (void *)ps_hle_ctxt, (void *)&as_dyn_br[bitrt_ctr]);
2078             }
2079 
2080             /* release async ctrl buffer*/
2081             ihevce_q_rel_buf(
2082                 ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, ps_ctrl_buf->i4_buf_id);
2083         }
2084 
2085         {
2086             WORD32 *pi4_cmd_buf = (WORD32 *)ps_lap_inp_buf->s_input_buf.pv_synch_ctrl_bufs;
2087 
2088             /* check for sync cmd buffer error */
2089             /* check FLUSH comand and Force IDR in the complete buffer */
2090             i4_flush_check = 0;
2091             i4_force_idr_check = 0;
2092             ihevce_lap_parse_sync_cmd(
2093                 ps_hle_ctxt,
2094                 &ps_lap_struct->s_static_cfg_params,
2095                 pi4_cmd_buf,
2096                 ps_lap_inp_buf,
2097                 &i4_flush_check,
2098                 &i4_force_idr_check);
2099 
2100             if(i4_flush_check)
2101                 ps_lap_struct->end_flag = 1;
2102 
2103             ps_lap_inp_buf->s_lap_out.i4_out_flush_flag = 0;
2104             ps_lap_inp_buf->s_lap_out.i4_end_flag = ps_lap_struct->end_flag;
2105 
2106             /* check if input buffer is a valid buffer */
2107             if(1 == ps_lap_inp_buf->s_input_buf.i4_inp_frm_data_valid_flag)
2108             {
2109                 /* Initialise laps input buffer descriptors */
2110                 memset(&ps_lap_inp_buf->s_lap_out, 0, sizeof(ihevce_lap_output_params_t));
2111                 memset(&ps_lap_inp_buf->s_rc_lap_out, 0, sizeof(rc_lap_out_params_t));
2112                 /* Default initialization of lapout parameters */
2113                 ps_lap_inp_buf->s_lap_out.i4_scene_type = SCENE_TYPE_NORMAL;
2114                 ps_lap_inp_buf->s_lap_out.u4_scene_num = 0;
2115                 ps_lap_inp_buf->s_lap_out.i4_display_num = ps_lap_struct->i4_display_num;
2116                 ps_lap_inp_buf->s_lap_out.i4_quality_preset = ps_tgt_params->i4_quality_preset;
2117                 ps_lap_inp_buf->s_lap_out.i1_weighted_pred_flag = 0;
2118                 ps_lap_inp_buf->s_lap_out.i1_weighted_bipred_flag = 0;
2119                 ps_lap_inp_buf->s_lap_out.i4_log2_luma_wght_denom = DENOM_DEFAULT;
2120                 ps_lap_inp_buf->s_lap_out.i4_log2_chroma_wght_denom = DENOM_DEFAULT;
2121                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].i4_num_duplicate_entries_in_ref_list = 1;
2122                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].i4_used_by_cur_pic_flag = 1;
2123                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0].as_wght_off[0].u1_luma_weight_enable_flag =
2124                     0;
2125                 ps_lap_inp_buf->s_lap_out.as_ref_pics[0]
2126                     .as_wght_off[0]
2127                     .u1_chroma_weight_enable_flag = 0;
2128                 ps_lap_inp_buf->s_lap_out.i4_first_field = 1;
2129                 ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 0;
2130                 ps_lap_inp_buf->s_lap_out.i4_curr_frm_qp = ps_tgt_params->ai4_frame_qp[0];
2131                 ps_lap_inp_buf->s_lap_out.i4_used = 1;
2132                 if(i4_force_idr_check)
2133                 {
2134                     ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 1;
2135                 }
2136                 /* Populate input params in lap out struct */
2137                 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_y_buf =
2138                     ps_lap_inp_buf->s_input_buf.s_input_buf.pv_y_buf;
2139                 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_u_buf =
2140                     ps_lap_inp_buf->s_input_buf.s_input_buf.pv_u_buf;
2141                 ps_lap_inp_buf->s_lap_out.s_input_buf.pv_v_buf =
2142                     ps_lap_inp_buf->s_input_buf.s_input_buf.pv_v_buf;
2143                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_wd =
2144                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_wd;
2145                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_ht =
2146                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_ht;
2147                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_y_strd =
2148                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_y_strd;
2149                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_wd =
2150                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_wd;
2151                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_ht =
2152                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_ht;
2153                 ps_lap_inp_buf->s_lap_out.s_input_buf.i4_uv_strd =
2154                     ps_lap_inp_buf->s_input_buf.s_input_buf.i4_uv_strd;
2155 
2156                 ps_lap_struct->i4_display_num++;
2157                 ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_enq_idx] = ps_lap_inp_buf;
2158                 /* update first field flag */
2159                 ps_lap_inp_buf->s_lap_out.i4_first_field = 1;
2160                 if(i4_field_flag)
2161                 {
2162                     ps_lap_inp_buf->s_lap_out.i4_first_field =
2163                         (ps_lap_inp_buf->s_input_buf.i4_topfield_first ^
2164                          ps_lap_inp_buf->s_input_buf.i4_bottom_field);
2165                 }
2166 
2167                 /* force idr in case interlace input can be taken only for first field */
2168                 if(!ps_lap_inp_buf->s_lap_out.i4_first_field)
2169                 {
2170                     ps_lap_inp_buf->s_lap_out.i4_force_idr_flag = 0;
2171                 }
2172 
2173                 if((i4_lap_window_size > 1) &&
2174                    (ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr] != PIC_TYPE_IDR))
2175                 {
2176                     ps_lap_struct->i4_sub_gop_pic_idx++;
2177                     if(ps_lap_struct->i4_sub_gop_pic_idx > i4_lap_window_size)
2178                     {
2179                         ps_lap_struct->i4_sub_gop_pic_idx =
2180                             ps_lap_struct->i4_sub_gop_pic_idx - i4_lap_window_size;
2181                     }
2182                 }
2183                 else if(1 == i4_lap_window_size)
2184                 {
2185                     ps_lap_struct->i4_sub_gop_pic_idx = 1;
2186                 }
2187 
2188                 if(i4_force_idr_check &&
2189                    (ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr] != PIC_TYPE_IDR))
2190                 {
2191                     ps_lap_struct->i4_force_idr_pos = ps_lap_struct->i4_sub_gop_pic_idx;
2192                 }
2193 
2194                 /* store pictype for next subgop */
2195                 if((0 == ps_lap_struct->i4_num_frm_type_decided) &&
2196                    (ps_lap_struct->i4_force_idr_pos == 0))
2197                 {
2198                     ps_lap_struct->ai1_pic_type[0] =
2199                         ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr];
2200 
2201                     ihevce_determine_next_sub_gop_state(ps_lap_struct);
2202 
2203                     ps_lap_struct->i4_next_start_ctr = 0;
2204                 }
2205                 else if(
2206                     i4_force_idr_check &&
2207                     (ps_lap_struct->i4_force_idr_pos <= ps_lap_struct->i4_sub_gop_size))
2208                 {
2209                     /*check force idr pos is 1st pic in sub-gop then don't add dummy pics*/
2210                     if(ps_lap_struct->i4_force_idr_pos != 1)
2211                     {
2212                         WORD32 sub_gop_pos = ps_lap_struct->i4_force_idr_pos;
2213                         while(sub_gop_pos <= ps_lap_struct->i4_sub_gop_size)
2214                         {
2215                             ps_lap_struct->i4_num_dummy_pic++;
2216                             ihevce_lap_queue_input(ps_lap_struct, NULL, &i4_tree_num);
2217                             sub_gop_pos++;
2218                         }
2219                         ps_lap_struct->i4_num_dummy_pic = 0;
2220                     }
2221                     ps_lap_struct->ai1_pic_type[0] =
2222                         ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr];
2223 
2224                     ihevce_determine_next_sub_gop_state(ps_lap_struct);
2225 
2226                     ps_lap_struct->i4_next_start_ctr = 0;
2227                 }
2228 
2229                 if(/*ps_lap_struct->i4_init_delay_over &&*/ 0 !=
2230                    ps_lap_struct->i4_num_frm_type_decided)
2231                 {
2232                     ihevce_assign_pic_type(
2233                         ps_lap_struct,
2234                         ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]);
2235 
2236                     ps_lap_struct->i4_num_frm_type_decided--;
2237 
2238                     if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx])
2239                     {
2240                         /*special case of two consequetive idr at the start of encode or due to force idr*/
2241                         ps_lap_struct->i4_immediate_idr_case =
2242                             ps_lap_struct->i4_is_all_i_pic_in_seq;
2243                         if(ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]
2244                                ->s_lap_out.i4_pic_type == IV_IDR_FRAME)
2245                         {
2246                             ps_lap_struct->i4_immediate_idr_case = 1;
2247                         }
2248                         else
2249                         {
2250                             WORD32 i4_prev_idx = ps_lap_struct->i4_buf_deq_idx > 0
2251                                                      ? ps_lap_struct->i4_buf_deq_idx - 1
2252                                                      : ps_lap_struct->i4_buf_deq_idx;
2253                             /*field case of single IDR field followed by P*/
2254                             if(NULL != ps_lap_struct->aps_lap_inp_buf[i4_prev_idx] &&
2255                                i4_field_flag &&
2256                                ps_lap_struct->aps_lap_inp_buf[i4_prev_idx]->s_lap_out.i4_pic_type ==
2257                                    IV_IDR_FRAME &&
2258                                !ps_lap_struct->i4_num_frm_type_decided)
2259                             {
2260                                 ps_lap_struct->i4_immediate_idr_case = 1;
2261                             }
2262                         }
2263                     }
2264 
2265                     /* Queue in the current input Buffer to LAP que */
2266                     ihevce_lap_queue_input(
2267                         ps_lap_struct,
2268                         ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx],
2269                         &i4_tree_num);
2270 
2271                     ps_lap_struct->i4_next_start_ctr++;
2272                     ps_lap_struct->i4_buf_deq_idx++;
2273                     if(ps_lap_struct->i4_buf_deq_idx >= MAX_QUEUE_LENGTH)
2274                         ps_lap_struct->i4_buf_deq_idx = 0;
2275                 }
2276 
2277                 ps_lap_struct->i4_buf_enq_idx++;
2278                 if(ps_lap_struct->i4_buf_enq_idx >= MAX_QUEUE_LENGTH)
2279                     ps_lap_struct->i4_buf_enq_idx = 0;
2280             } /* end if for valid input buffer check*/
2281         }
2282 
2283         /* source pixel padding if width/height is not aligned to 8 pixel */
2284         if(ps_lap_inp_buf->s_input_buf.i4_inp_frm_data_valid_flag)
2285         {
2286             ihevce_src_params_t *ps_src_prms = &ps_lap_struct->s_static_cfg_params.s_src_prms;
2287             WORD32 i4_align_wd = ps_src_prms->i4_width;
2288             WORD32 i4_align_ht = ps_src_prms->i4_height;
2289             WORD32 min_cu_size =
2290                 (1 << ps_lap_struct->s_static_cfg_params.s_config_prms.i4_min_log2_cu_size);
2291 
2292             i4_align_wd += SET_CTB_ALIGN(ps_src_prms->i4_width, min_cu_size);
2293             i4_align_ht += SET_CTB_ALIGN(ps_src_prms->i4_height, min_cu_size);
2294 
2295             ihevce_lap_pad_input_bufs(ps_lap_inp_buf, i4_align_wd, i4_align_ht);
2296         }
2297         {
2298             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_width = 0;
2299             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_height = 0;
2300             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_x_offset = 0;
2301             ps_lap_inp_buf->s_lap_out.s_logo_ctxt.logo_y_offset = 0;
2302         }
2303     }
2304 
2305     if(ps_lap_struct->end_flag == 1)
2306     {
2307         ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_enq_idx] = ps_lap_inp_buf;
2308 
2309         /*to be filed*/
2310         if(0 == ps_lap_struct->i4_num_frm_type_decided)
2311         {
2312             ps_lap_struct->ai1_pic_type[0] =
2313                 ps_lap_struct->ai1_pic_type[ps_lap_struct->i4_next_start_ctr];
2314 
2315             ihevce_determine_next_sub_gop_state(ps_lap_struct);
2316 
2317             ps_lap_struct->i4_next_start_ctr = 0;
2318         }
2319 
2320         if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx])
2321         {
2322             ihevce_assign_pic_type(
2323                 ps_lap_struct, ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]);
2324         }
2325 
2326         ps_lap_struct->i4_num_frm_type_decided--;
2327 
2328         if(NULL != ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx])
2329         {
2330             /*special case of two consequetive idr at the start of encode or due to force idr*/
2331             ps_lap_struct->i4_immediate_idr_case = ps_lap_struct->i4_is_all_i_pic_in_seq;
2332 
2333             if(ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx]
2334                    ->s_lap_out.i4_pic_type == IV_IDR_FRAME)
2335             {
2336                 ps_lap_struct->i4_immediate_idr_case = 1;
2337             }
2338             else
2339             {
2340                 WORD32 i4_prev_idx = ps_lap_struct->i4_buf_deq_idx > 0
2341                                          ? ps_lap_struct->i4_buf_deq_idx - 1
2342                                          : ps_lap_struct->i4_buf_deq_idx;
2343                 /*field case of single IDR field followed by P*/
2344                 if(NULL != ps_lap_struct->aps_lap_inp_buf[i4_prev_idx] && i4_field_flag &&
2345                    ps_lap_struct->aps_lap_inp_buf[i4_prev_idx]->s_lap_out.i4_pic_type ==
2346                        IV_IDR_FRAME &&
2347                    !ps_lap_struct->i4_num_frm_type_decided)
2348                 {
2349                     ps_lap_struct->i4_immediate_idr_case = 1;
2350                 }
2351             }
2352         }
2353         /* Queue in the current input Buffer to LAP que */
2354         ihevce_lap_queue_input(
2355             ps_lap_struct,
2356             ps_lap_struct->aps_lap_inp_buf[ps_lap_struct->i4_buf_deq_idx],
2357             &i4_tree_num);
2358         ps_lap_struct->i4_max_buf_in_enc_order =
2359             ps_lap_struct->ai4_num_buffer[ps_lap_struct->i4_deq_lap_buf];
2360         ps_lap_struct->i4_next_start_ctr++;
2361         ps_lap_struct->i4_buf_deq_idx++;
2362 
2363         if(ps_lap_struct->i4_buf_deq_idx >= MAX_QUEUE_LENGTH)
2364             ps_lap_struct->i4_buf_deq_idx = 0;
2365 
2366         ps_lap_struct->i4_buf_enq_idx++;
2367         if(ps_lap_struct->i4_buf_enq_idx >= MAX_QUEUE_LENGTH)
2368             ps_lap_struct->i4_buf_enq_idx = 0;
2369     }
2370 
2371     if(1 == ps_lap_struct->i4_force_end_flag)
2372     {
2373         ihevce_force_end(ps_hle_ctxt);
2374     }
2375 
2376     /*return encode order pic to pre enc*/
2377     ps_lap_inp_buf = NULL;
2378 
2379     if(NULL !=
2380        ps_lap_struct->api4_lap_out_buf[ps_lap_struct->i4_deq_lap_buf][ps_lap_struct->i4_lap_out_idx])
2381     {
2382         ps_lap_inp_buf =
2383             ps_lap_struct
2384                 ->api4_lap_out_buf[ps_lap_struct->i4_deq_lap_buf][ps_lap_struct->i4_lap_out_idx];
2385         ps_lap_struct
2386             ->api4_lap_out_buf[ps_lap_struct->i4_deq_lap_buf][ps_lap_struct->i4_lap_out_idx] = NULL;
2387         if(!ps_lap_inp_buf->s_lap_out.i4_end_flag)
2388             ihevce_pre_rel_lapout_update(ps_lap_struct, ps_lap_inp_buf);
2389 
2390         ps_lap_struct->i4_max_buf_in_enc_order =
2391             ps_lap_struct->ai4_num_buffer[ps_lap_struct->i4_deq_lap_buf];
2392     }
2393 
2394     ps_lap_struct->i4_lap_out_idx++;
2395     if(ps_lap_struct->i4_lap_out_idx == ps_lap_struct->i4_max_buf_in_enc_order)
2396     {
2397         if(ps_lap_struct->ai4_num_buffer[ps_lap_struct->i4_deq_lap_buf])
2398         {
2399             ps_lap_struct->ai4_num_buffer[ps_lap_struct->i4_deq_lap_buf] = 0;
2400             ps_lap_struct->i4_deq_lap_buf++;
2401             ps_lap_struct->i4_deq_lap_buf &= (MAX_SUBGOP_IN_ENCODE_QUEUE - 1);
2402         }
2403 
2404         ps_lap_struct->i4_lap_out_idx = 0;
2405     }
2406 
2407     return (ps_lap_inp_buf);
2408 }
2409 
2410 /*!
2411 ************************************************************************
2412 * \brief
2413 *    lap get input buffer requirement count
2414 ************************************************************************
2415 */
ihevce_lap_get_num_ip_bufs(ihevce_lap_static_params_t * ps_lap_stat_prms)2416 WORD32 ihevce_lap_get_num_ip_bufs(ihevce_lap_static_params_t *ps_lap_stat_prms)
2417 {
2418     WORD32 i4_lap_window_size = 1;
2419     WORD32 gop_delay = 1 << ps_lap_stat_prms->i4_max_temporal_layers;
2420 
2421     if(ps_lap_stat_prms->s_lap_params.i4_rc_look_ahead_pics != 0)
2422     {
2423         i4_lap_window_size = 1 + ps_lap_stat_prms->s_lap_params.i4_rc_look_ahead_pics;
2424     }
2425 
2426     gop_delay += (i4_lap_window_size);
2427     return gop_delay;
2428 }
2429