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