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