• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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