Home | History | Annotate | Download | only in encoder
      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 */
    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 */
    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 */
    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 */
    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 */
    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