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