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