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 ihevce_hle_que_func.c
24 *
25 * \brief
26 * This file contains Que finction of Hehg level encoder
27 *
28 * \date
29 * 18/09/2012
30 *
31 * \author
32 * Ittiam
33 *
34 * List of Functions
35 * <TODO: TO BE ADDED>
36 *
37 ******************************************************************************
38 */
39
40 /*****************************************************************************/
41 /* File Includes */
42 /*****************************************************************************/
43 /* System include files */
44 #include <stdio.h>
45 #include <string.h>
46 #include <stdlib.h>
47 #include <assert.h>
48 #include <stdarg.h>
49 #include <math.h>
50
51 /* User include files */
52 #include "ihevc_typedefs.h"
53 #include "itt_video_api.h"
54 #include "ihevce_api.h"
55
56 #include "rc_cntrl_param.h"
57 #include "rc_frame_info_collector.h"
58 #include "rc_look_ahead_params.h"
59
60 #include "ihevc_defs.h"
61 #include "ihevc_macros.h"
62 #include "ihevc_debug.h"
63 #include "ihevc_structs.h"
64 #include "ihevc_platform_macros.h"
65 #include "ihevc_deblk.h"
66 #include "ihevc_itrans_recon.h"
67 #include "ihevc_chroma_itrans_recon.h"
68 #include "ihevc_chroma_intra_pred.h"
69 #include "ihevc_intra_pred.h"
70 #include "ihevc_inter_pred.h"
71 #include "ihevc_mem_fns.h"
72 #include "ihevc_padding.h"
73 #include "ihevc_weighted_pred.h"
74 #include "ihevc_sao.h"
75 #include "ihevc_resi_trans.h"
76 #include "ihevc_quant_iquant_ssd.h"
77 #include "ihevc_cabac_tables.h"
78 #include "ihevc_trans_tables.h"
79 #include "ihevc_trans_macros.h"
80
81 #include "ihevce_defs.h"
82 #include "ihevce_hle_interface.h"
83 #include "ihevce_hle_q_func.h"
84 #include "ihevce_buffer_que_interface.h"
85 #include "ihevce_lap_enc_structs.h"
86 #include "ihevce_multi_thrd_structs.h"
87 #include "ihevce_multi_thrd_funcs.h"
88 #include "ihevce_me_common_defs.h"
89 #include "ihevce_had_satd.h"
90 #include "ihevce_error_codes.h"
91 #include "ihevce_error_checks.h"
92 #include "ihevce_bitstream.h"
93 #include "ihevce_cabac.h"
94 #include "ihevce_rdoq_macros.h"
95 #include "ihevce_function_selector.h"
96 #include "ihevce_enc_structs.h"
97
98 #include "cast_types.h"
99 #include "osal.h"
100 #include "osal_defaults.h"
101
102 /*****************************************************************************/
103 /* Function Definitions */
104 /*****************************************************************************/
105
106 /*!
107 ******************************************************************************
108 * \if Function name : ihevce_q_get_free_buff \endif
109 *
110 * \brief
111 * Gets a free buffer from the que requested
112 *
113 * \param[in] high level encoder context pointer
114 * \param[in] Que id of the buffer
115 * \param[in] pointer to return the buffer id
116 *
117 * \return
118 * None
119 *
120 * \author
121 * Ittiam
122 *
123 *****************************************************************************
124 */
ihevce_q_get_free_buff(void * pv_enc_ctxt,WORD32 i4_q_id,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)125 void *ihevce_q_get_free_buff(
126 void *pv_enc_ctxt, WORD32 i4_q_id, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
127 {
128 /* local varaibles */
129 WORD32 end_flag = 0;
130 void *pv_buff = NULL;
131 WORD32 i4_mres_single_out;
132 enc_ctxt_t *ps_enc_ctxt = (enc_ctxt_t *)pv_enc_ctxt;
133 i4_mres_single_out = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out;
134
135 while(1 != end_flag)
136 {
137 /* acquire mutex lock */
138 osal_mutex_lock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
139
140 /* call the buffer api function */
141 pv_buff =
142 ihevce_buff_que_get_free_buf(ps_enc_ctxt->s_enc_ques.apv_q_hdl[i4_q_id], pi4_buff_id);
143
144 /* release mutex lock */
145 osal_mutex_unlock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
146
147 /* if no free buffer is available */
148 if(NULL == pv_buff)
149 {
150 /* check if the mode is blocking */
151 if(BUFF_QUE_BLOCKING_MODE == i4_blocking_mode)
152 {
153 /* ------------------------------------------------- */
154 /* Get free buffers are called by producers */
155 /* these producers threads will be put in pend state */
156 /* ------------------------------------------------- */
157
158 /* choose the semaphore based on Que Id */
159 void *pv_sem_handle = NULL;
160
161 /* input data Que : application's input data processing */
162 /* thread is put to pend state */
163 if(IHEVCE_INPUT_DATA_CTRL_Q == i4_q_id)
164 {
165 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle;
166 }
167
168 /* input ctrl Que : application's input ctrl processing */
169 /* thread is put to pend state */
170 if(IHEVCE_INPUT_ASYNCH_CTRL_Q == i4_q_id)
171 {
172 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle;
173 }
174
175 if(IHEVCE_ENC_INPUT_Q == i4_q_id)
176 {
177 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl;
178 }
179
180 /* Output data Que : Output thread is put to pend state */
181 if(IHEVCE_OUTPUT_DATA_Q == i4_q_id)
182 {
183 if(1 == i4_mres_single_out)
184 {
185 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl;
186 }
187 else
188 {
189 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[0];
190 }
191 }
192 /* Recon data Que : Recon thread is put to pend state */
193 if(IHEVCE_RECON_DATA_Q == i4_q_id)
194 {
195 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[0];
196 }
197 /* frm prs ent cod data Que : frame process is put to pend state */
198 if(IHEVCE_FRM_PRS_ENT_COD_Q == i4_q_id)
199 {
200 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle;
201 }
202 /* Pre encode/ encode data Que : pre enocde is put to pend state */
203 if(IHEVCE_PRE_ENC_ME_Q == i4_q_id)
204 {
205 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle;
206 }
207 /* ME/ENC Que : enc frame proc is put to pend state */
208 if(IHEVCE_ME_ENC_RDOPT_Q == i4_q_id)
209 {
210 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle;
211 }
212 if(IHEVCE_L0_IPE_ENC_Q == i4_q_id)
213 {
214 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle;
215 }
216 /* output status queue should be used by both LAP and Frame
217 process in non blocking mode */
218 if(IHEVCE_OUTPUT_STATUS_Q == i4_q_id)
219 {
220 ASSERT(0);
221 }
222
223 /* go the pend state */
224 osal_sem_wait(pv_sem_handle);
225 }
226 /* if non blocking then return NULL and break from loop */
227 else
228 {
229 end_flag = 1;
230 }
231 }
232 /* if valid free buffer is available then break from loop */
233 else
234 {
235 end_flag = 1;
236 }
237 }
238
239 return (pv_buff);
240 }
241
242 /*!
243 ******************************************************************************
244 * \if Function name : ihevce_q_set_buff_prod \endif
245 *
246 * \brief
247 * Sets the buffer as produced in the que requested
248 *
249 * \param[in] high level encoder context pointer
250 * \param[in] Que id of the buffer
251 * \param[in] buffer id which needs to be set as produced
252 *
253 * \return
254 * None
255 *
256 * \author
257 * Ittiam
258 *
259 *****************************************************************************
260 */
ihevce_q_set_buff_prod(void * pv_enc_ctxt,WORD32 i4_q_id,WORD32 i4_buff_id)261 IV_API_CALL_STATUS_T ihevce_q_set_buff_prod(void *pv_enc_ctxt, WORD32 i4_q_id, WORD32 i4_buff_id)
262 {
263 /* local varaibles */
264
265 WORD32 i4_num_users = 0;
266 WORD32 i4_mres_single_out;
267 enc_ctxt_t *ps_enc_ctxt = (enc_ctxt_t *)pv_enc_ctxt;
268 i4_mres_single_out = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out;
269
270 /* acquire mutex lock */
271 osal_mutex_lock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
272
273 /* call the buffer api function */
274 ihevce_buff_que_set_buf_prod(
275 ps_enc_ctxt->s_enc_ques.apv_q_hdl[i4_q_id], i4_buff_id, i4_num_users);
276
277 /* release mutex lock */
278 osal_mutex_unlock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
279
280 /* ------------------------------------------------------------- */
281 /* after setting the buffer the consumers thread needs to be */
282 /* posted in case if that thread is in wait state */
283 /* currently this post is done unconditionally */
284 /* ------------------------------------------------------------- */
285
286 /* input command que : LAP & Frame process threads needs to posted */
287 if(IHEVCE_INPUT_ASYNCH_CTRL_Q == i4_q_id)
288 {
289 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle);
290 }
291
292 /* input data que : LAP thread needs to posted */
293 if(IHEVCE_INPUT_DATA_CTRL_Q == i4_q_id)
294 {
295 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle);
296 }
297
298 /* output stream data que : Entropy processing thread needs to posted */
299 if(IHEVCE_OUTPUT_DATA_Q == i4_q_id)
300 {
301 WORD32 i4_entropy_thrd_id;
302 WORD32 i4_bufque_id;
303
304 i4_bufque_id = (i4_q_id - IHEVCE_OUTPUT_DATA_Q);
305 i4_entropy_thrd_id = i4_bufque_id;
306
307 if(i4_bufque_id == 0)
308 {
309 i4_entropy_thrd_id = ps_enc_ctxt->i4_ref_mbr_id;
310 }
311 else if(i4_bufque_id == ps_enc_ctxt->i4_ref_mbr_id)
312 {
313 i4_entropy_thrd_id = 0;
314 }
315
316 if(IHEVCE_OUTPUT_DATA_Q == i4_q_id)
317 {
318 if(1 == i4_mres_single_out)
319 {
320 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl);
321 }
322 else
323 {
324 osal_sem_post(
325 ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i4_entropy_thrd_id]);
326 }
327 }
328 }
329
330 /* output recon data que : app's output data processing thread needs to posted */
331 if(IHEVCE_RECON_DATA_Q == i4_q_id)
332 {
333 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
334 }
335 /* output control que : app's output processing thread needs to posted */
336 if(IHEVCE_OUTPUT_STATUS_Q == i4_q_id)
337 {
338 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle);
339 }
340
341 /* frm process entropy que : entropy thread needs to posted */
342 if(IHEVCE_FRM_PRS_ENT_COD_Q == i4_q_id)
343 {
344 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[0]);
345 }
346 /* pre-encode/encode que : encode frame proc thread needs to posted */
347 if(IHEVCE_PRE_ENC_ME_Q == i4_q_id)
348 {
349 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
350 }
351 /* ME/ENC Que : enc frame proc needs to be posted */
352 if(IHEVCE_ME_ENC_RDOPT_Q == i4_q_id)
353 {
354 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
355 }
356 if(IHEVCE_L0_IPE_ENC_Q == i4_q_id)
357 {
358 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
359 }
360
361 if(IHEVCE_ENC_INPUT_Q == i4_q_id)
362 {
363 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl);
364 }
365
366 return (IV_SUCCESS);
367 }
368
369 /*!
370 ******************************************************************************
371 * \if Function name : ihevce_q_get_filled_buff \endif
372 *
373 * \brief
374 * Gets a next filled buffer from the que requested
375 *
376 * \param[in] high level encoder context pointer
377 * \param[in] Que id of the buffer
378 * \param[in] pointer to return the buffer id
379 *
380 * \return
381 * None
382 *
383 * \author
384 * Ittiam
385 *
386 *****************************************************************************
387 */
ihevce_q_get_filled_buff(void * pv_enc_ctxt,WORD32 i4_q_id,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)388 void *ihevce_q_get_filled_buff(
389 void *pv_enc_ctxt, WORD32 i4_q_id, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
390 {
391 /* local varaibles */
392 WORD32 end_flag = 0;
393 void *pv_buff = NULL;
394 WORD32 i4_mres_single_out;
395 enc_ctxt_t *ps_enc_ctxt = (enc_ctxt_t *)pv_enc_ctxt;
396 i4_mres_single_out = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out;
397
398 while(1 != end_flag)
399 {
400 /* acquire mutex lock */
401 osal_mutex_lock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
402
403 /* call the buffer api function */
404 pv_buff =
405 ihevce_buff_que_get_next_buf(ps_enc_ctxt->s_enc_ques.apv_q_hdl[i4_q_id], pi4_buff_id);
406
407 /* release mutex lock */
408 osal_mutex_unlock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
409
410 /* if no free buffer is available */
411 if(NULL == pv_buff)
412 {
413 /* check if the mode is blocking */
414 if(BUFF_QUE_BLOCKING_MODE == i4_blocking_mode)
415 {
416 /* ------------------------------------------------- */
417 /* Get filled buffers are called by consumers */
418 /* these consumer threads will be put in pend state */
419 /* ------------------------------------------------- */
420
421 /* choose the semaphore based on Que Id */
422 void *pv_sem_handle = NULL;
423
424 /* input data Que : LAP thread is put to pend state */
425 if(IHEVCE_INPUT_DATA_CTRL_Q == i4_q_id)
426 {
427 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle;
428 }
429
430 /* input ctrl Que : LAP thread is put to pend state */
431 if(IHEVCE_INPUT_ASYNCH_CTRL_Q == i4_q_id)
432 {
433 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle;
434 }
435
436 /* Output Stream data Que : Entropy processing */
437 /* thread is put to pend state */
438 if(IHEVCE_OUTPUT_DATA_Q == i4_q_id)
439 {
440 WORD32 i4_entropy_thrd_id;
441 WORD32 i4_bufque_id;
442
443 i4_bufque_id = (i4_q_id - IHEVCE_OUTPUT_DATA_Q);
444 i4_entropy_thrd_id = i4_bufque_id;
445
446 if(i4_bufque_id == 0)
447 {
448 i4_entropy_thrd_id = ps_enc_ctxt->i4_ref_mbr_id;
449 }
450 else if(i4_bufque_id == ps_enc_ctxt->i4_ref_mbr_id)
451 {
452 i4_entropy_thrd_id = 0;
453 }
454
455 if(IHEVCE_OUTPUT_DATA_Q == i4_q_id)
456 {
457 if(1 == i4_mres_single_out)
458 {
459 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl;
460 }
461 else
462 {
463 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt
464 .apv_ent_cod_sem_handle[i4_entropy_thrd_id];
465 }
466 }
467 }
468
469 /* Output Recon data Que : Frame processing */
470 /* thread is put to pend state */
471 if(IHEVCE_RECON_DATA_Q == i4_q_id)
472 {
473 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle;
474 }
475 /* frm prs ent cod data Que : entropy thread is put to pend state */
476 if(IHEVCE_FRM_PRS_ENT_COD_Q == i4_q_id)
477 {
478 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[0];
479 }
480 /* Output status Que : application's output processing */
481 /* thread is put to pend state */
482 if(IHEVCE_OUTPUT_STATUS_Q == i4_q_id)
483 {
484 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle;
485 }
486
487 /* pre-encode/encode Que : encode frame proc thread */
488 if(IHEVCE_PRE_ENC_ME_Q == i4_q_id)
489 {
490 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle;
491 }
492 /* ME/ENC Que : enc frame proc is put to pend state */
493 if(IHEVCE_ME_ENC_RDOPT_Q == i4_q_id)
494 {
495 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle;
496 }
497 if(IHEVCE_L0_IPE_ENC_Q == i4_q_id)
498 {
499 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle;
500 }
501 /* This call will be made from pre-enc enc thread, hence when input is not available the caller thread should go to pend */
502 if(IHEVCE_ENC_INPUT_Q == i4_q_id)
503 {
504 pv_sem_handle = ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl;
505 }
506
507 /* go the pend state */
508 osal_sem_wait(pv_sem_handle);
509 }
510 /* if non blocking then return NULL and break from loop */
511 else
512 {
513 end_flag = 1;
514 }
515 }
516 /* if valid filled buffer is available then break from loop */
517 else
518 {
519 end_flag = 1;
520 }
521 }
522
523 return (pv_buff);
524 }
525
526 /*!
527 ******************************************************************************
528 * \if Function name : ihevce_q_rel_buf \endif
529 *
530 * \brief
531 * Frees the buffer as in the que requested
532 *
533 * \param[in] high level encoder context pointer
534 * \param[in] Que id of the buffer
535 * \param[in] buffer id which needs to be freed
536 *
537 * \return
538 * None
539 *
540 * \author
541 * Ittiam
542 *
543 *****************************************************************************
544 */
ihevce_q_rel_buf(void * pv_enc_ctxt,WORD32 i4_q_id,WORD32 i4_buff_id)545 IV_API_CALL_STATUS_T ihevce_q_rel_buf(void *pv_enc_ctxt, WORD32 i4_q_id, WORD32 i4_buff_id)
546 {
547 /* local varaibles */
548 WORD32 i4_mres_single_out;
549 enc_ctxt_t *ps_enc_ctxt = (enc_ctxt_t *)pv_enc_ctxt;
550 i4_mres_single_out = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out;
551 /* acquire mutex lock */
552 osal_mutex_lock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
553
554 /* call the buffer api function */
555 ihevce_buff_que_rel_buf(ps_enc_ctxt->s_enc_ques.apv_q_hdl[i4_q_id], i4_buff_id);
556
557 /* release mutex lock */
558 osal_mutex_unlock(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
559
560 /* ------------------------------------------------------------- */
561 /* after releasing the buffer the producer thread needs to be */
562 /* posted in case if that thread is in wait state */
563 /* currently this post is done unconditionally */
564 /* ------------------------------------------------------------- */
565
566 /* input data que : app's input data producing thread needs to posted */
567 if(IHEVCE_INPUT_DATA_CTRL_Q == i4_q_id)
568 {
569 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle);
570 }
571
572 /* input data control que : app's command que producing thread needs to posted */
573 if(IHEVCE_INPUT_ASYNCH_CTRL_Q == i4_q_id)
574 {
575 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle);
576 }
577 /*multiple input queue*/
578 if(IHEVCE_ENC_INPUT_Q == i4_q_id)
579 {
580 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl);
581 }
582
583 /* output data que: Output thread needs to posted */
584 if(IHEVCE_OUTPUT_DATA_Q == i4_q_id)
585 {
586 if(1 == i4_mres_single_out)
587 {
588 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl);
589 }
590 else
591 {
592 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[0]);
593 }
594 }
595 /* Recon data que: Recon thread needs to posted */
596 if(IHEVCE_RECON_DATA_Q == i4_q_id)
597 {
598 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[0]);
599 }
600 /* output status que: LAP & Frame process threads needs to posted */
601 if(IHEVCE_OUTPUT_STATUS_Q == i4_q_id)
602 {
603 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle);
604 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle);
605 }
606
607 /* frm process entropy que : Frame process needs to posted */
608 if(IHEVCE_FRM_PRS_ENT_COD_Q == i4_q_id)
609 {
610 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
611 }
612 /* pre-encode/encode Que : pre-encode frame proc needs to be posted */
613 if(IHEVCE_PRE_ENC_ME_Q == i4_q_id)
614 {
615 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle);
616 }
617 /* ME/ENC Que : enc frame proc needs to be posted */
618 if(IHEVCE_ME_ENC_RDOPT_Q == i4_q_id)
619 {
620 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
621 }
622 if(IHEVCE_L0_IPE_ENC_Q == i4_q_id)
623 {
624 osal_sem_post(ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle);
625 }
626 return (IV_SUCCESS);
627 }
628
629 /*!
630 ******************************************************************************
631 * \if Function name : ihevce_force_end \endif
632 *
633 * \brief
634 * Sets force end flag in enc_ctxt for all resolutions
635 *
636 * \param[in] high level encoder context pointer
637 *
638 * \return
639 * None
640 *
641 * \author
642 * Ittiam
643 *
644 *****************************************************************************
645 */
ihevce_force_end(ihevce_hle_ctxt_t * ps_hle_ctxt)646 void ihevce_force_end(ihevce_hle_ctxt_t *ps_hle_ctxt)
647 {
648 enc_ctxt_t *ps_enc_ctxt;
649 WORD32 i4_resolution_id = 0;
650 WORD32 i4_num_res_layers = 0;
651 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
652
653 i4_num_res_layers = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_num_res_layers;
654 for(i4_resolution_id = 0; i4_resolution_id < i4_num_res_layers; i4_resolution_id++)
655 {
656 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
657 ps_enc_ctxt->s_multi_thrd.i4_force_end_flag = 1;
658 }
659 }
660