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