Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010-2017, Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of The Linux Foundation nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 /*============================================================================
     29                             O p e n M A X   w r a p p e r s
     30                              O p e n  M A X   C o r e
     31 
     32 *//** @file omx_video_base.cpp
     33   This module contains the implementation of the OpenMAX core & component.
     34 
     35 *//*========================================================================*/
     36 
     37 //////////////////////////////////////////////////////////////////////////////
     38 //                             Include Files
     39 //////////////////////////////////////////////////////////////////////////////
     40 
     41 #define __STDC_FORMAT_MACROS //enables the format specifiers in inttypes.h
     42 #include <inttypes.h>
     43 #include <string.h>
     44 #include "omx_video_base.h"
     45 #include <stdlib.h>
     46 #include <errno.h>
     47 #include <fcntl.h>
     48 #include <unistd.h>
     49 #include <sys/prctl.h>
     50 #include <sys/ioctl.h>
     51 #ifdef _ANDROID_ICS_
     52 #include <media/hardware/HardwareAPI.h>
     53 #include <gralloc_priv.h>
     54 #endif
     55 #ifdef _USE_GLIB_
     56 #include <glib.h>
     57 #define strlcpy g_strlcpy
     58 #endif
     59 #define H264_SUPPORTED_WIDTH (480)
     60 #define H264_SUPPORTED_HEIGHT (368)
     61 
     62 #define MPEG4_SUPPORTED_WIDTH (480)
     63 #define MPEG4_SUPPORTED_HEIGHT (368)
     64 
     65 #define VC1_SP_MP_START_CODE        0xC5000000
     66 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
     67 #define VC1_AP_START_CODE           0x00000100
     68 #define VC1_AP_START_CODE_MASK      0xFFFFFF00
     69 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
     70 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
     71 #define VC1_SIMPLE_PROFILE          0
     72 #define VC1_MAIN_PROFILE            1
     73 #define VC1_ADVANCE_PROFILE         3
     74 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
     75 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
     76 #define VC1_STRUCT_C_LEN            4
     77 #define VC1_STRUCT_C_POS            8
     78 #define VC1_STRUCT_A_POS            12
     79 #define VC1_STRUCT_B_POS            24
     80 #define VC1_SEQ_LAYER_SIZE          36
     81 
     82 #define SZ_4K                       0x1000
     83 #define SZ_1M                       0x100000
     84 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
     85 
     86 #ifndef ION_FLAG_CP_BITSTREAM
     87 #define ION_FLAG_CP_BITSTREAM 0
     88 #endif
     89 
     90 #ifndef ION_FLAG_CP_PIXEL
     91 #define ION_FLAG_CP_PIXEL 0
     92 #endif
     93 
     94 #undef MEM_HEAP_ID
     95 
     96 #ifdef MASTER_SIDE_CP
     97 
     98 #define MEM_HEAP_ID ION_SECURE_HEAP_ID
     99 #define SECURE_ALIGN SZ_4K
    100 #define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL)
    101 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM)
    102 
    103 #else //SLAVE_SIDE_CP
    104 
    105 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
    106 #define SECURE_ALIGN SZ_1M
    107 #define SECURE_FLAGS_INPUT_BUFFER ION_SECURE
    108 #define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE
    109 
    110 #endif
    111 
    112 typedef struct OMXComponentCapabilityFlagsType {
    113     ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
    114     OMX_U32 nSize;
    115     OMX_VERSIONTYPE nVersion;
    116     OMX_BOOL iIsOMXComponentMultiThreaded;
    117     OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
    118     OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
    119     OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
    120     OMX_BOOL iOMXComponentSupportsPartialFrames;
    121     OMX_BOOL iOMXComponentUsesNALStartCodes;
    122     OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
    123     OMX_BOOL iOMXComponentUsesFullAVCFrames;
    124 
    125 } OMXComponentCapabilityFlagsType;
    126 #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347
    127 
    128 void* message_thread_enc(void *input)
    129 {
    130     omx_video* omx = reinterpret_cast<omx_video*>(input);
    131     unsigned char id;
    132     int n;
    133 
    134     fd_set readFds;
    135     int res = 0;
    136     struct timeval tv;
    137 
    138     DEBUG_PRINT_HIGH("omx_venc: message thread start");
    139     prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
    140     while (!omx->msg_thread_stop) {
    141 
    142         tv.tv_sec = 2;
    143         tv.tv_usec = 0;
    144 
    145         FD_ZERO(&readFds);
    146         FD_SET(omx->m_pipe_in, &readFds);
    147 
    148         res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv);
    149         if (res < 0) {
    150             DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno));
    151             continue;
    152         } else if (res == 0 /*timeout*/ || omx->msg_thread_stop) {
    153             continue;
    154         }
    155 
    156         n = read(omx->m_pipe_in, &id, 1);
    157         if (0 == n) {
    158             break;
    159         }
    160 
    161         if (1 == n) {
    162             omx->process_event_cb(omx, id);
    163         }
    164 #ifdef QLE_BUILD
    165         if (n < 0) break;
    166 #else
    167         if ((n < 0) && (errno != EINTR)) {
    168             DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
    169             break;
    170         }
    171 #endif
    172     }
    173     DEBUG_PRINT_HIGH("omx_venc: message thread stop");
    174     return 0;
    175 }
    176 
    177 void post_message(omx_video *omx, unsigned char id)
    178 {
    179     DEBUG_PRINT_LOW("omx_venc: post_message %d", id);
    180     int ret_value;
    181     ret_value = write(omx->m_pipe_out, &id, 1);
    182     if (ret_value <= 0) {
    183         DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno));
    184     } else {
    185         DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
    186     }
    187 }
    188 
    189 // omx_cmd_queue destructor
    190 omx_video::omx_cmd_queue::~omx_cmd_queue()
    191 {
    192     // Nothing to do
    193 }
    194 
    195 // omx cmd queue constructor
    196 omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    197 {
    198     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    199 }
    200 
    201 // omx cmd queue insert
    202 bool omx_video::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
    203 {
    204     bool ret = true;
    205     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
    206         m_q[m_write].id       = id;
    207         m_q[m_write].param1   = p1;
    208         m_q[m_write].param2   = p2;
    209         m_write++;
    210         m_size ++;
    211         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    212             m_write = 0;
    213         }
    214     } else {
    215         ret = false;
    216         DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full");
    217     }
    218     return ret;
    219 }
    220 
    221 // omx cmd queue pop
    222 bool omx_video::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
    223 {
    224     bool ret = true;
    225     if (m_size > 0) {
    226         *id = m_q[m_read].id;
    227         *p1 = m_q[m_read].param1;
    228         *p2 = m_q[m_read].param2;
    229         // Move the read pointer ahead
    230         ++m_read;
    231         --m_size;
    232         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    233             m_read = 0;
    234         }
    235     } else {
    236         ret = false;
    237     }
    238     return ret;
    239 }
    240 
    241 // Retrieve the first mesg type in the queue
    242 unsigned omx_video::omx_cmd_queue::get_q_msg_type()
    243 {
    244     return m_q[m_read].id;
    245 }
    246 
    247 
    248 /* ======================================================================
    249    FUNCTION
    250    omx_venc::omx_venc
    251 
    252    DESCRIPTION
    253    Constructor
    254 
    255    PARAMETERS
    256    None
    257 
    258    RETURN VALUE
    259    None.
    260    ========================================================================== */
    261 omx_video::omx_video():
    262     c2d_opened(false),
    263     psource_frame(NULL),
    264     pdest_frame(NULL),
    265     secure_session(false),
    266     mEmptyEosBuffer(NULL),
    267     m_pipe_in(-1),
    268     m_pipe_out(-1),
    269     m_pInput_pmem(NULL),
    270     m_pOutput_pmem(NULL),
    271 #ifdef USE_ION
    272     m_pInput_ion(NULL),
    273     m_pOutput_ion(NULL),
    274 #endif
    275     m_error_propogated(false),
    276     m_state(OMX_StateInvalid),
    277     m_app_data(NULL),
    278     m_use_input_pmem(OMX_FALSE),
    279     m_use_output_pmem(OMX_FALSE),
    280     m_sExtraData(0),
    281     m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
    282     m_inp_mem_ptr(NULL),
    283     m_out_mem_ptr(NULL),
    284     input_flush_progress (false),
    285     output_flush_progress (false),
    286     input_use_buffer (false),
    287     output_use_buffer (false),
    288     pending_input_buffers(0),
    289     pending_output_buffers(0),
    290     allocate_native_handle(false),
    291     m_out_bm_count(0),
    292     m_inp_bm_count(0),
    293     m_flags(0),
    294     m_etb_count(0),
    295     m_fbd_count(0),
    296     m_event_port_settings_sent(false),
    297     hw_overload(false),
    298     m_graphicbuffer_size(0)
    299 {
    300     DEBUG_PRINT_HIGH("omx_video(): Inside Constructor()");
    301     memset(&m_cmp,0,sizeof(m_cmp));
    302     memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
    303     async_thread_created = false;
    304     msg_thread_created = false;
    305     msg_thread_stop = false;
    306 
    307     OMX_INIT_STRUCT(&m_blurInfo, OMX_QTI_VIDEO_CONFIG_BLURINFO);
    308     m_blurInfo.nPortIndex == (OMX_U32)PORT_INDEX_IN;
    309 
    310     mUsesColorConversion = false;
    311     pthread_mutex_init(&m_lock, NULL);
    312     pthread_mutex_init(&timestamp.m_lock, NULL);
    313     timestamp.is_buffer_pending = false;
    314     sem_init(&m_cmd_lock,0,0);
    315     DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr);
    316 
    317     memset(m_platform, 0, sizeof(m_platform));
    318 #ifdef _ANDROID_
    319     char platform_name[PROPERTY_VALUE_MAX] = {0};
    320     property_get("ro.board.platform", platform_name, "0");
    321     strlcpy(m_platform, platform_name, sizeof(m_platform));
    322 #endif
    323 }
    324 
    325 
    326 /* ======================================================================
    327    FUNCTION
    328    omx_venc::~omx_venc
    329 
    330    DESCRIPTION
    331    Destructor
    332 
    333    PARAMETERS
    334    None
    335 
    336    RETURN VALUE
    337    None.
    338    ========================================================================== */
    339 omx_video::~omx_video()
    340 {
    341     DEBUG_PRINT_HIGH("~omx_video(): Inside Destructor()");
    342     if (msg_thread_created) {
    343         msg_thread_stop = true;
    344         post_message(this, OMX_COMPONENT_CLOSE_MSG);
    345         DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit");
    346         pthread_join(msg_thread_id,NULL);
    347     }
    348     close(m_pipe_in);
    349     close(m_pipe_out);
    350     m_pipe_in = -1;
    351     m_pipe_out = -1;
    352     DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit");
    353     /*For V4L2 based drivers, pthread_join is done in device_close
    354      * so no need to do it here*/
    355 #ifndef _MSM8974_
    356     if (async_thread_created)
    357         pthread_join(async_thread_id,NULL);
    358 #endif
    359     pthread_mutex_destroy(&m_lock);
    360     pthread_mutex_destroy(&timestamp.m_lock);
    361     sem_destroy(&m_cmd_lock);
    362     DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count,
    363             m_fbd_count);
    364     DEBUG_PRINT_HIGH("omx_video: Destructor exit");
    365     DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ...");
    366 }
    367 
    368 /* ======================================================================
    369    FUNCTION
    370    omx_venc::OMXCntrlProcessMsgCb
    371 
    372    DESCRIPTION
    373    IL Client callbacks are generated through this routine. The decoder
    374    provides the thread context for this routine.
    375 
    376    PARAMETERS
    377    ctxt -- Context information related to the self.
    378    id   -- Event identifier. This could be any of the following:
    379    1. Command completion event
    380    2. Buffer done callback event
    381    3. Frame done callback event
    382 
    383    RETURN VALUE
    384    None.
    385 
    386    ========================================================================== */
    387 void omx_video::process_event_cb(void *ctxt, unsigned char id)
    388 {
    389     unsigned long p1; // Parameter - 1
    390     unsigned long p2; // Parameter - 2
    391     unsigned long ident;
    392     unsigned qsize=0; // qsize
    393     omx_video *pThis = (omx_video *) ctxt;
    394 
    395     if (!pThis) {
    396         DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out");
    397         return;
    398     }
    399 
    400     // Protect the shared queue data structure
    401     do {
    402         /*Read the message id's from the queue*/
    403 
    404         pthread_mutex_lock(&pThis->m_lock);
    405         qsize = pThis->m_cmd_q.m_size;
    406         if (qsize) {
    407             pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
    408         }
    409 
    410         if (qsize == 0) {
    411             qsize = pThis->m_ftb_q.m_size;
    412             if (qsize) {
    413                 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
    414             }
    415         }
    416 
    417         if (qsize == 0) {
    418             qsize = pThis->m_etb_q.m_size;
    419             if (qsize) {
    420                 pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
    421             }
    422         }
    423 
    424         pthread_mutex_unlock(&pThis->m_lock);
    425 
    426         /*process message if we have one*/
    427         if (qsize > 0) {
    428             id = ident;
    429             switch (id) {
    430                 case OMX_COMPONENT_GENERATE_EVENT:
    431                     if (pThis->m_pCallbacks.EventHandler) {
    432                         switch (p1) {
    433                             case OMX_CommandStateSet:
    434                                 pThis->m_state = (OMX_STATETYPE) p2;
    435                                 DEBUG_PRINT_LOW("Process -> state set to %d", pThis->m_state);
    436                                 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    437                                         OMX_EventCmdComplete, p1, p2, NULL);
    438                                 break;
    439 
    440                             case OMX_EventError:
    441                                 DEBUG_PRINT_ERROR("ERROR: OMX_EventError: p2 = %lu", p2);
    442                                 if (p2 == (unsigned)OMX_ErrorHardware) {
    443                                     pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    444                                             OMX_EventError,OMX_ErrorHardware,0,NULL);
    445                                 } else {
    446                                     pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    447                                             OMX_EventError, p2, 0, 0);
    448 
    449                                 }
    450                                 break;
    451 
    452                             case OMX_CommandPortDisable:
    453                                 DEBUG_PRINT_LOW("Process -> Port %lu set to PORT_STATE_DISABLED" \
    454                                         "state", p2);
    455                                 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    456                                         OMX_EventCmdComplete, p1, p2, NULL );
    457                                 break;
    458                             case OMX_CommandPortEnable:
    459                                 DEBUG_PRINT_LOW("Process ->Port %lu set PORT_STATE_ENABLED state" \
    460                                         , p2);
    461                                 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
    462                                         OMX_EventCmdComplete, p1, p2, NULL );
    463                                 break;
    464 
    465                             default:
    466                                 DEBUG_PRINT_LOW("process_event_cb forwarding EventCmdComplete %lu", p1);
    467                                 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    468                                         OMX_EventCmdComplete, p1, p2, NULL );
    469                                 break;
    470 
    471                         }
    472                     } else {
    473                         DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks");
    474                     }
    475                     break;
    476                 case OMX_COMPONENT_GENERATE_ETB_OPQ:
    477                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ");
    478                     if (pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
    479                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
    480                         DEBUG_PRINT_ERROR("ERROR: ETBProxy() failed!");
    481                         pThis->omx_report_error ();
    482                     }
    483                     break;
    484                 case OMX_COMPONENT_GENERATE_ETB: {
    485                         OMX_ERRORTYPE iret;
    486                         DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB");
    487                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
    488                         if (iret == OMX_ErrorInsufficientResources) {
    489                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
    490                             pThis->omx_report_hw_overload ();
    491                         } else if (iret != OMX_ErrorNone) {
    492                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
    493                             pThis->omx_report_error ();
    494                         }
    495                     }
    496                     break;
    497 
    498                 case OMX_COMPONENT_GENERATE_FTB:
    499                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    500                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
    501                         DEBUG_PRINT_ERROR("ERROR: FTBProxy() failed!");
    502                         pThis->omx_report_error ();
    503                     }
    504                     break;
    505 
    506                 case OMX_COMPONENT_GENERATE_COMMAND:
    507                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
    508                             (OMX_U32)p2,(OMX_PTR)NULL);
    509                     break;
    510 
    511                 case OMX_COMPONENT_GENERATE_EBD:
    512                     if ( pThis->empty_buffer_done(&pThis->m_cmp,
    513                                 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
    514                         DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
    515                         pThis->omx_report_error ();
    516                     }
    517                     break;
    518 
    519                 case OMX_COMPONENT_GENERATE_FBD:
    520                     if ( pThis->fill_buffer_done(&pThis->m_cmp,
    521                                 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
    522                         DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
    523                         pThis->omx_report_error ();
    524                     }
    525                     break;
    526 
    527                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
    528 
    529                     pThis->input_flush_progress = false;
    530                     DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %" PRIu64, m_etb_count);
    531                     m_etb_count = 0;
    532                     if (pThis->m_pCallbacks.EventHandler) {
    533                         /*Check if we need generate event for Flush done*/
    534                         if (BITMASK_PRESENT(&pThis->m_flags,
    535                                     OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
    536                             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
    537                             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    538                                     OMX_EventCmdComplete,OMX_CommandFlush,
    539                                     PORT_INDEX_IN,NULL );
    540                         } else if (BITMASK_PRESENT(&pThis->m_flags,
    541                                     OMX_COMPONENT_IDLE_PENDING)) {
    542                             if (!pThis->output_flush_progress) {
    543                                 DEBUG_PRINT_LOW("dev_stop called after input flush complete");
    544                                 if (dev_stop() != 0) {
    545                                     DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in i/p flush!");
    546                                     pThis->omx_report_error ();
    547                                 }
    548                             }
    549                         }
    550                     }
    551 
    552                     break;
    553 
    554                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
    555 
    556                     pThis->output_flush_progress = false;
    557                     DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %" PRIu64, m_fbd_count);
    558                     m_fbd_count = 0;
    559                     if (pThis->m_pCallbacks.EventHandler) {
    560                         /*Check if we need generate event for Flush done*/
    561                         if (BITMASK_PRESENT(&pThis->m_flags,
    562                                     OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
    563                             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
    564 
    565                             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    566                                     OMX_EventCmdComplete,OMX_CommandFlush,
    567                                     PORT_INDEX_OUT,NULL );
    568                         } else if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
    569                             DEBUG_PRINT_LOW("dev_stop called after Output flush complete");
    570                             if (!pThis->input_flush_progress) {
    571                                 if (dev_stop() != 0) {
    572                                     DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in o/p flush!");
    573                                     pThis->omx_report_error ();
    574                                 }
    575                             }
    576                         }
    577                     }
    578                     break;
    579 
    580                 case OMX_COMPONENT_GENERATE_START_DONE:
    581                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE msg");
    582 
    583                     if (pThis->m_pCallbacks.EventHandler) {
    584                         DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
    585                         if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
    586                             DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Move to \
    587                                     executing");
    588                             // Send the callback now
    589                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
    590                             pThis->m_state = OMX_StateExecuting;
    591                             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    592                                     OMX_EventCmdComplete,OMX_CommandStateSet,
    593                                     OMX_StateExecuting, NULL);
    594                         } else if (BITMASK_PRESENT(&pThis->m_flags,
    595                                     OMX_COMPONENT_PAUSE_PENDING)) {
    596                             if (dev_pause()) {
    597                                 DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in Start Done!");
    598                                 pThis->omx_report_error ();
    599                             }
    600                         } else if (BITMASK_PRESENT(&pThis->m_flags,
    601                                     OMX_COMPONENT_LOADED_START_PENDING)) {
    602                             if (dev_loaded_start_done()) {
    603                                 DEBUG_PRINT_LOW("successful loaded Start Done!");
    604                             } else {
    605                                 DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
    606                                 pThis->omx_report_error ();
    607                             }
    608                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
    609                         } else {
    610                             DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
    611                         }
    612                     } else {
    613                         DEBUG_PRINT_LOW("Event Handler callback is NULL");
    614                     }
    615                     break;
    616 
    617                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
    618                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
    619                     if (pThis->m_pCallbacks.EventHandler) {
    620                         if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
    621                             //Send the callback now
    622                             pThis->complete_pending_buffer_done_cbs();
    623                             DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD");
    624                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
    625                             pThis->m_state = OMX_StatePause;
    626                             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    627                                     OMX_EventCmdComplete,OMX_CommandStateSet,
    628                                     OMX_StatePause, NULL);
    629                         }
    630                     }
    631 
    632                     break;
    633 
    634                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
    635                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_RESUME_DONE msg");
    636                     if (pThis->m_pCallbacks.EventHandler) {
    637                         if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
    638                             // Send the callback now
    639                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
    640                             pThis->m_state = OMX_StateExecuting;
    641                             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    642                                     OMX_EventCmdComplete,OMX_CommandStateSet,
    643                                     OMX_StateExecuting,NULL);
    644                         }
    645                     }
    646 
    647                     break;
    648 
    649                 case OMX_COMPONENT_GENERATE_STOP_DONE:
    650                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE msg");
    651                     if (pThis->m_pCallbacks.EventHandler) {
    652                         pThis->complete_pending_buffer_done_cbs();
    653                         if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
    654                             // Send the callback now
    655                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
    656                             pThis->m_state = OMX_StateIdle;
    657                             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
    658                                     OMX_EventCmdComplete,OMX_CommandStateSet,
    659                                     OMX_StateIdle,NULL);
    660                         } else if (BITMASK_PRESENT(&pThis->m_flags,
    661                                     OMX_COMPONENT_LOADED_STOP_PENDING)) {
    662                             if (dev_loaded_stop_done()) {
    663                                 DEBUG_PRINT_LOW("successful loaded Stop Done!");
    664                             } else {
    665                                 DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
    666                                 pThis->omx_report_error ();
    667                             }
    668                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
    669                         } else {
    670                             DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
    671                         }
    672                     }
    673 
    674                     break;
    675 
    676                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
    677                     DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!");
    678                     pThis->omx_report_error ();
    679                     break;
    680 #ifndef _MSM8974_
    681                 case OMX_COMPONENT_GENERATE_LTRUSE_FAILED:
    682                     DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_LTRUSE_FAILED!");
    683                     if (pThis->m_pCallbacks.EventHandler) {
    684                         DEBUG_PRINT_ERROR("Sending QOMX_ErrorLTRUseFailed, p2 = 0x%x", p2);
    685                         pThis->m_pCallbacks.EventHandler(
    686                                 &pThis->m_cmp, pThis->m_app_data,
    687                                 OMX_EventError, QOMX_ErrorLTRUseFailed, NULL, NULL);
    688                     }
    689                     break;
    690 #endif
    691                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
    692                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
    693                     pThis->omx_report_unsupported_setting();
    694                     break;
    695 
    696                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
    697                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
    698                     pThis->omx_report_hw_overload();
    699                     break;
    700 
    701                 default:
    702                     DEBUG_PRINT_LOW("process_event_cb unknown msg id 0x%02x", id);
    703                     break;
    704             }
    705         }
    706 
    707         pthread_mutex_lock(&pThis->m_lock);
    708         qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
    709                 pThis->m_etb_q.m_size;
    710 
    711         pthread_mutex_unlock(&pThis->m_lock);
    712 
    713     } while (qsize>0);
    714     DEBUG_PRINT_LOW("exited the while loop");
    715 
    716 }
    717 
    718 
    719 
    720 
    721 /* ======================================================================
    722    FUNCTION
    723    omx_venc::GetComponentVersion
    724 
    725    DESCRIPTION
    726    Returns the component version.
    727 
    728    PARAMETERS
    729    TBD.
    730 
    731    RETURN VALUE
    732    OMX_ErrorNone.
    733 
    734    ========================================================================== */
    735 OMX_ERRORTYPE  omx_video::get_component_version
    736 (
    737  OMX_IN OMX_HANDLETYPE hComp,
    738  OMX_OUT OMX_STRING componentName,
    739  OMX_OUT OMX_VERSIONTYPE* componentVersion,
    740  OMX_OUT OMX_VERSIONTYPE* specVersion,
    741  OMX_OUT OMX_UUIDTYPE* componentUUID
    742  )
    743 {
    744     (void)hComp;
    745     (void)componentName;
    746     (void)componentVersion;
    747     (void)componentUUID;
    748     if (m_state == OMX_StateInvalid) {
    749         DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State");
    750         return OMX_ErrorInvalidState;
    751     }
    752     /* TBD -- Return the proper version */
    753     if (specVersion) {
    754         specVersion->nVersion = OMX_SPEC_VERSION;
    755     }
    756     return OMX_ErrorNone;
    757 }
    758 /* ======================================================================
    759    FUNCTION
    760    omx_venc::SendCommand
    761 
    762    DESCRIPTION
    763    Returns zero if all the buffers released..
    764 
    765    PARAMETERS
    766    None.
    767 
    768    RETURN VALUE
    769    true/false
    770 
    771    ========================================================================== */
    772 OMX_ERRORTYPE  omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
    773         OMX_IN OMX_COMMANDTYPE cmd,
    774         OMX_IN OMX_U32 param1,
    775         OMX_IN OMX_PTR cmdData
    776         )
    777 {
    778     (void)hComp;
    779     if (m_state == OMX_StateInvalid) {
    780         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
    781         return OMX_ErrorInvalidState;
    782     }
    783 
    784     if (cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) {
    785         if ((param1 != (OMX_U32)PORT_INDEX_IN) && (param1 != (OMX_U32)PORT_INDEX_OUT) && (param1 != (OMX_U32)PORT_INDEX_BOTH)) {
    786             DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
    787             return OMX_ErrorBadPortIndex;
    788         }
    789     }
    790     if (cmd == OMX_CommandMarkBuffer) {
    791         if (param1 != PORT_INDEX_IN) {
    792             DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
    793             return OMX_ErrorBadPortIndex;
    794         }
    795         if (!cmdData) {
    796             DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
    797             return OMX_ErrorBadParameter;
    798         }
    799     }
    800 
    801     post_event((unsigned long)cmd,(unsigned long)param1,OMX_COMPONENT_GENERATE_COMMAND);
    802     sem_wait(&m_cmd_lock);
    803     return OMX_ErrorNone;
    804 }
    805 
    806 /* ======================================================================
    807    FUNCTION
    808    omx_venc::SendCommand
    809 
    810    DESCRIPTION
    811    Returns zero if all the buffers released..
    812 
    813    PARAMETERS
    814    None.
    815 
    816    RETURN VALUE
    817    true/false
    818 
    819    ========================================================================== */
    820 OMX_ERRORTYPE  omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
    821         OMX_IN OMX_COMMANDTYPE cmd,
    822         OMX_IN OMX_U32 param1,
    823         OMX_IN OMX_PTR cmdData
    824         )
    825 {
    826     (void)hComp;
    827     (void)cmdData;
    828 
    829     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    830     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
    831     int bFlag = 1;
    832 
    833     if (cmd == OMX_CommandStateSet) {
    834         /***************************/
    835         /* Current State is Loaded */
    836         /***************************/
    837         if (m_state == OMX_StateLoaded) {
    838             if (eState == OMX_StateIdle) {
    839                 //if all buffers are allocated or all ports disabled
    840                 if (allocate_done() ||
    841                         ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) {
    842                     DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle");
    843                 } else {
    844                     DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending");
    845                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
    846                     // Skip the event notification
    847                     bFlag = 0;
    848                 }
    849             }
    850             /* Requesting transition from Loaded to Loaded */
    851             else if (eState == OMX_StateLoaded) {
    852                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded");
    853                 post_event(OMX_EventError,OMX_ErrorSameState,\
    854                         OMX_COMPONENT_GENERATE_EVENT);
    855                 eRet = OMX_ErrorSameState;
    856             }
    857             /* Requesting transition from Loaded to WaitForResources */
    858             else if (eState == OMX_StateWaitForResources) {
    859                 /* Since error is None , we will post an event
    860                    at the end of this function definition */
    861                 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources");
    862             }
    863             /* Requesting transition from Loaded to Executing */
    864             else if (eState == OMX_StateExecuting) {
    865                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing");
    866                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    867                         OMX_COMPONENT_GENERATE_EVENT);
    868                 eRet = OMX_ErrorIncorrectStateTransition;
    869             }
    870             /* Requesting transition from Loaded to Pause */
    871             else if (eState == OMX_StatePause) {
    872                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause");
    873                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    874                         OMX_COMPONENT_GENERATE_EVENT);
    875                 eRet = OMX_ErrorIncorrectStateTransition;
    876             }
    877             /* Requesting transition from Loaded to Invalid */
    878             else if (eState == OMX_StateInvalid) {
    879                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid");
    880                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
    881                 eRet = OMX_ErrorInvalidState;
    882             } else {
    883                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled",\
    884                         eState);
    885                 eRet = OMX_ErrorBadParameter;
    886             }
    887         }
    888 
    889         /***************************/
    890         /* Current State is IDLE */
    891         /***************************/
    892         else if (m_state == OMX_StateIdle) {
    893             if (eState == OMX_StateLoaded) {
    894                 if (release_done()) {
    895                     /*
    896                        Since error is None , we will post an event at the end
    897                        of this function definition
    898                      */
    899                     DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded");
    900                     if (dev_stop() != 0) {
    901                         DEBUG_PRINT_ERROR("ERROR: dev_stop() failed at Idle --> Loaded");
    902                         eRet = OMX_ErrorHardware;
    903                     }
    904                 } else {
    905                     DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending");
    906                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
    907                     // Skip the event notification
    908                     bFlag = 0;
    909                 }
    910             }
    911             /* Requesting transition from Idle to Executing */
    912             else if (eState == OMX_StateExecuting) {
    913                 if ( dev_start() ) {
    914                     DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Exe");
    915                     omx_report_error ();
    916                     eRet = OMX_ErrorHardware;
    917                 } else {
    918                     BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
    919                     DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing");
    920                     bFlag = 0;
    921                 }
    922 
    923                 dev_start_done();
    924             }
    925             /* Requesting transition from Idle to Idle */
    926             else if (eState == OMX_StateIdle) {
    927                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle");
    928                 post_event(OMX_EventError,OMX_ErrorSameState,\
    929                         OMX_COMPONENT_GENERATE_EVENT);
    930                 eRet = OMX_ErrorSameState;
    931             }
    932             /* Requesting transition from Idle to WaitForResources */
    933             else if (eState == OMX_StateWaitForResources) {
    934                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources");
    935                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    936                         OMX_COMPONENT_GENERATE_EVENT);
    937                 eRet = OMX_ErrorIncorrectStateTransition;
    938             }
    939             /* Requesting transition from Idle to Pause */
    940             else if (eState == OMX_StatePause) {
    941                 /*To pause the Video core we need to start the driver*/
    942                 if ( dev_start() ) {
    943                     DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Pause");
    944                     omx_report_error ();
    945                     eRet = OMX_ErrorHardware;
    946                 } else {
    947                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
    948                     DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause");
    949                     bFlag = 0;
    950                 }
    951             }
    952             /* Requesting transition from Idle to Invalid */
    953             else if (eState == OMX_StateInvalid) {
    954                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid");
    955                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
    956                 eRet = OMX_ErrorInvalidState;
    957             } else {
    958                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled",eState);
    959                 eRet = OMX_ErrorBadParameter;
    960             }
    961         }
    962 
    963         /******************************/
    964         /* Current State is Executing */
    965         /******************************/
    966         else if (m_state == OMX_StateExecuting) {
    967             /* Requesting transition from Executing to Idle */
    968             if (eState == OMX_StateIdle) {
    969                 /* Since error is None , we will post an event
    970                    at the end of this function definition
    971                  */
    972                 DEBUG_PRINT_LOW("OMXCORE-SM: Executing --> Idle");
    973                 //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
    974                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
    975                 execute_omx_flush(OMX_ALL);
    976                 bFlag = 0;
    977             }
    978             /* Requesting transition from Executing to Paused */
    979             else if (eState == OMX_StatePause) {
    980 
    981                 if (dev_pause()) {
    982                     DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in SCP on Exe --> Pause");
    983                     post_event(OMX_EventError,OMX_ErrorHardware,\
    984                             OMX_COMPONENT_GENERATE_EVENT);
    985                     eRet = OMX_ErrorHardware;
    986                 } else {
    987                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
    988                     DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause");
    989                     bFlag = 0;
    990                 }
    991             }
    992             /* Requesting transition from Executing to Loaded */
    993             else if (eState == OMX_StateLoaded) {
    994                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Loaded");
    995                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    996                         OMX_COMPONENT_GENERATE_EVENT);
    997                 eRet = OMX_ErrorIncorrectStateTransition;
    998             }
    999             /* Requesting transition from Executing to WaitForResources */
   1000             else if (eState == OMX_StateWaitForResources) {
   1001                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> WaitForResources");
   1002                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1003                         OMX_COMPONENT_GENERATE_EVENT);
   1004                 eRet = OMX_ErrorIncorrectStateTransition;
   1005             }
   1006             /* Requesting transition from Executing to Executing */
   1007             else if (eState == OMX_StateExecuting) {
   1008                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Executing");
   1009                 post_event(OMX_EventError,OMX_ErrorSameState,\
   1010                         OMX_COMPONENT_GENERATE_EVENT);
   1011                 eRet = OMX_ErrorSameState;
   1012             }
   1013             /* Requesting transition from Executing to Invalid */
   1014             else if (eState == OMX_StateInvalid) {
   1015                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Invalid");
   1016                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1017                 eRet = OMX_ErrorInvalidState;
   1018             } else {
   1019                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled",eState);
   1020                 eRet = OMX_ErrorBadParameter;
   1021             }
   1022         }
   1023         /***************************/
   1024         /* Current State is Pause  */
   1025         /***************************/
   1026         else if (m_state == OMX_StatePause) {
   1027             /* Requesting transition from Pause to Executing */
   1028             if (eState == OMX_StateExecuting) {
   1029                 DEBUG_PRINT_LOW("Pause --> Executing");
   1030                 if ( dev_resume() ) {
   1031                     post_event(OMX_EventError,OMX_ErrorHardware,\
   1032                             OMX_COMPONENT_GENERATE_EVENT);
   1033                     eRet = OMX_ErrorHardware;
   1034                 } else {
   1035                     BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
   1036                     DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing");
   1037                     post_event (0, 0, OMX_COMPONENT_GENERATE_RESUME_DONE);
   1038                     bFlag = 0;
   1039                 }
   1040             }
   1041             /* Requesting transition from Pause to Idle */
   1042             else if (eState == OMX_StateIdle) {
   1043                 /* Since error is None , we will post an event
   1044                    at the end of this function definition */
   1045                 DEBUG_PRINT_LOW("Pause --> Idle");
   1046                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   1047                 execute_omx_flush(OMX_ALL);
   1048                 bFlag = 0;
   1049             }
   1050             /* Requesting transition from Pause to loaded */
   1051             else if (eState == OMX_StateLoaded) {
   1052                 DEBUG_PRINT_ERROR("ERROR: Pause --> loaded");
   1053                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1054                         OMX_COMPONENT_GENERATE_EVENT);
   1055                 eRet = OMX_ErrorIncorrectStateTransition;
   1056             }
   1057             /* Requesting transition from Pause to WaitForResources */
   1058             else if (eState == OMX_StateWaitForResources) {
   1059                 DEBUG_PRINT_ERROR("ERROR: Pause --> WaitForResources");
   1060                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1061                         OMX_COMPONENT_GENERATE_EVENT);
   1062                 eRet = OMX_ErrorIncorrectStateTransition;
   1063             }
   1064             /* Requesting transition from Pause to Pause */
   1065             else if (eState == OMX_StatePause) {
   1066                 DEBUG_PRINT_ERROR("ERROR: Pause --> Pause");
   1067                 post_event(OMX_EventError,OMX_ErrorSameState,\
   1068                         OMX_COMPONENT_GENERATE_EVENT);
   1069                 eRet = OMX_ErrorSameState;
   1070             }
   1071             /* Requesting transition from Pause to Invalid */
   1072             else if (eState == OMX_StateInvalid) {
   1073                 DEBUG_PRINT_ERROR("ERROR: Pause --> Invalid");
   1074                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1075                 eRet = OMX_ErrorInvalidState;
   1076             } else {
   1077                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled",eState);
   1078                 eRet = OMX_ErrorBadParameter;
   1079             }
   1080         }
   1081         /***************************/
   1082         /* Current State is WaitForResources  */
   1083         /***************************/
   1084         else if (m_state == OMX_StateWaitForResources) {
   1085             /* Requesting transition from WaitForResources to Loaded */
   1086             if (eState == OMX_StateLoaded) {
   1087                 /* Since error is None , we will post an event
   1088                    at the end of this function definition */
   1089                 DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded");
   1090             }
   1091             /* Requesting transition from WaitForResources to WaitForResources */
   1092             else if (eState == OMX_StateWaitForResources) {
   1093                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources");
   1094                 post_event(OMX_EventError,OMX_ErrorSameState,
   1095                         OMX_COMPONENT_GENERATE_EVENT);
   1096                 eRet = OMX_ErrorSameState;
   1097             }
   1098             /* Requesting transition from WaitForResources to Executing */
   1099             else if (eState == OMX_StateExecuting) {
   1100                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing");
   1101                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1102                         OMX_COMPONENT_GENERATE_EVENT);
   1103                 eRet = OMX_ErrorIncorrectStateTransition;
   1104             }
   1105             /* Requesting transition from WaitForResources to Pause */
   1106             else if (eState == OMX_StatePause) {
   1107                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause");
   1108                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1109                         OMX_COMPONENT_GENERATE_EVENT);
   1110                 eRet = OMX_ErrorIncorrectStateTransition;
   1111             }
   1112             /* Requesting transition from WaitForResources to Invalid */
   1113             else if (eState == OMX_StateInvalid) {
   1114                 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid");
   1115                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1116                 eRet = OMX_ErrorInvalidState;
   1117             }
   1118             /* Requesting transition from WaitForResources to Loaded -
   1119                is NOT tested by Khronos TS */
   1120 
   1121         } else {
   1122             DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)",m_state,eState);
   1123             eRet = OMX_ErrorBadParameter;
   1124         }
   1125     }
   1126     /********************************/
   1127     /* Current State is Invalid */
   1128     /*******************************/
   1129     else if (m_state == OMX_StateInvalid) {
   1130         /* State Transition from Inavlid to any state */
   1131         if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
   1132                     || OMX_StateIdle || OMX_StateExecuting
   1133                     || OMX_StatePause || OMX_StateInvalid)) {
   1134             DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded");
   1135             post_event(OMX_EventError,OMX_ErrorInvalidState,\
   1136                     OMX_COMPONENT_GENERATE_EVENT);
   1137             eRet = OMX_ErrorInvalidState;
   1138         }
   1139     } else if (cmd == OMX_CommandFlush) {
   1140         if (0 == param1 || OMX_ALL == param1) {
   1141             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   1142         }
   1143         if (1 == param1 || OMX_ALL == param1) {
   1144             //generate output flush event only.
   1145             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1146         }
   1147 
   1148         execute_omx_flush(param1);
   1149         bFlag = 0;
   1150     } else if ( cmd == OMX_CommandPortEnable) {
   1151         if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) {
   1152             m_sInPortDef.bEnabled = OMX_TRUE;
   1153 
   1154             if ( (m_state == OMX_StateLoaded &&
   1155                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   1156                     || allocate_input_done()) {
   1157                 post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
   1158                         OMX_COMPONENT_GENERATE_EVENT);
   1159             } else {
   1160                 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending");
   1161                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   1162                 // Skip the event notification
   1163                 bFlag = 0;
   1164             }
   1165         }
   1166         if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) {
   1167             m_sOutPortDef.bEnabled = OMX_TRUE;
   1168 
   1169             if ( (m_state == OMX_StateLoaded &&
   1170                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   1171                     || (allocate_output_done())) {
   1172                 post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
   1173                         OMX_COMPONENT_GENERATE_EVENT);
   1174 
   1175             } else {
   1176                 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending");
   1177                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   1178                 // Skip the event notification
   1179                 bFlag = 0;
   1180             }
   1181         }
   1182     } else if (cmd == OMX_CommandPortDisable) {
   1183         if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) {
   1184             m_sInPortDef.bEnabled = OMX_FALSE;
   1185             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   1186                     && release_input_done()) {
   1187                 post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
   1188                         OMX_COMPONENT_GENERATE_EVENT);
   1189             } else {
   1190                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   1191                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   1192                     execute_omx_flush(PORT_INDEX_IN);
   1193                 }
   1194 
   1195                 // Skip the event notification
   1196                 bFlag = 0;
   1197             }
   1198         }
   1199         if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) {
   1200             m_sOutPortDef.bEnabled = OMX_FALSE;
   1201 
   1202             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   1203                     && release_output_done()) {
   1204                 post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
   1205                         OMX_COMPONENT_GENERATE_EVENT);
   1206             } else {
   1207                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1208                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   1209                     execute_omx_flush(PORT_INDEX_OUT);
   1210                 }
   1211                 // Skip the event notification
   1212                 bFlag = 0;
   1213 
   1214             }
   1215         }
   1216     } else {
   1217         DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)",cmd);
   1218         eRet = OMX_ErrorNotImplemented;
   1219     }
   1220     if (eRet == OMX_ErrorNone && bFlag) {
   1221         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   1222     }
   1223     sem_post(&m_cmd_lock);
   1224     return eRet;
   1225 }
   1226 
   1227 /* ======================================================================
   1228    FUNCTION
   1229    omx_venc::ExecuteOmxFlush
   1230 
   1231    DESCRIPTION
   1232    Executes the OMX flush.
   1233 
   1234    PARAMETERS
   1235    flushtype - input flush(1)/output flush(0)/ both.
   1236 
   1237    RETURN VALUE
   1238    true/false
   1239 
   1240    ========================================================================== */
   1241 bool omx_video::execute_omx_flush(OMX_U32 flushType)
   1242 {
   1243     bool bRet = false;
   1244     DEBUG_PRINT_LOW("execute_omx_flush -  %u", (unsigned int)flushType);
   1245 #ifdef _MSM8974_
   1246     /* XXX: The driver/hardware does not support flushing of individual ports
   1247      * in all states. So we pretty much need to flush both ports internally,
   1248      * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
   1249      * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
   1250      * we automatically omit sending the FLUSH done for the "opposite" port. */
   1251 
   1252     input_flush_progress = true;
   1253     output_flush_progress = true;
   1254     bRet = execute_flush_all();
   1255 #else
   1256     if (flushType == 0 || flushType == OMX_ALL) {
   1257         input_flush_progress = true;
   1258         //flush input only
   1259         bRet = execute_input_flush();
   1260     }
   1261     if (flushType == 1 || flushType == OMX_ALL) {
   1262         //flush output only
   1263         output_flush_progress = true;
   1264         bRet = execute_output_flush();
   1265     }
   1266 #endif
   1267     return bRet;
   1268 }
   1269 /*=========================================================================
   1270 FUNCTION : execute_output_flush
   1271 
   1272 DESCRIPTION
   1273 Executes the OMX flush at OUTPUT PORT.
   1274 
   1275 PARAMETERS
   1276 None.
   1277 
   1278 RETURN VALUE
   1279 true/false
   1280 ==========================================================================*/
   1281 bool omx_video::execute_output_flush(void)
   1282 {
   1283     unsigned long p1 = 0; // Parameter - 1
   1284     unsigned long p2 = 0; // Parameter - 2
   1285     unsigned long ident = 0;
   1286     bool bRet = true;
   1287 
   1288     /*Generate FBD for all Buffers in the FTBq*/
   1289     DEBUG_PRINT_LOW("execute_output_flush");
   1290     pthread_mutex_lock(&m_lock);
   1291     while (m_ftb_q.m_size) {
   1292         m_ftb_q.pop_entry(&p1,&p2,&ident);
   1293 
   1294         if (ident == OMX_COMPONENT_GENERATE_FTB ) {
   1295             pending_output_buffers++;
   1296             VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   1297             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1298         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   1299             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1300         }
   1301     }
   1302 
   1303     pthread_mutex_unlock(&m_lock);
   1304     /*Check if there are buffers with the Driver*/
   1305     if (dev_flush(PORT_INDEX_OUT)) {
   1306         DEBUG_PRINT_ERROR("ERROR: o/p dev_flush() Failed");
   1307         return false;
   1308     }
   1309 
   1310     return bRet;
   1311 }
   1312 /*=========================================================================
   1313 FUNCTION : execute_input_flush
   1314 
   1315 DESCRIPTION
   1316 Executes the OMX flush at INPUT PORT.
   1317 
   1318 PARAMETERS
   1319 None.
   1320 
   1321 RETURN VALUE
   1322 true/false
   1323 ==========================================================================*/
   1324 bool omx_video::execute_input_flush(void)
   1325 {
   1326     unsigned long p1 = 0; // Parameter - 1
   1327     unsigned long p2 = 0; // Parameter - 2
   1328     unsigned long ident = 0;
   1329     bool bRet = true;
   1330 
   1331     /*Generate EBD for all Buffers in the ETBq*/
   1332     DEBUG_PRINT_LOW("execute_input_flush");
   1333 
   1334     pthread_mutex_lock(&m_lock);
   1335     while (m_etb_q.m_size) {
   1336         m_etb_q.pop_entry(&p1,&p2,&ident);
   1337         if (ident == OMX_COMPONENT_GENERATE_ETB) {
   1338             pending_input_buffers++;
   1339             VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   1340             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1341         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   1342             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1343         } else if (ident == OMX_COMPONENT_GENERATE_ETB_OPQ) {
   1344             m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
   1345         }
   1346     }
   1347     if (mUseProxyColorFormat) {
   1348         if (psource_frame) {
   1349             m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
   1350             psource_frame = NULL;
   1351         }
   1352         while (m_opq_meta_q.m_size) {
   1353             unsigned long p1,p2,id;
   1354             m_opq_meta_q.pop_entry(&p1,&p2,&id);
   1355             m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
   1356                     (OMX_BUFFERHEADERTYPE  *)p1);
   1357         }
   1358         if (pdest_frame) {
   1359             m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0);
   1360             pdest_frame = NULL;
   1361         }
   1362     }
   1363     pthread_mutex_unlock(&m_lock);
   1364     /*Check if there are buffers with the Driver*/
   1365     if (dev_flush(PORT_INDEX_IN)) {
   1366         DEBUG_PRINT_ERROR("ERROR: i/p dev_flush() Failed");
   1367         return false;
   1368     }
   1369 
   1370     return bRet;
   1371 }
   1372 
   1373 
   1374 /*=========================================================================
   1375 FUNCTION : execute_flush
   1376 
   1377 DESCRIPTION
   1378 Executes the OMX flush at INPUT & OUTPUT PORT.
   1379 
   1380 PARAMETERS
   1381 None.
   1382 
   1383 RETURN VALUE
   1384 true/false
   1385 ==========================================================================*/
   1386 #ifdef _MSM8974_
   1387 bool omx_video::execute_flush_all(void)
   1388 {
   1389     unsigned long p1 = 0; // Parameter - 1
   1390     unsigned long p2 = 0; // Parameter - 2
   1391     unsigned long ident = 0;
   1392     bool bRet = true;
   1393 
   1394     DEBUG_PRINT_LOW("execute_flush_all");
   1395 
   1396     /*Generate EBD for all Buffers in the ETBq*/
   1397     pthread_mutex_lock(&m_lock);
   1398     while (m_etb_q.m_size) {
   1399         m_etb_q.pop_entry(&p1,&p2,&ident);
   1400         if (ident == OMX_COMPONENT_GENERATE_ETB) {
   1401             pending_input_buffers++;
   1402             VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   1403             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1404         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   1405             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1406         } else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) {
   1407             m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
   1408         }
   1409     }
   1410     if(mUseProxyColorFormat) {
   1411         if(psource_frame) {
   1412             m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
   1413             psource_frame = NULL;
   1414         }
   1415         while(m_opq_meta_q.m_size) {
   1416             unsigned long p1,p2,id;
   1417             m_opq_meta_q.pop_entry(&p1,&p2,&id);
   1418             m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
   1419                 (OMX_BUFFERHEADERTYPE  *)p1);
   1420         }
   1421         if(pdest_frame){
   1422             m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0);
   1423             pdest_frame = NULL;
   1424         }
   1425     }
   1426 
   1427     /*Generate FBD for all Buffers in the FTBq*/
   1428     DEBUG_PRINT_LOW("execute_output_flush");
   1429     while (m_ftb_q.m_size) {
   1430         m_ftb_q.pop_entry(&p1,&p2,&ident);
   1431 
   1432         if (ident == OMX_COMPONENT_GENERATE_FTB ) {
   1433             pending_output_buffers++;
   1434             VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   1435             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1436         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   1437             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1438         }
   1439     }
   1440 
   1441     pthread_mutex_unlock(&m_lock);
   1442 
   1443     /*Check if there are buffers with the Driver*/
   1444     if (dev_flush(PORT_INDEX_BOTH)) {
   1445         DEBUG_PRINT_ERROR("ERROR: dev_flush() Failed");
   1446         return false;
   1447     }
   1448     return bRet;
   1449 }
   1450 
   1451 #endif
   1452 
   1453 /* ======================================================================
   1454    FUNCTION
   1455    omx_venc::SendCommandEvent
   1456 
   1457    DESCRIPTION
   1458    Send the event to decoder pipe.  This is needed to generate the callbacks
   1459    in decoder thread context.
   1460 
   1461    PARAMETERS
   1462    None.
   1463 
   1464    RETURN VALUE
   1465    true/false
   1466 
   1467    ========================================================================== */
   1468 bool omx_video::post_event(unsigned long p1,
   1469         unsigned long p2,
   1470         unsigned long id)
   1471 {
   1472     bool bRet =  false;
   1473 
   1474     pthread_mutex_lock(&m_lock);
   1475 
   1476     if ((id == OMX_COMPONENT_GENERATE_FTB) ||
   1477             (id == OMX_COMPONENT_GENERATE_FBD) ||
   1478             (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH)) {
   1479         m_ftb_q.insert_entry(p1,p2,id);
   1480     } else if ((id == OMX_COMPONENT_GENERATE_ETB) ||
   1481             (id == OMX_COMPONENT_GENERATE_EBD) ||
   1482             (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH)) {
   1483         m_etb_q.insert_entry(p1,p2,id);
   1484     } else {
   1485         m_cmd_q.insert_entry(p1,p2,id);
   1486     }
   1487 
   1488     bRet = true;
   1489     DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
   1490     post_message(this, id);
   1491     pthread_mutex_unlock(&m_lock);
   1492 
   1493     return bRet;
   1494 }
   1495 
   1496 /* ======================================================================
   1497    FUNCTION
   1498    omx_venc::GetParameter
   1499 
   1500    DESCRIPTION
   1501    OMX Get Parameter method implementation
   1502 
   1503    PARAMETERS
   1504    <TBD>.
   1505 
   1506    RETURN VALUE
   1507    Error None if successful.
   1508 
   1509    ========================================================================== */
   1510 OMX_ERRORTYPE  omx_video::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   1511         OMX_IN OMX_INDEXTYPE paramIndex,
   1512         OMX_INOUT OMX_PTR     paramData)
   1513 {
   1514     (void)hComp;
   1515     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1516     unsigned int height=0,width = 0;
   1517 
   1518     DEBUG_PRINT_LOW("get_parameter:");
   1519     if (m_state == OMX_StateInvalid) {
   1520         DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State");
   1521         return OMX_ErrorInvalidState;
   1522     }
   1523     if (paramData == NULL) {
   1524         DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
   1525         return OMX_ErrorBadParameter;
   1526     }
   1527     switch ((int)paramIndex) {
   1528         case OMX_IndexParamPortDefinition:
   1529             {
   1530                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   1531                 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   1532                 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   1533 
   1534                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
   1535                 if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
   1536                     dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
   1537                         &m_sInPortDef.nBufferCountActual,
   1538                         &m_sInPortDef.nBufferSize,
   1539                         m_sInPortDef.nPortIndex);
   1540                     DEBUG_PRINT_LOW("m_sInPortDef: size = %u, min cnt = %u, actual cnt = %u",
   1541                             (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountMin,
   1542                             (unsigned int)m_sInPortDef.nBufferCountActual);
   1543                     memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
   1544 #ifdef _ANDROID_ICS_
   1545                     if (meta_mode_enable) {
   1546                         // request size of largest metadata (happens to be NativeHandleSource) since
   1547                         // we do not know the exact metadata-type yet
   1548                         portDefn->nBufferSize = sizeof(LEGACY_CAM_METADATA_TYPE);
   1549                     }
   1550                     if (mUseProxyColorFormat) {
   1551                         portDefn->format.video.eColorFormat =
   1552                             (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
   1553                     }
   1554 #endif
   1555                 } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1556                     if (m_state != OMX_StateExecuting) {
   1557                         dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
   1558                             &m_sOutPortDef.nBufferCountActual,
   1559                             &m_sOutPortDef.nBufferSize,
   1560                             m_sOutPortDef.nPortIndex);
   1561                     }
   1562                     DEBUG_PRINT_LOW("m_sOutPortDef: size = %u, min cnt = %u, actual cnt = %u",
   1563                             (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountMin,
   1564                             (unsigned int)m_sOutPortDef.nBufferCountActual);
   1565                     memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
   1566 
   1567                     if (secure_session || allocate_native_handle) {
   1568                         portDefn->nBufferSize =
   1569                                 sizeof(native_handle_t) + (sizeof(int) * (1/*numFds*/ + 3/*numInts*/));
   1570                     }
   1571                 } else {
   1572                     DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1573                     eRet = OMX_ErrorBadPortIndex;
   1574                 }
   1575                 break;
   1576             }
   1577         case OMX_IndexParamVideoInit:
   1578             {
   1579                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   1580                 OMX_PORT_PARAM_TYPE *portParamType =
   1581                     (OMX_PORT_PARAM_TYPE *) paramData;
   1582                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
   1583 
   1584                 memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
   1585                 break;
   1586             }
   1587         case OMX_IndexParamVideoPortFormat:
   1588             {
   1589                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   1590                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   1591                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   1592                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
   1593 
   1594                 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
   1595                     unsigned index = portFmt->nIndex;
   1596 
   1597 #ifdef _UBWC_
   1598                     //we support following formats
   1599                     //index 0 - Compressed (UBWC) Venus flavour of YUV420SP
   1600                     //index 1 - Venus flavour of YUV420SP
   1601                     //index 2 - Compressed (UBWC) Venus flavour of RGBA8888
   1602                     //index 3 - Venus flavour of RGBA8888
   1603                     //index 4 - opaque which internally maps to YUV420SP.
   1604                     //index 5 - vannilla YUV420SP
   1605                     //this can be extended in the future
   1606                     int supportedFormats[] = {
   1607                         [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed,
   1608                         [1] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
   1609                         [2] = QOMX_COLOR_Format32bitRGBA8888Compressed,
   1610                         [3] = QOMX_COLOR_Format32bitRGBA8888,
   1611                         [4] = QOMX_COLOR_FormatAndroidOpaque,
   1612                         [5] = OMX_COLOR_FormatYUV420SemiPlanar,
   1613                     };
   1614 #else
   1615                     //we support two formats
   1616                     //index 0 - Venus flavour of YUV420SP
   1617                     //index 1 - opaque which internally maps to YUV420SP.
   1618                     //index 2 - vannilla YUV420SP
   1619                     //this can be extended in the future
   1620                     int supportedFormats[] = {
   1621                         [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
   1622                         [1] = QOMX_COLOR_FormatAndroidOpaque,
   1623                         [2] = OMX_COLOR_FormatYUV420SemiPlanar,
   1624                     };
   1625 #endif
   1626                     if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1))
   1627                         eRet = OMX_ErrorNoMore;
   1628                     else {
   1629                         memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
   1630                         portFmt->nIndex = index; //restore index set from client
   1631                         portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)supportedFormats[index];
   1632                     }
   1633                 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1634                     memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
   1635                 } else {
   1636                     DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1637                     eRet = OMX_ErrorBadPortIndex;
   1638                 }
   1639                 break;
   1640             }
   1641         case OMX_IndexParamVideoBitrate:
   1642             {
   1643                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_BITRATETYPE);
   1644                 OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
   1645                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate");
   1646 
   1647                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1648                     memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
   1649                 } else {
   1650                     DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1651                     eRet = OMX_ErrorBadPortIndex;
   1652                 }
   1653 
   1654                 break;
   1655             }
   1656         case OMX_IndexParamVideoMpeg4:
   1657             {
   1658                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_MPEG4TYPE);
   1659                 OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
   1660                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4");
   1661                 memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
   1662                 break;
   1663             }
   1664         case OMX_IndexParamVideoH263:
   1665             {
   1666                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_H263TYPE);
   1667                 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
   1668                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263");
   1669                 memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
   1670                 break;
   1671             }
   1672         case OMX_IndexParamVideoAvc:
   1673             {
   1674                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_AVCTYPE);
   1675                 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
   1676                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc");
   1677                 memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
   1678                 break;
   1679             }
   1680         case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
   1681             {
   1682                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_VP8TYPE);
   1683                 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
   1684                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoVp8");
   1685                 memcpy(pParam, &m_sParamVP8, sizeof(m_sParamVP8));
   1686                 break;
   1687             }
   1688         case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
   1689             {
   1690                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_HEVCTYPE);
   1691                 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
   1692                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoHevc");
   1693                 memcpy(pParam, &m_sParamHEVC, sizeof(m_sParamHEVC));
   1694                 break;
   1695             }
   1696         case OMX_IndexParamVideoProfileLevelQuerySupported:
   1697             {
   1698                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   1699                 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   1700                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported");
   1701                 eRet = get_supported_profile_level(pParam);
   1702                 if (eRet && eRet != OMX_ErrorNoMore)
   1703                     DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %u, %u",
   1704                             (unsigned int)pParam->eProfile, (unsigned int)pParam->eLevel);
   1705                 break;
   1706             }
   1707         case OMX_IndexParamVideoProfileLevelCurrent:
   1708             {
   1709                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   1710                 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   1711                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent");
   1712                 memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
   1713                 break;
   1714             }
   1715         case OMX_QcomIndexConfigH264EntropyCodingCabac:
   1716             {
   1717                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
   1718                 QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam = (QOMX_VIDEO_H264ENTROPYCODINGTYPE*)paramData;
   1719                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexConfigH264EntropyCodingCabac");
   1720                 memcpy(pParam, &m_sParamEntropy, sizeof(m_sParamEntropy));
   1721                 break;
   1722             }
   1723             /*Component should support this port definition*/
   1724         case OMX_IndexParamAudioInit:
   1725             {
   1726                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   1727                 OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
   1728                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
   1729                 memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
   1730                 break;
   1731             }
   1732             /*Component should support this port definition*/
   1733         case OMX_IndexParamImageInit:
   1734             {
   1735                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   1736                 OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
   1737                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
   1738                 memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
   1739                 break;
   1740 
   1741             }
   1742             /*Component should support this port definition*/
   1743         case OMX_IndexParamOtherInit:
   1744             {
   1745                 DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x", paramIndex);
   1746                 eRet =OMX_ErrorUnsupportedIndex;
   1747                 break;
   1748             }
   1749         case OMX_IndexParamStandardComponentRole:
   1750             {
   1751                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   1752                 OMX_PARAM_COMPONENTROLETYPE *comp_role;
   1753                 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   1754                 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   1755                 comp_role->nSize = sizeof(*comp_role);
   1756 
   1757                 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",paramIndex);
   1758                 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
   1759                 break;
   1760             }
   1761             /* Added for parameter test */
   1762         case OMX_IndexParamPriorityMgmt:
   1763             {
   1764                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   1765                 OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
   1766                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
   1767                 memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
   1768                 break;
   1769             }
   1770             /* Added for parameter test */
   1771         case OMX_IndexParamCompBufferSupplier:
   1772             {
   1773                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   1774                 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   1775                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
   1776                 if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) {
   1777                     memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier));
   1778                 } else if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) {
   1779                     memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier));
   1780                 } else {
   1781                     DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1782                     eRet = OMX_ErrorBadPortIndex;
   1783                 }
   1784                 break;
   1785             }
   1786 
   1787         case OMX_IndexParamVideoQuantization:
   1788             {
   1789                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
   1790                 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
   1791                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization");
   1792                 memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
   1793                 break;
   1794             }
   1795 
   1796         case OMX_QcomIndexParamVideoQPRange:
   1797             {
   1798                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE);
   1799                 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData;
   1800                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange");
   1801                 memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange));
   1802                 break;
   1803             }
   1804 
   1805         case OMX_QcomIndexParamVideoIPBQPRange:
   1806             {
   1807                 OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData;
   1808                 DEBUG_PRINT_LOW("get_parameter: OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE");
   1809                 memcpy(qp_range, &m_sSessionIPBQPRange, sizeof(m_sSessionIPBQPRange));
   1810                 break;
   1811             }
   1812 
   1813         case OMX_IndexParamVideoErrorCorrection:
   1814             {
   1815                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
   1816                 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
   1817                 DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
   1818                 errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
   1819                 errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
   1820                 errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
   1821                 break;
   1822             }
   1823         case OMX_IndexParamVideoIntraRefresh:
   1824             {
   1825                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
   1826                 OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
   1827                 DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh");
   1828                 intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
   1829                 intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
   1830                 break;
   1831             }
   1832         case OMX_QcomIndexPortDefn:
   1833             //TODO
   1834             break;
   1835         case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
   1836             {
   1837                 VALIDATE_OMX_PARAM_DATA(paramData, OMXComponentCapabilityFlagsType);
   1838                 OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
   1839                 DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX");
   1840                 pParam->iIsOMXComponentMultiThreaded = OMX_TRUE;
   1841                 pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE;
   1842                 pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
   1843                 pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
   1844                 pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE;
   1845                 pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE;
   1846                 pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE;
   1847                 pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
   1848                 m_use_input_pmem = OMX_TRUE;
   1849                 DEBUG_PRINT_LOW("Supporting capability index in encoder node");
   1850                 break;
   1851             }
   1852 #if !defined(MAX_RES_720P) || defined(_MSM8974_)
   1853         case OMX_QcomIndexParamIndexExtraDataType:
   1854             {
   1855                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
   1856                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType");
   1857                 QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
   1858                 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) {
   1859                     if (pParam->nPortIndex == PORT_INDEX_OUT) {
   1860                         pParam->bEnabled =
   1861                             (OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_SLICEINFO);
   1862                         DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled);
   1863                     } else {
   1864                         DEBUG_PRINT_ERROR("get_parameter: slice information is "
   1865                                 "valid for output port only");
   1866                         eRet = OMX_ErrorUnsupportedIndex;
   1867                     }
   1868                 } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo) {
   1869                     if (pParam->nPortIndex == PORT_INDEX_OUT) {
   1870                         pParam->bEnabled =
   1871                             (OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_MBINFO);
   1872                         DEBUG_PRINT_HIGH("MB Info extradata %d", pParam->bEnabled);
   1873                     } else {
   1874                         DEBUG_PRINT_ERROR("get_parameter: MB information is "
   1875                                 "valid for output port only");
   1876                         eRet = OMX_ErrorUnsupportedIndex;
   1877                     }
   1878                 } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataFrameDimension) {
   1879                     if (pParam->nPortIndex == PORT_INDEX_IN) {
   1880                         pParam->bEnabled =
   1881                             (OMX_BOOL)((m_sExtraData & VENC_EXTRADATA_FRAMEDIMENSION) ? 1 : 0);
   1882                         DEBUG_PRINT_HIGH("Frame dimension extradata %d", pParam->bEnabled);
   1883                     } else {
   1884                         DEBUG_PRINT_ERROR("get_parameter: frame dimension is "
   1885                                 "valid for input port only");
   1886                         eRet = OMX_ErrorUnsupportedIndex;
   1887                     }
   1888                 }
   1889                 else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) {
   1890                     if (pParam->nPortIndex == PORT_INDEX_OUT) {
   1891                         pParam->bEnabled =
   1892                             (OMX_BOOL)(m_sExtraData & VEN_EXTRADATA_LTRINFO);
   1893                         DEBUG_PRINT_HIGH("LTR Info extradata %d", pParam->bEnabled);
   1894                     } else {
   1895                         DEBUG_PRINT_ERROR("get_parameter: LTR information is "
   1896                                 "valid for output port only");
   1897                         eRet = OMX_ErrorUnsupportedIndex;
   1898                     }
   1899                 }
   1900                 else {
   1901                     DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)",
   1902                             pParam->nIndex);
   1903                     eRet = OMX_ErrorUnsupportedIndex;
   1904                 }
   1905                 break;
   1906             }
   1907         case QOMX_IndexParamVideoLTRCountRangeSupported:
   1908             {
   1909                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_RANGETYPE);
   1910                 DEBUG_PRINT_HIGH("get_parameter: QOMX_IndexParamVideoLTRCountRangeSupported");
   1911                 QOMX_EXTNINDEX_RANGETYPE *pParam = (QOMX_EXTNINDEX_RANGETYPE *)paramData;
   1912                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
   1913                     OMX_U32 min = 0, max = 0, step_size = 0;
   1914                     if (dev_get_capability_ltrcount(&min, &max, &step_size)) {
   1915                         pParam->nMin = min;
   1916                         pParam->nMax = max;
   1917                         pParam->nStepSize = step_size;
   1918                     } else {
   1919                         DEBUG_PRINT_ERROR("get_parameter: get_capability_ltrcount failed");
   1920                         eRet = OMX_ErrorUndefined;
   1921                     }
   1922                 } else {
   1923                     DEBUG_PRINT_ERROR("LTR count range is valid for output port only");
   1924                     eRet = OMX_ErrorUnsupportedIndex;
   1925                 }
   1926             }
   1927             break;
   1928         case OMX_QcomIndexParamVideoLTRCount:
   1929             {
   1930                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE);
   1931                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoLTRCount");
   1932                 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE *pParam =
   1933                         reinterpret_cast<OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*>(paramData);
   1934                 memcpy(pParam, &m_sParamLTRCount, sizeof(m_sParamLTRCount));
   1935                 break;
   1936             }
   1937 #endif
   1938         case QOMX_IndexParamVideoSyntaxHdr:
   1939             {
   1940                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE);
   1941                 DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
   1942                 QOMX_EXTNINDEX_PARAMTYPE* pParam =
   1943                     reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData);
   1944                 if (pParam->pData == NULL) {
   1945                     DEBUG_PRINT_ERROR("Error: Data buffer is NULL");
   1946                     eRet = OMX_ErrorBadParameter;
   1947                     break;
   1948                 }
   1949                 if (get_syntaxhdr_enable == false) {
   1950                     DEBUG_PRINT_ERROR("ERROR: get_parameter: Get syntax header disabled");
   1951                     eRet = OMX_ErrorUnsupportedIndex;
   1952                     break;
   1953                 }
   1954                 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
   1955                 if (dev_loaded_start()) {
   1956                     DEBUG_PRINT_LOW("device start successful");
   1957                 } else {
   1958                     DEBUG_PRINT_ERROR("device start failed");
   1959                     BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
   1960                     return OMX_ErrorHardware;
   1961                 }
   1962                 if (dev_get_seq_hdr(pParam->pData,
   1963                             (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)),
   1964                             (unsigned *)(void *)&pParam->nDataSize)) {
   1965                     DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %u)",
   1966                             (unsigned int)pParam->nDataSize);
   1967                     for (unsigned i = 0; i < pParam->nDataSize; i++) {
   1968                         DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i));
   1969                     }
   1970                 } else {
   1971                     DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()");
   1972                     eRet = OMX_ErrorHardware;
   1973                 }
   1974                 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
   1975                 if (dev_loaded_stop()) {
   1976                     DEBUG_PRINT_LOW("device stop successful");
   1977                 } else {
   1978                     DEBUG_PRINT_ERROR("device stop failed");
   1979                     BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
   1980                     eRet = OMX_ErrorHardware;
   1981                 }
   1982                 break;
   1983             }
   1984         case OMX_QcomIndexHierarchicalStructure:
   1985             {
   1986                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_HIERARCHICALLAYERS);
   1987                 QOMX_VIDEO_HIERARCHICALLAYERS* hierp = (QOMX_VIDEO_HIERARCHICALLAYERS*) paramData;
   1988                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexHierarchicalStructure");
   1989                 memcpy(hierp, &m_sHierLayers, sizeof(m_sHierLayers));
   1990                 break;
   1991             }
   1992          case OMX_QcomIndexParamMBIStatisticsMode:
   1993             {
   1994                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QOMX_VIDEO_MBI_STATISTICS);
   1995                 OMX_QOMX_VIDEO_MBI_STATISTICS* mbi_mode = (OMX_QOMX_VIDEO_MBI_STATISTICS*) paramData;
   1996                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamMBIStatisticsMode");
   1997                 memcpy(mbi_mode, &m_sMBIStatistics, sizeof(m_sMBIStatistics));
   1998                 break;
   1999             }
   2000         case OMX_QcomIndexParamPerfLevel:
   2001             {
   2002                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PERF_LEVEL);
   2003                 OMX_U32 perflevel;
   2004                 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
   2005                     reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PERF_LEVEL*>(paramData);
   2006                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPerfLevel");
   2007                 if (!dev_get_performance_level(&perflevel)) {
   2008                     DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
   2009                         pParam->ePerfLevel);
   2010                 } else {
   2011                     pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
   2012                 }
   2013                 break;
   2014             }
   2015         case OMX_QcomIndexParamH264VUITimingInfo:
   2016             {
   2017                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO);
   2018                 OMX_U32 enabled;
   2019                 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
   2020                     reinterpret_cast<OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO*>(paramData);
   2021                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamH264VUITimingInfo");
   2022                 if (!dev_get_vui_timing_info(&enabled)) {
   2023                     DEBUG_PRINT_ERROR("Invalid entry returned from get_vui_Timing_info %d",
   2024                         pParam->bEnable);
   2025                 } else {
   2026                     pParam->bEnable = (OMX_BOOL)enabled;
   2027                 }
   2028                 break;
   2029             }
   2030         case OMX_QTIIndexParamVQZIPSEIType:
   2031             {
   2032                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
   2033                 OMX_U32 enabled;
   2034                 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
   2035                     reinterpret_cast<OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*>(paramData);
   2036                 DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVQZIPSEIType");
   2037                 if (!dev_get_vqzip_sei_info(&enabled)) {
   2038                     DEBUG_PRINT_ERROR("Invalid entry returned from get_vqzip_sei_type %d",
   2039                         pParam->bEnable);
   2040                 } else {
   2041                     pParam->bEnable = (OMX_BOOL)enabled;
   2042                 }
   2043                 break;
   2044             }
   2045         case OMX_QcomIndexParamPeakBitrate:
   2046             {
   2047                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE);
   2048                 OMX_U32 peakbitrate;
   2049                 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
   2050                     reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE*>(paramData);
   2051                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPeakBitrate");
   2052                 if (!dev_get_peak_bitrate(&peakbitrate)) {
   2053                     DEBUG_PRINT_ERROR("Invalid entry returned from get_peak_bitrate %u",
   2054                         (unsigned int)pParam->nPeakBitrate);
   2055                 } else {
   2056                     pParam->nPeakBitrate = peakbitrate;
   2057                 }
   2058                 break;
   2059             }
   2060          case QOMX_IndexParamVideoInitialQp:
   2061             {
   2062                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP);
   2063                  QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp =
   2064                      reinterpret_cast<QOMX_EXTNINDEX_VIDEO_INITIALQP *>(paramData);
   2065                      memcpy(initqp, &m_sParamInitqp, sizeof(m_sParamInitqp));
   2066                 break;
   2067             }
   2068          case OMX_QcomIndexParamBatchSize:
   2069             {
   2070                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_U32TYPE);
   2071                 OMX_PARAM_U32TYPE* batch =
   2072                     reinterpret_cast<OMX_PARAM_U32TYPE *>(paramData);
   2073 
   2074                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamBatchSize");
   2075                 if (!dev_get_batch_size(&batch->nU32)) {
   2076                     DEBUG_PRINT_ERROR("Invalid entry returned from dev_get_batch_size %u",
   2077                         (unsigned int)batch->nSize);
   2078                     eRet = OMX_ErrorUnsupportedIndex;
   2079                     break;
   2080                 }
   2081 
   2082                 batch->nPortIndex = PORT_INDEX_IN;
   2083                 break;
   2084             }
   2085         case OMX_QcomIndexParamSequenceHeaderWithIDR:
   2086             {
   2087                 VALIDATE_OMX_PARAM_DATA(paramData, PrependSPSPPSToIDRFramesParams);
   2088                 PrependSPSPPSToIDRFramesParams * pParam =
   2089                     reinterpret_cast<PrependSPSPPSToIDRFramesParams *>(paramData);
   2090                 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamSequenceHeaderWithIDR");
   2091                 memcpy(pParam, &m_sPrependSPSPPS, sizeof(m_sPrependSPSPPS));
   2092                 break;
   2093             }
   2094         case OMX_QcomIndexParamVencAspectRatio:
   2095             {
   2096                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_SAR);
   2097                QOMX_EXTNINDEX_VIDEO_VENC_SAR * pParam =
   2098                    reinterpret_cast<QOMX_EXTNINDEX_VIDEO_VENC_SAR *>(paramData);
   2099                 memcpy(pParam, &m_sSar, sizeof(m_sSar));
   2100                 break;
   2101             }
   2102         case OMX_QTIIndexParamLowLatencyMode:
   2103            {
   2104                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE);
   2105                QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE * pParam =
   2106                    reinterpret_cast<QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE *>(paramData);
   2107                 memcpy(pParam, &m_slowLatencyMode, sizeof(m_slowLatencyMode));
   2108                 break;
   2109            }
   2110         case OMX_IndexParamAndroidVideoTemporalLayering:
   2111             {
   2112                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
   2113                 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pLayerInfo =
   2114                         reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*>(paramData);
   2115                 if (!dev_get_temporal_layer_caps(&m_sParamTemporalLayers.nLayerCountMax,
   2116                         &m_sParamTemporalLayers.nBLayerCountMax)) {
   2117                     DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities");
   2118                     eRet = OMX_ErrorUnsupportedIndex;
   2119                 }
   2120                 memcpy(pLayerInfo, &m_sParamTemporalLayers, sizeof(m_sParamTemporalLayers));
   2121                 break;
   2122             }
   2123         case OMX_QTIIndexParamDisablePQ:
   2124             {
   2125                 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_DISABLETYPE);
   2126                 OMX_BOOL pq_status;
   2127                 QOMX_DISABLETYPE *pParam =
   2128                         reinterpret_cast<QOMX_DISABLETYPE*>(paramData);
   2129                 if (!dev_get_pq_status(&pq_status)) {
   2130                     DEBUG_PRINT_ERROR("Failed to get PQ status");
   2131                     eRet = OMX_ErrorHardware;
   2132                 }
   2133                 pParam->bDisable = pq_status ? OMX_FALSE : OMX_TRUE;
   2134                 break;
   2135             }
   2136         case OMX_IndexParamVideoSliceFMO:
   2137         default:
   2138             {
   2139                 DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x", paramIndex);
   2140                 eRet =OMX_ErrorUnsupportedIndex;
   2141                 break;
   2142             }
   2143 
   2144     }
   2145 
   2146     return eRet;
   2147 
   2148 }
   2149 /* ======================================================================
   2150    FUNCTION
   2151    omx_video::GetConfig
   2152 
   2153    DESCRIPTION
   2154    OMX Get Config Method implementation.
   2155 
   2156    PARAMETERS
   2157    <TBD>.
   2158 
   2159    RETURN VALUE
   2160    OMX Error None if successful.
   2161 
   2162    ========================================================================== */
   2163 OMX_ERRORTYPE  omx_video::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   2164         OMX_IN OMX_INDEXTYPE configIndex,
   2165         OMX_INOUT OMX_PTR     configData)
   2166 {
   2167     (void)hComp;
   2168     ////////////////////////////////////////////////////////////////
   2169     // Supported Config Index           Type
   2170     // =============================================================
   2171     // OMX_IndexConfigVideoBitrate      OMX_VIDEO_CONFIG_BITRATETYPE
   2172     // OMX_IndexConfigVideoFramerate    OMX_CONFIG_FRAMERATETYPE
   2173     // OMX_IndexConfigCommonRotate      OMX_CONFIG_ROTATIONTYPE
   2174     ////////////////////////////////////////////////////////////////
   2175 
   2176     if (configData == NULL) {
   2177         DEBUG_PRINT_ERROR("ERROR: param is null");
   2178         return OMX_ErrorBadParameter;
   2179     }
   2180 
   2181     if (m_state == OMX_StateInvalid) {
   2182         DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
   2183         return OMX_ErrorIncorrectStateOperation;
   2184     }
   2185 
   2186     //@todo need to validate params
   2187     switch ((int)configIndex) {
   2188         case OMX_IndexConfigVideoBitrate:
   2189             {
   2190                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE);
   2191                 OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
   2192                 memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
   2193                 break;
   2194             }
   2195         case OMX_IndexConfigVideoFramerate:
   2196             {
   2197                 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE);
   2198                 OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
   2199                 memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
   2200                 break;
   2201             }
   2202         case OMX_IndexConfigCommonRotate:
   2203             {
   2204                 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE);
   2205                 OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
   2206                 memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
   2207                 break;
   2208             }
   2209         case QOMX_IndexConfigVideoIntraperiod:
   2210             {
   2211                 DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod");
   2212                 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE);
   2213                 QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
   2214                 memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
   2215                 break;
   2216             }
   2217         case OMX_IndexConfigVideoAVCIntraPeriod:
   2218             {
   2219                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD);
   2220                 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam =
   2221                     reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData);
   2222                 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod");
   2223                 memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod));
   2224                 break;
   2225             }
   2226         case OMX_IndexConfigCommonDeinterlace:
   2227             {
   2228                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE);
   2229                 OMX_VIDEO_CONFIG_DEINTERLACE *pParam =
   2230                     reinterpret_cast<OMX_VIDEO_CONFIG_DEINTERLACE*>(configData);
   2231                 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigCommonDeinterlace");
   2232                 memcpy(pParam, &m_sConfigDeinterlace, sizeof(m_sConfigDeinterlace));
   2233                 break;
   2234             }
   2235        case OMX_IndexConfigVideoVp8ReferenceFrame:
   2236            {
   2237                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE);
   2238                OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam =
   2239                    reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData);
   2240                DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame");
   2241                memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame));
   2242                break;
   2243            }
   2244         case OMX_QcomIndexConfigPerfLevel:
   2245             {
   2246                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
   2247                 OMX_U32 perflevel;
   2248                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam =
   2249                     reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData);
   2250                 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel");
   2251                 if (!dev_get_performance_level(&perflevel)) {
   2252                     DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
   2253                         pParam->ePerfLevel);
   2254                 } else {
   2255                     pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
   2256                 }
   2257                 break;
   2258             }
   2259        case OMX_QcomIndexConfigNumHierPLayers:
   2260            {
   2261                 VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS);
   2262                QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS* pParam =
   2263                    reinterpret_cast<QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS*>(configData);
   2264                DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigNumHierPLayers");
   2265                memcpy(pParam, &m_sHPlayers, sizeof(m_sHPlayers));
   2266                break;
   2267            }
   2268        case OMX_QcomIndexConfigQp:
   2269            {
   2270                 VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_QP);
   2271                OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
   2272                    reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_QP*>(configData);
   2273                DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigQp");
   2274                memcpy(pParam, &m_sConfigQP, sizeof(m_sConfigQP));
   2275                break;
   2276            }
   2277        case OMX_QcomIndexConfigBaseLayerId:
   2278            {
   2279                VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID);
   2280                OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
   2281                    reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*>(configData);
   2282                DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigBaseLayerId");
   2283                memcpy(pParam, &m_sBaseLayerID, sizeof(m_sBaseLayerID));
   2284                break;
   2285            }
   2286 #ifdef SUPPORT_CONFIG_INTRA_REFRESH
   2287        case OMX_IndexConfigAndroidIntraRefresh:
   2288            {
   2289                VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE);
   2290                OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam =
   2291                    reinterpret_cast<OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*>(configData);
   2292                DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidIntraRefresh");
   2293                memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh));
   2294                break;
   2295            }
   2296 #endif
   2297        case OMX_QTIIndexConfigVideoBlurResolution:
   2298            {
   2299                VALIDATE_OMX_PARAM_DATA(configData, OMX_QTI_VIDEO_CONFIG_BLURINFO);
   2300                OMX_QTI_VIDEO_CONFIG_BLURINFO* pParam =
   2301                    reinterpret_cast<OMX_QTI_VIDEO_CONFIG_BLURINFO*>(configData);
   2302                DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigVideoBlurResolution");
   2303                memcpy(pParam, &m_blurInfo, sizeof(m_blurInfo));
   2304                break;
   2305            }
   2306        case OMX_QTIIndexConfigDescribeColorAspects:
   2307             {
   2308                 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
   2309                 DescribeColorAspectsParams* pParam =
   2310                     reinterpret_cast<DescribeColorAspectsParams*>(configData);
   2311                 DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigDescribeColorAspects");
   2312                 if (pParam->bRequestingDataSpace) {
   2313                     DEBUG_PRINT_HIGH("Does not handle dataspace request");
   2314                     return OMX_ErrorUnsupportedSetting;
   2315                 }
   2316                 if (pParam->bDataSpaceChanged == OMX_TRUE) {
   2317 
   2318                     print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) Client says");
   2319                     // If the dataspace says RGB, recommend 601-limited;
   2320                     // since that is the destination colorspace that C2D or Venus will convert to.
   2321                     if (pParam->nPixelFormat == HAL_PIXEL_FORMAT_RGBA_8888) {
   2322                         DEBUG_PRINT_HIGH("get_config (dataspace changed): ColorSpace: Recommend 601-limited for RGBA8888");
   2323                         pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
   2324                         pParam->sAspects.mRange = ColorAspects::RangeLimited;
   2325                         pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
   2326                         pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   2327                     } else {
   2328                         // For IMPLEMENTATION_DEFINED (or anything else), stick to client's defaults.
   2329                         DEBUG_PRINT_HIGH("get_config (dataspace changed): ColorSpace: use client-default for format=%x",
   2330                                 pParam->nPixelFormat);
   2331                     }
   2332                     print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) recommended");
   2333                 } else {
   2334                     memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects));
   2335                     print_debug_color_aspects(&(pParam->sAspects), "get_config");
   2336                 }
   2337                 break;
   2338             }
   2339         case OMX_IndexParamAndroidVideoTemporalLayering:
   2340             {
   2341                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
   2342                 OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *layerConfig =
   2343                         (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)configData;
   2344                 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidVideoTemporalLayering");
   2345                 memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers));
   2346                 break;
   2347             }
   2348         case OMX_IndexConfigAndroidVendorExtension:
   2349             {
   2350                 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
   2351 
   2352                 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
   2353                     reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
   2354                 VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
   2355                 return get_vendor_extension_config(ext);
   2356             }
   2357 
   2358         default:
   2359             DEBUG_PRINT_HIGH("WARNING: get_config: unsupported index %x", (int) configIndex);
   2360             return OMX_ErrorUnsupportedIndex;
   2361     }
   2362     return OMX_ErrorNone;
   2363 
   2364 }
   2365 
   2366 #define extn_equals(param, extn) (!strcmp(param, extn))
   2367 
   2368 /* ======================================================================
   2369    FUNCTION
   2370    omx_video::GetExtensionIndex
   2371 
   2372    DESCRIPTION
   2373    OMX GetExtensionIndex method implementaion.  <TBD>
   2374 
   2375    PARAMETERS
   2376    <TBD>.
   2377 
   2378    RETURN VALUE
   2379    OMX Error None if everything successful.
   2380 
   2381    ========================================================================== */
   2382 OMX_ERRORTYPE  omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   2383         OMX_IN OMX_STRING      paramName,
   2384         OMX_OUT OMX_INDEXTYPE* indexType)
   2385 {
   2386     (void)hComp;
   2387     if (m_state == OMX_StateInvalid) {
   2388         DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State");
   2389         return OMX_ErrorInvalidState;
   2390     }
   2391 #ifdef MAX_RES_1080P
   2392     if (extn_equals(paramName, "OMX.QCOM.index.param.SliceDeliveryMode")) {
   2393         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
   2394         return OMX_ErrorNone;
   2395     }
   2396 #endif
   2397 #ifdef _ANDROID_ICS_
   2398     if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
   2399         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
   2400         return OMX_ErrorNone;
   2401     }
   2402 #endif
   2403     if (extn_equals(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) {
   2404         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
   2405         return OMX_ErrorNone;
   2406     }
   2407 
   2408     if (extn_equals(paramName, "OMX.QCOM.index.param.video.HierStructure")) {
   2409         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexHierarchicalStructure;
   2410         return OMX_ErrorNone;
   2411     }
   2412 
   2413     if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRCount")) {
   2414         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoLTRCount;
   2415         return OMX_ErrorNone;
   2416     }
   2417 
   2418     if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRPeriod")) {
   2419         return OMX_ErrorNone;
   2420     }
   2421 
   2422     if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRUse")) {
   2423         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRUse;
   2424         return OMX_ErrorNone;
   2425     }
   2426 
   2427     if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRMark")) {
   2428         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRMark;
   2429         return OMX_ErrorNone;
   2430     }
   2431 
   2432     if (extn_equals(paramName, "OMX.QCOM.index.config.video.hierplayers")) {
   2433         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigNumHierPLayers;
   2434         return OMX_ErrorNone;
   2435     }
   2436 
   2437     if (extn_equals(paramName, "OMX.QCOM.index.param.video.baselayerid")) {
   2438         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId;
   2439         return OMX_ErrorNone;
   2440     }
   2441 
   2442     if (extn_equals(paramName, "OMX.QCOM.index.config.video.qp")) {
   2443         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigQp;
   2444         return OMX_ErrorNone;
   2445     }
   2446 
   2447     if (extn_equals(paramName, "OMX.QCOM.index.param.video.sar")) {
   2448         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVencAspectRatio;
   2449         return OMX_ErrorNone;
   2450     }
   2451 
   2452     if (extn_equals(paramName, "OMX.QCOM.index.param.video.InputBatch")) {
   2453         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamBatchSize;
   2454         return OMX_ErrorNone;
   2455     }
   2456 
   2457     if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) {
   2458         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode;
   2459         return OMX_ErrorNone;
   2460     }
   2461 
   2462     if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_SETTIMEDATA)) {
   2463         *indexType = (OMX_INDEXTYPE)OMX_IndexConfigTimePosition;
   2464         return OMX_ErrorNone;
   2465     }
   2466 
   2467     if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO)) {
   2468         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableRoiInfo;
   2469         return OMX_ErrorNone;
   2470     }
   2471 
   2472     if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO)) {
   2473         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiInfo;
   2474         return OMX_ErrorNone;
   2475     }
   2476 
   2477     if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_BLURINFO)) {
   2478         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoBlurResolution;
   2479         return OMX_ErrorNone;
   2480     }
   2481 
   2482     if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
   2483         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
   2484         return OMX_ErrorNone;
   2485     }
   2486 
   2487     if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
   2488         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
   2489         return OMX_ErrorNone;
   2490     }
   2491 
   2492     return OMX_ErrorNotImplemented;
   2493 }
   2494 
   2495 /* ======================================================================
   2496    FUNCTION
   2497    omx_video::GetState
   2498 
   2499    DESCRIPTION
   2500    Returns the state information back to the caller.<TBD>
   2501 
   2502    PARAMETERS
   2503    <TBD>.
   2504 
   2505    RETURN VALUE
   2506    Error None if everything is successful.
   2507    ========================================================================== */
   2508 OMX_ERRORTYPE  omx_video::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   2509         OMX_OUT OMX_STATETYPE* state)
   2510 {
   2511     (void)hComp;
   2512     *state = m_state;
   2513     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
   2514     return OMX_ErrorNone;
   2515 }
   2516 
   2517 /* ======================================================================
   2518    FUNCTION
   2519    omx_video::ComponentTunnelRequest
   2520 
   2521    DESCRIPTION
   2522    OMX Component Tunnel Request method implementation. <TBD>
   2523 
   2524    PARAMETERS
   2525    None.
   2526 
   2527    RETURN VALUE
   2528    OMX Error None if everything successful.
   2529 
   2530    ========================================================================== */
   2531 OMX_ERRORTYPE  omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
   2532         OMX_IN OMX_U32                        port,
   2533         OMX_IN OMX_HANDLETYPE        peerComponent,
   2534         OMX_IN OMX_U32                    peerPort,
   2535         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   2536 {
   2537     (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup;
   2538     DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented");
   2539     return OMX_ErrorNotImplemented;
   2540 }
   2541 
   2542 /* ======================================================================
   2543    FUNCTION
   2544    omx_video::UseInputBuffer
   2545 
   2546    DESCRIPTION
   2547    Helper function for Use buffer in the input pin
   2548 
   2549    PARAMETERS
   2550    None.
   2551 
   2552    RETURN VALUE
   2553    true/false
   2554 
   2555    ========================================================================== */
   2556 OMX_ERRORTYPE  omx_video::use_input_buffer(
   2557         OMX_IN OMX_HANDLETYPE            hComp,
   2558         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2559         OMX_IN OMX_U32                   port,
   2560         OMX_IN OMX_PTR                   appData,
   2561         OMX_IN OMX_U32                   bytes,
   2562         OMX_IN OMX_U8*                   buffer)
   2563 {
   2564     (void) hComp;
   2565     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2566 
   2567     unsigned   i = 0;
   2568     unsigned char *buf_addr = NULL;
   2569 
   2570     DEBUG_PRINT_HIGH("use_input_buffer: port = %u appData = %p bytes = %u buffer = %p",(unsigned int)port,appData,(unsigned int)bytes,buffer);
   2571     if (bytes < m_sInPortDef.nBufferSize) {
   2572         DEBUG_PRINT_ERROR("ERROR: use_input_buffer: Size Mismatch!! "
   2573                 "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
   2574         return OMX_ErrorBadParameter;
   2575     }
   2576 
   2577     if (!m_inp_mem_ptr) {
   2578         input_use_buffer = true;
   2579         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   2580                         calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
   2581         if (m_inp_mem_ptr == NULL) {
   2582             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
   2583             return OMX_ErrorInsufficientResources;
   2584         }
   2585         DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
   2586 
   2587 
   2588         m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
   2589         if (m_pInput_pmem == NULL) {
   2590             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
   2591             return OMX_ErrorInsufficientResources;
   2592         }
   2593 #ifdef USE_ION
   2594         m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
   2595         if (m_pInput_ion == NULL) {
   2596             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
   2597             return OMX_ErrorInsufficientResources;
   2598         }
   2599 #endif
   2600 
   2601         for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   2602             m_pInput_pmem[i].fd = -1;
   2603 #ifdef USE_ION
   2604             m_pInput_ion[i].ion_device_fd =-1;
   2605             m_pInput_ion[i].fd_ion_data.fd =-1;
   2606             m_pInput_ion[i].ion_alloc_data.handle = 0;
   2607 #endif
   2608         }
   2609 
   2610     }
   2611 
   2612     for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   2613         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   2614             break;
   2615         }
   2616     }
   2617 
   2618     if (i < m_sInPortDef.nBufferCountActual) {
   2619 
   2620         *bufferHdr = (m_inp_mem_ptr + i);
   2621         BITMASK_SET(&m_inp_bm_count,i);
   2622 
   2623         (*bufferHdr)->pBuffer           = (OMX_U8 *)buffer;
   2624         (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   2625         (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
   2626         (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
   2627         (*bufferHdr)->pAppPrivate       = appData;
   2628         (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
   2629 
   2630         if (!m_use_input_pmem) {
   2631 #ifdef USE_ION
   2632 #ifdef _MSM8974_
   2633             m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   2634                     &m_pInput_ion[i].ion_alloc_data,
   2635                     &m_pInput_ion[i].fd_ion_data,
   2636                     secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0);
   2637 #else
   2638             m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   2639                     &m_pInput_ion[i].ion_alloc_data,
   2640                     &m_pInput_ion[i].fd_ion_data, ION_FLAG_CACHED);
   2641 #endif
   2642             if (m_pInput_ion[i].ion_device_fd < 0) {
   2643                 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   2644                 return OMX_ErrorInsufficientResources;
   2645             }
   2646             m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
   2647 #else
   2648             m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2649             if (m_pInput_pmem[i].fd == 0) {
   2650                 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2651             }
   2652 
   2653             if (m_pInput_pmem[i] .fd < 0) {
   2654                 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
   2655                 return OMX_ErrorInsufficientResources;
   2656             }
   2657 #endif
   2658             m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   2659             m_pInput_pmem[i].offset = 0;
   2660 
   2661             m_pInput_pmem[i].buffer = NULL;
   2662             if(!secure_session) {
   2663                 m_pInput_pmem[i].buffer = (unsigned char *)mmap(
   2664                     NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
   2665                     MAP_SHARED,m_pInput_pmem[i].fd,0);
   2666 
   2667                 if (m_pInput_pmem[i].buffer == MAP_FAILED) {
   2668                     DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
   2669                     m_pInput_pmem[i].buffer = NULL;
   2670                     close(m_pInput_pmem[i].fd);
   2671 #ifdef USE_ION
   2672                     free_ion_memory(&m_pInput_ion[i]);
   2673 #endif
   2674                     return OMX_ErrorInsufficientResources;
   2675                 }
   2676             }
   2677 
   2678         } else {
   2679             OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
   2680             DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (unsigned)pParam->offset);
   2681 
   2682             if (pParam) {
   2683                 m_pInput_pmem[i].fd = pParam->pmem_fd;
   2684                 m_pInput_pmem[i].offset = pParam->offset;
   2685                 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   2686                 m_pInput_pmem[i].buffer = (unsigned char *)buffer;
   2687                 DEBUG_PRINT_LOW("DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
   2688                         (unsigned int)pParam->pmem_fd, (unsigned int)pParam->offset);
   2689             } else {
   2690                 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
   2691                 return OMX_ErrorBadParameter;
   2692             }
   2693         }
   2694 
   2695         DEBUG_PRINT_LOW("use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
   2696                 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
   2697         if ( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) {
   2698             DEBUG_PRINT_ERROR("ERROR: dev_use_buf() Failed for i/p buf");
   2699             return OMX_ErrorInsufficientResources;
   2700         }
   2701     } else {
   2702         DEBUG_PRINT_ERROR("ERROR: All buffers are already used, invalid use_buf call for "
   2703                 "index = %u", i);
   2704         eRet = OMX_ErrorInsufficientResources;
   2705     }
   2706 
   2707     return eRet;
   2708 }
   2709 
   2710 
   2711 
   2712 /* ======================================================================
   2713    FUNCTION
   2714    omx_video::UseOutputBuffer
   2715 
   2716    DESCRIPTION
   2717    Helper function for Use buffer in the input pin
   2718 
   2719    PARAMETERS
   2720    None.
   2721 
   2722    RETURN VALUE
   2723    true/false
   2724 
   2725    ========================================================================== */
   2726 OMX_ERRORTYPE  omx_video::use_output_buffer(
   2727         OMX_IN OMX_HANDLETYPE            hComp,
   2728         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2729         OMX_IN OMX_U32                   port,
   2730         OMX_IN OMX_PTR                   appData,
   2731         OMX_IN OMX_U32                   bytes,
   2732         OMX_IN OMX_U8*                   buffer)
   2733 {
   2734     (void)hComp, (void)port;
   2735     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2736     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   2737     unsigned                         i= 0; // Temporary counter
   2738     unsigned char *buf_addr = NULL;
   2739 #ifdef _MSM8974_
   2740     int align_size;
   2741 #endif
   2742 
   2743     DEBUG_PRINT_HIGH("Inside use_output_buffer()");
   2744     if (bytes < m_sOutPortDef.nBufferSize) {
   2745         DEBUG_PRINT_ERROR("ERROR: use_output_buffer: Size Mismatch!! "
   2746                 "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sOutPortDef.nBufferSize);
   2747         return OMX_ErrorBadParameter;
   2748     }
   2749 
   2750     if (!m_out_mem_ptr) {
   2751         output_use_buffer = true;
   2752         int nBufHdrSize        = 0;
   2753 
   2754         DEBUG_PRINT_LOW("Allocating First Output Buffer(%u)",(unsigned int)m_sOutPortDef.nBufferCountActual);
   2755         nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
   2756         /*
   2757          * Memory for output side involves the following:
   2758          * 1. Array of Buffer Headers
   2759          * 2. Bitmask array to hold the buffer allocation details
   2760          * In order to minimize the memory management entire allocation
   2761          * is done in one step.
   2762          */
   2763         //OMX Buffer header
   2764         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   2765         if (m_out_mem_ptr == NULL) {
   2766             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_out_mem_ptr");
   2767             return OMX_ErrorInsufficientResources;
   2768         }
   2769 
   2770         m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
   2771         if (m_pOutput_pmem == NULL) {
   2772             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
   2773             return OMX_ErrorInsufficientResources;
   2774         }
   2775 #ifdef USE_ION
   2776         m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
   2777         if (m_pOutput_ion == NULL) {
   2778             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
   2779             return OMX_ErrorInsufficientResources;
   2780         }
   2781 #endif
   2782         if (m_out_mem_ptr) {
   2783             bufHdr          =  m_out_mem_ptr;
   2784             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   2785             // Settting the entire storage nicely
   2786             for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
   2787                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   2788                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   2789                 bufHdr->nAllocLen          = bytes;
   2790                 bufHdr->nFilledLen         = 0;
   2791                 bufHdr->pAppPrivate        = appData;
   2792                 bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
   2793                 bufHdr->pBuffer            = NULL;
   2794                 bufHdr++;
   2795                 m_pOutput_pmem[i].fd = -1;
   2796 #ifdef USE_ION
   2797                 m_pOutput_ion[i].ion_device_fd =-1;
   2798                 m_pOutput_ion[i].fd_ion_data.fd=-1;
   2799                 m_pOutput_ion[i].ion_alloc_data.handle = 0;
   2800 #endif
   2801             }
   2802         } else {
   2803             DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]",m_out_mem_ptr);
   2804             eRet =  OMX_ErrorInsufficientResources;
   2805         }
   2806     }
   2807 
   2808     for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
   2809         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   2810             break;
   2811         }
   2812     }
   2813 
   2814     if (eRet == OMX_ErrorNone) {
   2815         if (i < m_sOutPortDef.nBufferCountActual) {
   2816             *bufferHdr = (m_out_mem_ptr + i );
   2817             (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
   2818             (*bufferHdr)->pAppPrivate = appData;
   2819 
   2820             if (!m_use_output_pmem) {
   2821 #ifdef USE_ION
   2822 #ifdef _MSM8974_
   2823                 align_size = (m_sOutPortDef.nBufferSize + (SZ_4K - 1)) & ~(SZ_4K - 1);
   2824                 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size,
   2825                         &m_pOutput_ion[i].ion_alloc_data,
   2826                         &m_pOutput_ion[i].fd_ion_data,
   2827                         secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
   2828 #else
   2829                 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(
   2830                         m_sOutPortDef.nBufferSize,
   2831                         &m_pOutput_ion[i].ion_alloc_data,
   2832                         &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED);
   2833 #endif
   2834                 if (m_pOutput_ion[i].ion_device_fd < 0) {
   2835                     DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   2836                     return OMX_ErrorInsufficientResources;
   2837                 }
   2838                 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
   2839 #else
   2840                 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2841 
   2842                 if (m_pOutput_pmem[i].fd == 0) {
   2843                     m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2844                 }
   2845 
   2846                 if (m_pOutput_pmem[i].fd < 0) {
   2847                     DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
   2848                     return OMX_ErrorInsufficientResources;
   2849                 }
   2850 #endif
   2851                 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   2852                 m_pOutput_pmem[i].offset = 0;
   2853 
   2854                 m_pOutput_pmem[i].buffer = NULL;
   2855                 if(!secure_session) {
   2856 #ifdef _MSM8974_
   2857                     m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   2858                         align_size,PROT_READ|PROT_WRITE,
   2859                         MAP_SHARED,m_pOutput_pmem[i].fd,0);
   2860 #else
   2861                     m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   2862                         m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
   2863                         MAP_SHARED,m_pOutput_pmem[i].fd,0);
   2864 #endif
   2865                     if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
   2866                         DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
   2867                         m_pOutput_pmem[i].buffer = NULL;
   2868                         close(m_pOutput_pmem[i].fd);
   2869 #ifdef USE_ION
   2870                         free_ion_memory(&m_pOutput_ion[i]);
   2871 #endif
   2872                         return OMX_ErrorInsufficientResources;
   2873                     }
   2874                 }
   2875             } else {
   2876                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
   2877                 DEBUG_PRINT_LOW("Inside qcom_ext pParam: %p", pParam);
   2878 
   2879                 if (pParam) {
   2880                     DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (int)pParam->offset);
   2881                     m_pOutput_pmem[i].fd = pParam->pmem_fd;
   2882                     m_pOutput_pmem[i].offset = pParam->offset;
   2883                     m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   2884                     m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
   2885                 } else {
   2886                     DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
   2887                     return OMX_ErrorBadParameter;
   2888                 }
   2889                 buf_addr = (unsigned char *)buffer;
   2890             }
   2891 
   2892             DEBUG_PRINT_LOW("use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
   2893                     (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
   2894             if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) {
   2895                 DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
   2896                 return OMX_ErrorInsufficientResources;
   2897             }
   2898 
   2899             BITMASK_SET(&m_out_bm_count,i);
   2900         } else {
   2901             DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
   2902                     "index = %u", i);
   2903             eRet = OMX_ErrorInsufficientResources;
   2904         }
   2905     }
   2906     return eRet;
   2907 }
   2908 
   2909 
   2910 /* ======================================================================
   2911    FUNCTION
   2912    omx_video::UseBuffer
   2913 
   2914    DESCRIPTION
   2915    OMX Use Buffer method implementation.
   2916 
   2917    PARAMETERS
   2918    <TBD>.
   2919 
   2920    RETURN VALUE
   2921    OMX Error None , if everything successful.
   2922 
   2923    ========================================================================== */
   2924 OMX_ERRORTYPE  omx_video::use_buffer(
   2925         OMX_IN OMX_HANDLETYPE            hComp,
   2926         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2927         OMX_IN OMX_U32                   port,
   2928         OMX_IN OMX_PTR                   appData,
   2929         OMX_IN OMX_U32                   bytes,
   2930         OMX_IN OMX_U8*                   buffer)
   2931 {
   2932     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2933     if (m_state == OMX_StateInvalid) {
   2934         DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State");
   2935         return OMX_ErrorInvalidState;
   2936     }
   2937     if (port == PORT_INDEX_IN) {
   2938         auto_lock l(m_lock);
   2939         eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   2940     } else if (port == PORT_INDEX_OUT) {
   2941         eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   2942     } else {
   2943         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
   2944         eRet = OMX_ErrorBadPortIndex;
   2945     }
   2946 
   2947     if (eRet == OMX_ErrorNone) {
   2948         if (allocate_done()) {
   2949             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   2950                 // Send the callback now
   2951                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   2952                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   2953                         OMX_COMPONENT_GENERATE_EVENT);
   2954             }
   2955         }
   2956         if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
   2957             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   2958                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2959                 post_event(OMX_CommandPortEnable,
   2960                         PORT_INDEX_IN,
   2961                         OMX_COMPONENT_GENERATE_EVENT);
   2962             }
   2963 
   2964         } else if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
   2965             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   2966                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   2967                 post_event(OMX_CommandPortEnable,
   2968                         PORT_INDEX_OUT,
   2969                         OMX_COMPONENT_GENERATE_EVENT);
   2970                 m_event_port_settings_sent = false;
   2971             }
   2972         }
   2973     }
   2974     return eRet;
   2975 }
   2976 
   2977 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   2978 {
   2979     unsigned int index = 0;
   2980     OMX_U8 *temp_buff ;
   2981 
   2982     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
   2983         DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
   2984                 bufferHdr, m_inp_mem_ptr);
   2985         return OMX_ErrorBadParameter;
   2986     }
   2987 
   2988     index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
   2989 #ifdef _ANDROID_ICS_
   2990     if (meta_mode_enable) {
   2991         if (index < m_sInPortDef.nBufferCountActual) {
   2992             memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
   2993             memset(&meta_buffers[index], 0, sizeof(meta_buffers[index]));
   2994         }
   2995         if (!mUseProxyColorFormat)
   2996             return OMX_ErrorNone;
   2997         else {
   2998             c2d_conv.close();
   2999             opaque_buffer_hdr[index] = NULL;
   3000         }
   3001     }
   3002 #endif
   3003     if (index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat &&
   3004             dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
   3005         DEBUG_PRINT_LOW("ERROR: dev_free_buf() Failed for i/p buf");
   3006     }
   3007 
   3008     if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) {
   3009         auto_lock l(m_lock);
   3010 
   3011         if (mUseProxyColorFormat) {
   3012             if (m_opq_pmem_q.m_size) {
   3013                 unsigned long addr, p1, id;
   3014                 m_opq_pmem_q.pop_entry(&addr, &p1, &id);
   3015                 DEBUG_PRINT_LOW("Removed entry in m_opq_pmem_q: address %lu", addr);
   3016             }
   3017         }
   3018 
   3019         if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) {
   3020             DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case");
   3021             if(!secure_session) {
   3022                 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
   3023             } else {
   3024                 free(m_pInput_pmem[index].buffer);
   3025             }
   3026             m_pInput_pmem[index].buffer = NULL;
   3027             close (m_pInput_pmem[index].fd);
   3028 #ifdef USE_ION
   3029             free_ion_memory(&m_pInput_ion[index]);
   3030 #endif
   3031             m_pInput_pmem[index].fd = -1;
   3032         } else if (m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
   3033                     m_use_input_pmem == OMX_FALSE)) {
   3034             DEBUG_PRINT_LOW("FreeBuffer:: i/p Heap UseBuffer case");
   3035             if (dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
   3036                 DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf");
   3037             }
   3038             if(!secure_session) {
   3039                 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
   3040                 m_pInput_pmem[index].buffer = NULL;
   3041             }
   3042             close (m_pInput_pmem[index].fd);
   3043 #ifdef USE_ION
   3044             free_ion_memory(&m_pInput_ion[index]);
   3045 #endif
   3046             m_pInput_pmem[index].fd = -1;
   3047         } else {
   3048             DEBUG_PRINT_ERROR("FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
   3049         }
   3050     }
   3051     return OMX_ErrorNone;
   3052 }
   3053 
   3054 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   3055 {
   3056     unsigned int index = 0;
   3057     OMX_U8 *temp_buff ;
   3058 
   3059     if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
   3060         DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
   3061                 bufferHdr, m_out_mem_ptr);
   3062         return OMX_ErrorBadParameter;
   3063     }
   3064     index = bufferHdr - m_out_mem_ptr;
   3065 
   3066     if (index < m_sOutPortDef.nBufferCountActual &&
   3067             dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
   3068         DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
   3069     }
   3070 
   3071     if (index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) {
   3072         if (m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) {
   3073             DEBUG_PRINT_LOW("FreeBuffer:: o/p AllocateBuffer case");
   3074             if(!secure_session) {
   3075                 munmap (m_pOutput_pmem[index].buffer,
   3076                         m_pOutput_pmem[index].size);
   3077             } else {
   3078                 if (allocate_native_handle) {
   3079                     native_handle_t *handle = NULL;
   3080                     handle = (native_handle_t *)m_pOutput_pmem[index].buffer;
   3081                     native_handle_close(handle);
   3082                     native_handle_delete(handle);
   3083                 } else {
   3084                     char *data = (char*) m_pOutput_pmem[index].buffer;
   3085                     native_handle_t *handle = NULL;
   3086                     memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*));
   3087                     native_handle_delete(handle);
   3088                     free(m_pOutput_pmem[index].buffer);
   3089                 }
   3090             }
   3091             close (m_pOutput_pmem[index].fd);
   3092 #ifdef USE_ION
   3093             free_ion_memory(&m_pOutput_ion[index]);
   3094 #endif
   3095             m_pOutput_pmem[index].fd = -1;
   3096         } else if ( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
   3097                     && m_use_output_pmem == OMX_FALSE)) {
   3098             DEBUG_PRINT_LOW("FreeBuffer:: o/p Heap UseBuffer case");
   3099             if (dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
   3100                 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
   3101             }
   3102             if(!secure_session) {
   3103                 munmap (m_pOutput_pmem[index].buffer,
   3104                         m_pOutput_pmem[index].size);
   3105             }
   3106             close (m_pOutput_pmem[index].fd);
   3107 #ifdef USE_ION
   3108             free_ion_memory(&m_pOutput_ion[index]);
   3109 #endif
   3110             m_pOutput_pmem[index].fd = -1;
   3111         } else {
   3112             DEBUG_PRINT_LOW("FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
   3113         }
   3114     }
   3115     return OMX_ErrorNone;
   3116 }
   3117 #ifdef _ANDROID_ICS_
   3118 OMX_ERRORTYPE omx_video::allocate_input_meta_buffer(
   3119         OMX_HANDLETYPE       hComp,
   3120         OMX_BUFFERHEADERTYPE **bufferHdr,
   3121         OMX_PTR              appData,
   3122         OMX_U32              bytes)
   3123 {
   3124     unsigned index = 0;
   3125     // In meta-mode alloc-length is not known conclusively
   3126     // Allow allocation for atleast gralloc metadata handles
   3127     //  and check for size in ETB
   3128     if (!bufferHdr || bytes < sizeof(VideoGrallocMetadata)) {
   3129         DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %u",
   3130                 bufferHdr, (unsigned int)bytes);
   3131         return OMX_ErrorBadParameter;
   3132     }
   3133 
   3134     if (!m_inp_mem_ptr && !mUseProxyColorFormat) {
   3135         m_inp_mem_ptr = meta_buffer_hdr;
   3136         DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p",
   3137                 meta_buffer_hdr, m_inp_mem_ptr);
   3138     }
   3139     for (index = 0; ((index < m_sInPortDef.nBufferCountActual) &&
   3140                 meta_buffer_hdr[index].pBuffer &&
   3141                 BITMASK_PRESENT(&m_inp_bm_count, index)); index++);
   3142 
   3143     if (index == m_sInPortDef.nBufferCountActual) {
   3144         DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer");
   3145         return OMX_ErrorBadParameter;
   3146     }
   3147     if (mUseProxyColorFormat) {
   3148         if (opaque_buffer_hdr[index]) {
   3149             DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
   3150             return OMX_ErrorBadParameter;
   3151         }
   3152         if (allocate_input_buffer(hComp,&opaque_buffer_hdr[index],
   3153                     PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) {
   3154             DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
   3155             return OMX_ErrorBadParameter;
   3156         }
   3157     }
   3158     BITMASK_SET(&m_inp_bm_count,index);
   3159     *bufferHdr = &meta_buffer_hdr[index];
   3160     memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
   3161     meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]);
   3162     meta_buffer_hdr[index].nAllocLen = bytes;
   3163     meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION;
   3164     meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN;
   3165     meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index];
   3166     meta_buffer_hdr[index].pAppPrivate = appData;
   3167     if (mUseProxyColorFormat) {
   3168         m_opq_pmem_q.insert_entry((unsigned long)opaque_buffer_hdr[index],0,0);
   3169         DEBUG_PRINT_HIGH("opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]);
   3170     }
   3171     return OMX_ErrorNone;
   3172 }
   3173 #endif
   3174 /* ======================================================================
   3175    FUNCTION
   3176    omx_venc::AllocateInputBuffer
   3177 
   3178    DESCRIPTION
   3179    Helper function for allocate buffer in the input pin
   3180 
   3181    PARAMETERS
   3182    None.
   3183 
   3184    RETURN VALUE
   3185    true/false
   3186 
   3187    ========================================================================== */
   3188 OMX_ERRORTYPE  omx_video::allocate_input_buffer(
   3189         OMX_IN OMX_HANDLETYPE            hComp,
   3190         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3191         OMX_IN OMX_U32                   port,
   3192         OMX_IN OMX_PTR                   appData,
   3193         OMX_IN OMX_U32                   bytes)
   3194 {
   3195     (void)hComp, (void)port;
   3196     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3197     unsigned   i = 0;
   3198 
   3199     DEBUG_PRINT_HIGH("allocate_input_buffer()::");
   3200     if (bytes < m_sInPortDef.nBufferSize) {
   3201         DEBUG_PRINT_ERROR("ERROR: Buffer size mismatch error: bytes[%u] < nBufferSize[%u]",
   3202                 (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
   3203         return OMX_ErrorBadParameter;
   3204     }
   3205 
   3206     if (!m_inp_mem_ptr) {
   3207         DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
   3208                 (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountActual);
   3209         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   3210                         calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
   3211         if (m_inp_mem_ptr == NULL) {
   3212             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
   3213             return OMX_ErrorInsufficientResources;
   3214         }
   3215 
   3216         DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
   3217         m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
   3218 
   3219         if (m_pInput_pmem == NULL) {
   3220             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
   3221             return OMX_ErrorInsufficientResources;
   3222         }
   3223 #ifdef USE_ION
   3224         m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
   3225         if (m_pInput_ion == NULL) {
   3226             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
   3227             return OMX_ErrorInsufficientResources;
   3228         }
   3229 #endif
   3230         for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   3231             m_pInput_pmem[i].fd = -1;
   3232 #ifdef USE_ION
   3233             m_pInput_ion[i].ion_device_fd =-1;
   3234             m_pInput_ion[i].fd_ion_data.fd =-1;
   3235             m_pInput_ion[i].ion_alloc_data.handle = 0;
   3236 #endif
   3237         }
   3238     }
   3239 
   3240     for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   3241         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   3242             break;
   3243         }
   3244     }
   3245     if (i < m_sInPortDef.nBufferCountActual) {
   3246 
   3247         *bufferHdr = (m_inp_mem_ptr + i);
   3248         (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   3249         (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
   3250         (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
   3251         (*bufferHdr)->pAppPrivate       = appData;
   3252         (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
   3253         // make fd available to app layer, help with testing
   3254         (*bufferHdr)->pInputPortPrivate = (OMX_PTR)&m_pInput_pmem[i];
   3255 
   3256 #ifdef USE_ION
   3257 #ifdef _MSM8974_
   3258         m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   3259                 &m_pInput_ion[i].ion_alloc_data,
   3260                 &m_pInput_ion[i].fd_ion_data,
   3261                 secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0);
   3262 #else
   3263         m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   3264                 &m_pInput_ion[i].ion_alloc_data,
   3265                 &m_pInput_ion[i].fd_ion_data, ION_FLAG_CACHED);
   3266 #endif
   3267         if (m_pInput_ion[i].ion_device_fd < 0) {
   3268             DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   3269             return OMX_ErrorInsufficientResources;
   3270         }
   3271 
   3272         m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
   3273 #else
   3274         m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   3275 
   3276         if (m_pInput_pmem[i].fd == 0) {
   3277             m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   3278         }
   3279 
   3280         if (m_pInput_pmem[i].fd < 0) {
   3281             DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
   3282             return OMX_ErrorInsufficientResources;
   3283         }
   3284 #endif
   3285         m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   3286         m_pInput_pmem[i].offset = 0;
   3287 
   3288         m_pInput_pmem[i].buffer = NULL;
   3289         if(!secure_session) {
   3290             m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   3291                 m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
   3292                 MAP_SHARED,m_pInput_pmem[i].fd,0);
   3293             if (m_pInput_pmem[i].buffer == MAP_FAILED) {
   3294                 DEBUG_PRINT_ERROR("ERROR: mmap FAILED= %d", errno);
   3295                 m_pInput_pmem[i].buffer = NULL;
   3296                 close(m_pInput_pmem[i].fd);
   3297 #ifdef USE_ION
   3298                 free_ion_memory(&m_pInput_ion[i]);
   3299 #endif
   3300                 return OMX_ErrorInsufficientResources;
   3301             }
   3302         } else {
   3303             //This should only be used for passing reference to source type and
   3304             //secure handle fd struct native_handle_t*
   3305             m_pInput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*));
   3306             if (m_pInput_pmem[i].buffer == NULL) {
   3307                 DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__);
   3308                 return OMX_ErrorInsufficientResources;
   3309             }
   3310             (*bufferHdr)->nAllocLen = sizeof(OMX_U32) + sizeof(native_handle_t*);
   3311         }
   3312 
   3313         (*bufferHdr)->pBuffer           = (OMX_U8 *)m_pInput_pmem[i].buffer;
   3314         DEBUG_PRINT_LOW("Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer);
   3315         BITMASK_SET(&m_inp_bm_count,i);
   3316         //here change the I/P param here from buf_adr to pmem
   3317         if (!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) {
   3318             DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for i/p buf");
   3319             return OMX_ErrorInsufficientResources;
   3320         }
   3321     } else {
   3322         DEBUG_PRINT_ERROR("ERROR: All i/p buffers are allocated, invalid allocate buf call"
   3323                 "for index [%d]", i);
   3324         eRet = OMX_ErrorInsufficientResources;
   3325     }
   3326 
   3327     return eRet;
   3328 }
   3329 
   3330 
   3331 /* ======================================================================
   3332    FUNCTION
   3333    omx_venc::AllocateOutputBuffer
   3334 
   3335    DESCRIPTION
   3336    Helper fn for AllocateBuffer in the output pin
   3337 
   3338    PARAMETERS
   3339    <TBD>.
   3340 
   3341    RETURN VALUE
   3342    OMX Error None if everything went well.
   3343 
   3344    ========================================================================== */
   3345 OMX_ERRORTYPE  omx_video::allocate_output_buffer(
   3346         OMX_IN OMX_HANDLETYPE            hComp,
   3347         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3348         OMX_IN OMX_U32                   port,
   3349         OMX_IN OMX_PTR                   appData,
   3350         OMX_IN OMX_U32                   bytes)
   3351 {
   3352     (void)hComp, (void)port;
   3353     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3354     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   3355     unsigned                         i= 0; // Temporary counter
   3356 #ifdef _MSM8974_
   3357     int align_size;
   3358 #endif
   3359     DEBUG_PRINT_HIGH("allocate_output_buffer()for %u bytes", (unsigned int)bytes);
   3360     if (!m_out_mem_ptr) {
   3361         int nBufHdrSize        = 0;
   3362         DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
   3363                 (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountActual);
   3364         nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
   3365 
   3366         /*
   3367          * Memory for output side involves the following:
   3368          * 1. Array of Buffer Headers
   3369          * 2. Bitmask array to hold the buffer allocation details
   3370          * In order to minimize the memory management entire allocation
   3371          * is done in one step.
   3372          */
   3373         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   3374 
   3375 #ifdef USE_ION
   3376         m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
   3377         if (m_pOutput_ion == NULL) {
   3378             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
   3379             return OMX_ErrorInsufficientResources;
   3380         }
   3381 #endif
   3382         m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
   3383         if (m_pOutput_pmem == NULL) {
   3384             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
   3385             return OMX_ErrorInsufficientResources;
   3386         }
   3387         if (m_out_mem_ptr && m_pOutput_pmem) {
   3388             bufHdr          =  m_out_mem_ptr;
   3389 
   3390             for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
   3391                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   3392                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   3393                 // Set the values when we determine the right HxW param
   3394                 bufHdr->nAllocLen          = bytes;
   3395                 bufHdr->nFilledLen         = 0;
   3396                 bufHdr->pAppPrivate        = appData;
   3397                 bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
   3398                 // make fd available to app layer, help with testing
   3399                 bufHdr->pOutputPortPrivate = (OMX_PTR)&m_pOutput_pmem[i];
   3400                 bufHdr->pBuffer            = NULL;
   3401                 bufHdr++;
   3402                 m_pOutput_pmem[i].fd = -1;
   3403 #ifdef USE_ION
   3404                 m_pOutput_ion[i].ion_device_fd =-1;
   3405                 m_pOutput_ion[i].fd_ion_data.fd=-1;
   3406                 m_pOutput_ion[i].ion_alloc_data.handle = 0;
   3407 #endif
   3408             }
   3409         } else {
   3410             DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
   3411             eRet = OMX_ErrorInsufficientResources;
   3412         }
   3413     }
   3414 
   3415     DEBUG_PRINT_HIGH("actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferCountActual);
   3416     for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
   3417         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   3418             DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
   3419             break;
   3420         }
   3421     }
   3422     if (eRet == OMX_ErrorNone) {
   3423         if (i < m_sOutPortDef.nBufferCountActual) {
   3424 #ifdef USE_ION
   3425 #ifdef _MSM8974_
   3426             align_size = ALIGN(m_sOutPortDef.nBufferSize, 4096);
   3427             m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size,
   3428                     &m_pOutput_ion[i].ion_alloc_data,
   3429                     &m_pOutput_ion[i].fd_ion_data,
   3430                     secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : ION_FLAG_CACHED);
   3431 #else
   3432             m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize,
   3433                     &m_pOutput_ion[i].ion_alloc_data,
   3434                     &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED);
   3435 #endif
   3436             if (m_pOutput_ion[i].ion_device_fd < 0) {
   3437                 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   3438                 return OMX_ErrorInsufficientResources;
   3439             }
   3440 
   3441             m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
   3442 #else
   3443             m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   3444             if (m_pOutput_pmem[i].fd == 0) {
   3445                 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   3446             }
   3447 
   3448             if (m_pOutput_pmem[i].fd < 0) {
   3449                 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() failed");
   3450                 return OMX_ErrorInsufficientResources;
   3451             }
   3452 #endif
   3453             m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   3454             m_pOutput_pmem[i].offset = 0;
   3455 
   3456             m_pOutput_pmem[i].buffer = NULL;
   3457             *bufferHdr = (m_out_mem_ptr + i );
   3458 
   3459             if(!secure_session) {
   3460 #ifdef _MSM8974_
   3461                 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   3462                     align_size,PROT_READ|PROT_WRITE,
   3463                     MAP_SHARED,m_pOutput_pmem[i].fd,0);
   3464 #else
   3465                 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   3466                     m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
   3467                     MAP_SHARED,m_pOutput_pmem[i].fd,0);
   3468 #endif
   3469                 if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
   3470                     DEBUG_PRINT_ERROR("ERROR: MMAP_FAILED in o/p alloc buffer");
   3471                     m_pOutput_pmem[i].buffer = NULL;
   3472                     close (m_pOutput_pmem[i].fd);
   3473 #ifdef USE_ION
   3474                     free_ion_memory(&m_pOutput_ion[i]);
   3475 #endif
   3476                     return OMX_ErrorInsufficientResources;
   3477                 }
   3478             }
   3479             else {
   3480                 //This should only be used for passing reference to source type and
   3481                 //secure handle fd struct native_handle_t*
   3482                 if (allocate_native_handle) {
   3483                     native_handle_t *nh = native_handle_create(1 /*numFds*/, 3 /*numInts*/);
   3484                     if (!nh) {
   3485                         DEBUG_PRINT_ERROR("Native handle create failed");
   3486                         return OMX_ErrorInsufficientResources;
   3487                     }
   3488                     nh->data[0] = m_pOutput_pmem[i].fd;
   3489                     nh->data[1] = 0;
   3490                     nh->data[2] = 0;
   3491                     nh->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
   3492                     m_pOutput_pmem[i].buffer = (OMX_U8 *)nh;
   3493                 } else {
   3494                     native_handle_t *handle = native_handle_create(1, 3); //fd, offset, size, alloc length
   3495                     if (!handle) {
   3496                         DEBUG_PRINT_ERROR("ERROR: native handle creation failed");
   3497                         return OMX_ErrorInsufficientResources;
   3498                     }
   3499                     m_pOutput_pmem[i].buffer = malloc(sizeof(output_metabuffer));
   3500                     if (m_pOutput_pmem[i].buffer == NULL) {
   3501                         DEBUG_PRINT_ERROR("%s: Failed to allocate meta buffer", __func__);
   3502                         return OMX_ErrorInsufficientResources;
   3503                     }
   3504                     (*bufferHdr)->nAllocLen = sizeof(output_metabuffer);
   3505                     handle->data[0] = m_pOutput_pmem[i].fd;
   3506                     handle->data[1] = 0;
   3507                     handle->data[2] = 0;
   3508                     handle->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
   3509                     output_metabuffer *buffer = (output_metabuffer*) m_pOutput_pmem[i].buffer;
   3510                     buffer->type = 1;
   3511                     buffer->nh = handle;
   3512                 }
   3513             }
   3514 
   3515             (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
   3516             (*bufferHdr)->pAppPrivate = appData;
   3517 
   3518             BITMASK_SET(&m_out_bm_count,i);
   3519 
   3520             if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) {
   3521                 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for o/p buf");
   3522                 return OMX_ErrorInsufficientResources;
   3523             }
   3524         } else {
   3525             DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call"
   3526                     "for index [%d] actual: %u", i, (unsigned int)m_sOutPortDef.nBufferCountActual);
   3527         }
   3528     }
   3529 
   3530     return eRet;
   3531 }
   3532 
   3533 
   3534 // AllocateBuffer  -- API Call
   3535 /* ======================================================================
   3536    FUNCTION
   3537    omx_video::AllocateBuffer
   3538 
   3539    DESCRIPTION
   3540    Returns zero if all the buffers released..
   3541 
   3542    PARAMETERS
   3543    None.
   3544 
   3545    RETURN VALUE
   3546    true/false
   3547 
   3548    ========================================================================== */
   3549 OMX_ERRORTYPE  omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   3550         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3551         OMX_IN OMX_U32                        port,
   3552         OMX_IN OMX_PTR                     appData,
   3553         OMX_IN OMX_U32                       bytes)
   3554 {
   3555 
   3556     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   3557 
   3558     DEBUG_PRINT_LOW("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port);
   3559     if (m_state == OMX_StateInvalid) {
   3560         DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
   3561         return OMX_ErrorInvalidState;
   3562     }
   3563 
   3564     // What if the client calls again.
   3565     if (port == PORT_INDEX_IN) {
   3566         auto_lock l(m_lock);
   3567 #ifdef _ANDROID_ICS_
   3568         if (meta_mode_enable)
   3569             eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
   3570         else
   3571 #endif
   3572             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   3573     } else if (port == PORT_INDEX_OUT) {
   3574         eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   3575     } else {
   3576         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
   3577         eRet = OMX_ErrorBadPortIndex;
   3578     }
   3579     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   3580     if (eRet == OMX_ErrorNone) {
   3581         if (allocate_done()) {
   3582             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   3583                 // Send the callback now
   3584                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   3585                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   3586                         OMX_COMPONENT_GENERATE_EVENT);
   3587             }
   3588         }
   3589         if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
   3590             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   3591                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   3592                 post_event(OMX_CommandPortEnable,
   3593                         PORT_INDEX_IN,
   3594                         OMX_COMPONENT_GENERATE_EVENT);
   3595             }
   3596         }
   3597         if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
   3598             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   3599                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   3600                 post_event(OMX_CommandPortEnable,
   3601                         PORT_INDEX_OUT,
   3602                         OMX_COMPONENT_GENERATE_EVENT);
   3603                 m_event_port_settings_sent = false;
   3604             }
   3605         }
   3606     }
   3607     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
   3608     return eRet;
   3609 }
   3610 
   3611 
   3612 // Free Buffer - API call
   3613 /* ======================================================================
   3614    FUNCTION
   3615    omx_video::FreeBuffer
   3616 
   3617    DESCRIPTION
   3618 
   3619    PARAMETERS
   3620    None.
   3621 
   3622    RETURN VALUE
   3623    true/false
   3624 
   3625    ========================================================================== */
   3626 OMX_ERRORTYPE  omx_video::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   3627         OMX_IN OMX_U32                 port,
   3628         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   3629 {
   3630     (void)hComp;
   3631     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3632     unsigned int nPortIndex;
   3633 
   3634     DEBUG_PRINT_LOW("In for encoder free_buffer");
   3635 
   3636     if (m_state == OMX_StateIdle &&
   3637             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   3638         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
   3639     } else if ((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
   3640             (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) {
   3641         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
   3642     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   3643         DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled");
   3644         post_event(OMX_EventError,
   3645                 OMX_ErrorPortUnpopulated,
   3646                 OMX_COMPONENT_GENERATE_EVENT);
   3647         return eRet;
   3648     } else {
   3649         DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers");
   3650         post_event(OMX_EventError,
   3651                 OMX_ErrorPortUnpopulated,
   3652                 OMX_COMPONENT_GENERATE_EVENT);
   3653     }
   3654 
   3655     if (port == PORT_INDEX_IN) {
   3656         // check if the buffer is valid
   3657         nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
   3658 
   3659         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
   3660                 nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
   3661         pthread_mutex_lock(&m_lock);
   3662         if (nPortIndex < m_sInPortDef.nBufferCountActual &&
   3663                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
   3664             // Clear the bit associated with it.
   3665             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   3666             pthread_mutex_unlock(&m_lock);
   3667             free_input_buffer (buffer);
   3668             m_sInPortDef.bPopulated = OMX_FALSE;
   3669 
   3670             /*Free the Buffer Header*/
   3671             if (release_input_done()) {
   3672                 input_use_buffer = false;
   3673                 // "m_inp_mem_ptr" may point to "meta_buffer_hdr" in some modes,
   3674                 // in which case, it was not explicitly allocated
   3675                 if (m_inp_mem_ptr && m_inp_mem_ptr != meta_buffer_hdr) {
   3676                     DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr");
   3677                     free (m_inp_mem_ptr);
   3678                 }
   3679                 m_inp_mem_ptr = NULL;
   3680                 if (m_pInput_pmem) {
   3681                     DEBUG_PRINT_LOW("Freeing m_pInput_pmem");
   3682                     free(m_pInput_pmem);
   3683                     m_pInput_pmem = NULL;
   3684                 }
   3685 #ifdef USE_ION
   3686                 if (m_pInput_ion) {
   3687                     DEBUG_PRINT_LOW("Freeing m_pInput_ion");
   3688                     free(m_pInput_ion);
   3689                     m_pInput_ion = NULL;
   3690                 }
   3691 #endif
   3692             }
   3693         } else {
   3694             pthread_mutex_unlock(&m_lock);
   3695             DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid");
   3696             eRet = OMX_ErrorBadPortIndex;
   3697         }
   3698 
   3699         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   3700                 && release_input_done()) {
   3701             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   3702             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   3703             post_event(OMX_CommandPortDisable,
   3704                     PORT_INDEX_IN,
   3705                     OMX_COMPONENT_GENERATE_EVENT);
   3706         }
   3707     } else if (port == PORT_INDEX_OUT) {
   3708         // check if the buffer is valid
   3709         nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
   3710 
   3711         DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u",
   3712                 nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
   3713         if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
   3714                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
   3715             // Clear the bit associated with it.
   3716             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   3717             m_sOutPortDef.bPopulated = OMX_FALSE;
   3718             free_output_buffer (buffer);
   3719 
   3720             if (release_output_done()) {
   3721                 output_use_buffer = false;
   3722                 if (m_out_mem_ptr) {
   3723                     DEBUG_PRINT_LOW("Freeing m_out_mem_ptr");
   3724                     free (m_out_mem_ptr);
   3725                     m_out_mem_ptr = NULL;
   3726                 }
   3727                 if (m_pOutput_pmem) {
   3728                     DEBUG_PRINT_LOW("Freeing m_pOutput_pmem");
   3729                     free(m_pOutput_pmem);
   3730                     m_pOutput_pmem = NULL;
   3731                 }
   3732 #ifdef USE_ION
   3733                 if (m_pOutput_ion) {
   3734                     DEBUG_PRINT_LOW("Freeing m_pOutput_ion");
   3735                     free(m_pOutput_ion);
   3736                     m_pOutput_ion = NULL;
   3737                 }
   3738 #endif
   3739             }
   3740         } else {
   3741             DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid");
   3742             eRet = OMX_ErrorBadPortIndex;
   3743         }
   3744         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   3745                 && release_output_done() ) {
   3746             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
   3747 
   3748             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   3749             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   3750             post_event(OMX_CommandPortDisable,
   3751                     PORT_INDEX_OUT,
   3752                     OMX_COMPONENT_GENERATE_EVENT);
   3753 
   3754         }
   3755     } else {
   3756         eRet = OMX_ErrorBadPortIndex;
   3757     }
   3758     if ((eRet == OMX_ErrorNone) &&
   3759             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   3760         if (release_done()) {
   3761             if (dev_stop() != 0) {
   3762                 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED");
   3763                 eRet = OMX_ErrorHardware;
   3764             }
   3765             // Send the callback now
   3766             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   3767             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   3768                     OMX_COMPONENT_GENERATE_EVENT);
   3769         } else {
   3770             DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers output %" PRIx64" input %" PRIx64,
   3771                     m_out_bm_count, m_inp_bm_count);
   3772         }
   3773     }
   3774 
   3775     return eRet;
   3776 }
   3777 
   3778 
   3779 /* ======================================================================
   3780    FUNCTION
   3781    omx_video::EmptyThisBuffer
   3782 
   3783    DESCRIPTION
   3784    This routine is used to push the encoded video frames to
   3785    the video decoder.
   3786 
   3787    PARAMETERS
   3788    None.
   3789 
   3790    RETURN VALUE
   3791    OMX Error None if everything went successful.
   3792 
   3793    ========================================================================== */
   3794 OMX_ERRORTYPE  omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   3795         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   3796 {
   3797     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   3798     unsigned int nBufferIndex ;
   3799 
   3800     DEBUG_PRINT_LOW("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer);
   3801     if (m_state != OMX_StateExecuting &&
   3802             m_state != OMX_StatePause &&
   3803             m_state != OMX_StateIdle) {
   3804         DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State");
   3805         return OMX_ErrorInvalidState;
   3806     }
   3807 
   3808     if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
   3809         DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid");
   3810         return OMX_ErrorBadParameter;
   3811     }
   3812 
   3813     if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
   3814         DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid");
   3815         return OMX_ErrorVersionMismatch;
   3816     }
   3817 
   3818     if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) {
   3819         DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer");
   3820         return OMX_ErrorBadPortIndex;
   3821     }
   3822     if (!m_sInPortDef.bEnabled) {
   3823         DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled");
   3824         return OMX_ErrorIncorrectStateOperation;
   3825     }
   3826 
   3827     nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
   3828 
   3829     if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
   3830         DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
   3831         return OMX_ErrorBadParameter;
   3832     }
   3833 
   3834     m_etb_count++;
   3835     m_etb_timestamp = buffer->nTimeStamp;
   3836     DEBUG_PRINT_LOW("DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
   3837     post_event ((unsigned long)hComp,(unsigned long)buffer,m_input_msg_id);
   3838     return OMX_ErrorNone;
   3839 }
   3840 /* ======================================================================
   3841    FUNCTION
   3842    omx_video::empty_this_buffer_proxy
   3843 
   3844    DESCRIPTION
   3845    This routine is used to push the encoded video frames to
   3846    the video decoder.
   3847 
   3848    PARAMETERS
   3849    None.
   3850 
   3851    RETURN VALUE
   3852    OMX Error None if everything went successful.
   3853 
   3854    ========================================================================== */
   3855 OMX_ERRORTYPE  omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
   3856         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   3857 {
   3858     VIDC_TRACE_NAME_HIGH("ETB");
   3859     (void)hComp;
   3860     OMX_U8 *pmem_data_buf = NULL;
   3861     int push_cnt = 0;
   3862     unsigned nBufIndex = 0;
   3863     OMX_ERRORTYPE ret = OMX_ErrorNone;
   3864     LEGACY_CAM_METADATA_TYPE *media_buffer = NULL;
   3865 
   3866 #ifdef _MSM8974_
   3867     int fd = 0;
   3868 #endif
   3869     DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer);
   3870     if (buffer == NULL) {
   3871         DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer);
   3872         return OMX_ErrorBadParameter;
   3873     }
   3874 
   3875     // Buffer sanity checks
   3876     if (meta_mode_enable && !mUsesColorConversion) {
   3877         //For color-conversion case, we have an internal buffer and not a meta buffer
   3878         bool met_error = false;
   3879         nBufIndex = buffer - meta_buffer_hdr;
   3880         if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
   3881             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex);
   3882             return OMX_ErrorBadParameter;
   3883         }
   3884         media_buffer = (LEGACY_CAM_METADATA_TYPE *)meta_buffer_hdr[nBufIndex].pBuffer;
   3885         if (!media_buffer) {
   3886             DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
   3887             return OMX_ErrorBadParameter;
   3888         }
   3889         if ((media_buffer->buffer_type == LEGACY_CAM_SOURCE)
   3890                 && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
   3891             DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
   3892                     buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
   3893             met_error = true;
   3894         } else if (media_buffer) {
   3895             if (media_buffer->buffer_type != LEGACY_CAM_SOURCE &&
   3896                     media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
   3897                 met_error = true;
   3898             } else {
   3899                 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
   3900                     if (media_buffer->meta_handle == NULL)
   3901                         met_error = true;
   3902                     else {
   3903                         // TBD: revisit this check !
   3904                         int nFds = media_buffer->meta_handle->numFds,
   3905                             nInt = media_buffer->meta_handle->numInts;
   3906                         met_error = ((nFds == 1 && nInt >= 2) /*normal*/ ||
   3907                                 (nFds < 16 && nInt >= nFds*3) /*batch*/) ? false : true;
   3908                         if (met_error) {
   3909                             DEBUG_PRINT_ERROR("Unbalanced fds in handle: fds=%d ints=%d",
   3910                                     nFds, nInt);
   3911                         }
   3912                     }
   3913                 }
   3914             }
   3915         } else
   3916             met_error = true;
   3917         if (met_error) {
   3918             DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call");
   3919             post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
   3920             return OMX_ErrorBadParameter;
   3921         }
   3922     } else {
   3923         nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   3924         if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
   3925             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex);
   3926             return OMX_ErrorBadParameter;
   3927         }
   3928     }
   3929 
   3930     pending_input_buffers++;
   3931     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   3932     if (input_flush_progress == true) {
   3933         post_event ((unsigned long)buffer,0,
   3934                 OMX_COMPONENT_GENERATE_EBD);
   3935         DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress");
   3936         return OMX_ErrorNone;
   3937     }
   3938 #ifdef _MSM8974_
   3939     if (!meta_mode_enable) {
   3940         fd = m_pInput_pmem[nBufIndex].fd;
   3941     }
   3942 #endif
   3943 #ifdef _ANDROID_ICS_
   3944     if (meta_mode_enable && !mUsesColorConversion) {
   3945         // Camera or Gralloc-source meta-buffers queued with encodeable color-format
   3946         struct pmem Input_pmem_info;
   3947         if (!media_buffer) {
   3948             DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
   3949             return OMX_ErrorBadParameter;
   3950         }
   3951         if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
   3952             Input_pmem_info.buffer = media_buffer;
   3953             Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
   3954 #ifdef _MSM8974_
   3955             fd = Input_pmem_info.fd;
   3956 #endif
   3957             int offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
   3958             int size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
   3959             if (offset < 0 || size < 0) {
   3960                 DEBUG_PRINT_ERROR("meta-buffer is invalid!");
   3961                 return OMX_ErrorBadParameter;
   3962             }
   3963             Input_pmem_info.offset = offset;
   3964             Input_pmem_info.size = size;
   3965             DEBUG_PRINT_INFO("ETB (meta-Camera) fd = %d, offset = %d, size = %d",
   3966                     Input_pmem_info.fd, Input_pmem_info.offset,
   3967                     Input_pmem_info.size);
   3968         } else {
   3969             VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)meta_buffer_hdr[nBufIndex].pBuffer;
   3970             private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
   3971             Input_pmem_info.buffer = media_buffer;
   3972             Input_pmem_info.fd = handle->fd;
   3973 #ifdef _MSM8974_
   3974             fd = Input_pmem_info.fd;
   3975 #endif
   3976             Input_pmem_info.offset = 0;
   3977             Input_pmem_info.size = handle->size;
   3978             DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
   3979                     Input_pmem_info.fd, Input_pmem_info.offset,
   3980                     Input_pmem_info.size);
   3981         }
   3982         if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,nBufIndex) != true) {
   3983             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
   3984             post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
   3985             return OMX_ErrorBadParameter;
   3986         }
   3987     } else if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
   3988 #else
   3989     if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
   3990 #endif
   3991     {
   3992         DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");
   3993 
   3994         auto_lock l(m_lock);
   3995         pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
   3996         if (pmem_data_buf && BITMASK_PRESENT(&m_inp_bm_count, nBufIndex)) {
   3997             memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
   3998                     buffer->nFilledLen);
   3999         }
   4000         DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
   4001     } else if (mUseProxyColorFormat) {
   4002         // Gralloc-source buffers with color-conversion
   4003         fd = m_pInput_pmem[nBufIndex].fd;
   4004         DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u",
   4005                 fd, (unsigned int)buffer->nFilledLen);
   4006     } else if (m_sInPortDef.format.video.eColorFormat ==
   4007                     OMX_COLOR_FormatYUV420SemiPlanar) {
   4008             //For the case where YUV420SP buffers are qeueued to component
   4009             //by sources other than camera (Apps via MediaCodec), conversion
   4010             //to vendor flavoured NV12 color format is required.
   4011             if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth,
   4012                                     m_sInPortDef.format.video.nFrameHeight)) {
   4013                     DEBUG_PRINT_ERROR("Failed to adjust buffer color");
   4014                     post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
   4015                     return OMX_ErrorUndefined;
   4016             }
   4017     }
   4018 #ifdef _MSM8974_
   4019     if (dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true)
   4020 #else
   4021     if (dev_empty_buf(buffer, pmem_data_buf,0,0) != true)
   4022 #endif
   4023     {
   4024         DEBUG_PRINT_ERROR("ERROR: ETBProxy: dev_empty_buf failed");
   4025 #ifdef _ANDROID_ICS_
   4026         omx_release_meta_buffer(buffer);
   4027 #endif
   4028         post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
   4029         /*Generate an async error and move to invalid state*/
   4030         pending_input_buffers--;
   4031         VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   4032         if (hw_overload) {
   4033             return OMX_ErrorInsufficientResources;
   4034         }
   4035         return OMX_ErrorBadParameter;
   4036     }
   4037     return ret;
   4038 }
   4039 
   4040 /* ======================================================================
   4041    FUNCTION
   4042    omx_video::FillThisBuffer
   4043 
   4044    DESCRIPTION
   4045    IL client uses this method to release the frame buffer
   4046    after displaying them.
   4047 
   4048    PARAMETERS
   4049    None.
   4050 
   4051    RETURN VALUE
   4052    true/false
   4053 
   4054    ========================================================================== */
   4055 OMX_ERRORTYPE  omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   4056         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   4057 {
   4058     DEBUG_PRINT_LOW("FTB: buffer->pBuffer[%p]", buffer->pBuffer);
   4059     if (m_state != OMX_StateExecuting &&
   4060             m_state != OMX_StatePause &&
   4061             m_state != OMX_StateIdle) {
   4062         DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State");
   4063         return OMX_ErrorInvalidState;
   4064     }
   4065 
   4066     if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
   4067         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size");
   4068         return OMX_ErrorBadParameter;
   4069     }
   4070 
   4071     if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
   4072         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid");
   4073         return OMX_ErrorVersionMismatch;
   4074     }
   4075 
   4076     if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) {
   4077         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index");
   4078         return OMX_ErrorBadPortIndex;
   4079     }
   4080 
   4081     if (!m_sOutPortDef.bEnabled) {
   4082         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled");
   4083         return OMX_ErrorIncorrectStateOperation;
   4084     }
   4085 
   4086     post_event((unsigned long) hComp, (unsigned long)buffer,OMX_COMPONENT_GENERATE_FTB);
   4087     return OMX_ErrorNone;
   4088 }
   4089 
   4090 /* ======================================================================
   4091    FUNCTION
   4092    omx_video::fill_this_buffer_proxy
   4093 
   4094    DESCRIPTION
   4095    IL client uses this method to release the frame buffer
   4096    after displaying them.
   4097 
   4098    PARAMETERS
   4099    None.
   4100 
   4101    RETURN VALUE
   4102    true/false
   4103 
   4104    ========================================================================== */
   4105 OMX_ERRORTYPE  omx_video::fill_this_buffer_proxy(
   4106         OMX_IN OMX_HANDLETYPE        hComp,
   4107         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   4108 {
   4109     VIDC_TRACE_NAME_HIGH("FTB");
   4110     (void)hComp;
   4111     OMX_U8 *pmem_data_buf = NULL;
   4112     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   4113 
   4114     DEBUG_PRINT_LOW("FTBProxy: bufferAdd->pBuffer[%p]", bufferAdd->pBuffer);
   4115 
   4116     if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) {
   4117         DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params");
   4118         return OMX_ErrorBadParameter;
   4119     }
   4120 
   4121     pending_output_buffers++;
   4122     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   4123     /*Return back the output buffer to client*/
   4124     if ( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) {
   4125         DEBUG_PRINT_LOW("o/p port is Disabled or Flush in Progress");
   4126         post_event ((unsigned long)bufferAdd,0,
   4127                 OMX_COMPONENT_GENERATE_FBD);
   4128         return OMX_ErrorNone;
   4129     }
   4130 
   4131     if (output_use_buffer && !m_use_output_pmem) {
   4132         DEBUG_PRINT_LOW("Heap UseBuffer case");
   4133         pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
   4134     }
   4135 
   4136     if (dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) {
   4137         DEBUG_PRINT_ERROR("ERROR: dev_fill_buf() Failed");
   4138         post_event ((unsigned long)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
   4139         pending_output_buffers--;
   4140         VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   4141         return OMX_ErrorBadParameter;
   4142     }
   4143 
   4144     return OMX_ErrorNone;
   4145 }
   4146 
   4147 /* ======================================================================
   4148    FUNCTION
   4149    omx_video::SetCallbacks
   4150 
   4151    DESCRIPTION
   4152    Set the callbacks.
   4153 
   4154    PARAMETERS
   4155    None.
   4156 
   4157    RETURN VALUE
   4158    OMX Error None if everything successful.
   4159 
   4160    ========================================================================== */
   4161 OMX_ERRORTYPE  omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   4162         OMX_IN OMX_CALLBACKTYPE* callbacks,
   4163         OMX_IN OMX_PTR             appData)
   4164 {
   4165     (void)hComp;
   4166     m_pCallbacks       = *callbacks;
   4167     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
   4168             m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
   4169     m_app_data =    appData;
   4170     return OMX_ErrorNotImplemented;
   4171 }
   4172 
   4173 
   4174 /* ======================================================================
   4175    FUNCTION
   4176    omx_venc::UseEGLImage
   4177 
   4178    DESCRIPTION
   4179    OMX Use EGL Image method implementation <TBD>.
   4180 
   4181    PARAMETERS
   4182    <TBD>.
   4183 
   4184    RETURN VALUE
   4185    Not Implemented error.
   4186 
   4187    ========================================================================== */
   4188 OMX_ERRORTYPE  omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE   hComp,
   4189         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4190         OMX_IN OMX_U32                        port,
   4191         OMX_IN OMX_PTR                     appData,
   4192         OMX_IN void*                      eglImage)
   4193 {
   4194     (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage;
   4195     DEBUG_PRINT_ERROR("ERROR: use_EGL_image:  Not Implemented");
   4196     return OMX_ErrorNotImplemented;
   4197 }
   4198 
   4199 /* ======================================================================
   4200    FUNCTION
   4201    omx_venc::ComponentRoleEnum
   4202 
   4203    DESCRIPTION
   4204    OMX Component Role Enum method implementation.
   4205 
   4206    PARAMETERS
   4207    <TBD>.
   4208 
   4209    RETURN VALUE
   4210    OMX Error None if everything is successful.
   4211    ========================================================================== */
   4212 OMX_ERRORTYPE  omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   4213         OMX_OUT OMX_U8*        role,
   4214         OMX_IN OMX_U32        index)
   4215 {
   4216     (void)hComp;
   4217     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4218     if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   4219         if ((0 == index) && role) {
   4220             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   4221             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4222         } else {
   4223             eRet = OMX_ErrorNoMore;
   4224         }
   4225     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   4226         if ((0 == index) && role) {
   4227             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   4228             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4229         } else {
   4230             DEBUG_PRINT_ERROR("ERROR: No more roles");
   4231             eRet = OMX_ErrorNoMore;
   4232         }
   4233     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   4234         if ((0 == index) && role) {
   4235             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   4236             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4237         } else {
   4238             DEBUG_PRINT_ERROR("ERROR: No more roles");
   4239             eRet = OMX_ErrorNoMore;
   4240         }
   4241     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
   4242         if ((0 == index) && role) {
   4243             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   4244             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4245         } else {
   4246             DEBUG_PRINT_ERROR("ERROR: No more roles");
   4247             eRet = OMX_ErrorNoMore;
   4248         }
   4249     }
   4250     if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   4251         if ((0 == index) && role) {
   4252             strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   4253             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4254         } else {
   4255             eRet = OMX_ErrorNoMore;
   4256         }
   4257     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   4258         if ((0 == index) && role) {
   4259             strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
   4260             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4261         } else {
   4262             DEBUG_PRINT_ERROR("ERROR: No more roles");
   4263             eRet = OMX_ErrorNoMore;
   4264         }
   4265     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   4266         if ((0 == index) && role) {
   4267             strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
   4268             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4269         } else {
   4270             DEBUG_PRINT_ERROR("ERROR: No more roles");
   4271             eRet = OMX_ErrorNoMore;
   4272         }
   4273     }
   4274 #ifdef _MSM8974_
   4275     else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   4276         if ((0 == index) && role) {
   4277             strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   4278             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   4279         } else {
   4280             DEBUG_PRINT_ERROR("ERROR: No more roles");
   4281             eRet = OMX_ErrorNoMore;
   4282         }
   4283     }
   4284 #endif
   4285     else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4286         if ((0 == index) && role) {
   4287             strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   4288             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
   4289         } else {
   4290             DEBUG_PRINT_ERROR("ERROR: No more roles");
   4291             eRet = OMX_ErrorNoMore;
   4292         }
   4293     }
   4294     else {
   4295         DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
   4296         eRet = OMX_ErrorInvalidComponentName;
   4297     }
   4298     return eRet;
   4299 }
   4300 
   4301 
   4302 
   4303 
   4304 /* ======================================================================
   4305    FUNCTION
   4306    omx_venc::AllocateDone
   4307 
   4308    DESCRIPTION
   4309    Checks if entire buffer pool is allocated by IL Client or not.
   4310    Need this to move to IDLE state.
   4311 
   4312    PARAMETERS
   4313    None.
   4314 
   4315    RETURN VALUE
   4316    true/false.
   4317 
   4318    ========================================================================== */
   4319 bool omx_video::allocate_done(void)
   4320 {
   4321     bool bRet = false;
   4322     bool bRet_In = false;
   4323     bool bRet_Out = false;
   4324 
   4325     bRet_In = allocate_input_done();
   4326     bRet_Out = allocate_output_done();
   4327 
   4328     if (bRet_In && bRet_Out) {
   4329         bRet = true;
   4330     }
   4331 
   4332     return bRet;
   4333 }
   4334 /* ======================================================================
   4335    FUNCTION
   4336    omx_venc::AllocateInputDone
   4337 
   4338    DESCRIPTION
   4339    Checks if I/P buffer pool is allocated by IL Client or not.
   4340 
   4341    PARAMETERS
   4342    None.
   4343 
   4344    RETURN VALUE
   4345    true/false.
   4346 
   4347    ========================================================================== */
   4348 bool omx_video::allocate_input_done(void)
   4349 {
   4350     bool bRet = false;
   4351     unsigned i=0;
   4352 
   4353     if (m_inp_mem_ptr == NULL) {
   4354         return bRet;
   4355     }
   4356     if (m_inp_mem_ptr ) {
   4357         for (; i<m_sInPortDef.nBufferCountActual; i++) {
   4358             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   4359                 break;
   4360             }
   4361         }
   4362     }
   4363     if (i==m_sInPortDef.nBufferCountActual) {
   4364         bRet = true;
   4365     }
   4366     if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) {
   4367         m_sInPortDef.bPopulated = OMX_TRUE;
   4368     }
   4369     return bRet;
   4370 }
   4371 /* ======================================================================
   4372    FUNCTION
   4373    omx_venc::AllocateOutputDone
   4374 
   4375    DESCRIPTION
   4376    Checks if entire O/P buffer pool is allocated by IL Client or not.
   4377 
   4378    PARAMETERS
   4379    None.
   4380 
   4381    RETURN VALUE
   4382    true/false.
   4383 
   4384    ========================================================================== */
   4385 bool omx_video::allocate_output_done(void)
   4386 {
   4387     bool bRet = false;
   4388     unsigned j=0;
   4389 
   4390     if (m_out_mem_ptr == NULL) {
   4391         return bRet;
   4392     }
   4393 
   4394     if (m_out_mem_ptr ) {
   4395         for (; j<m_sOutPortDef.nBufferCountActual; j++) {
   4396             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   4397                 break;
   4398             }
   4399         }
   4400     }
   4401 
   4402     if (j==m_sOutPortDef.nBufferCountActual) {
   4403         bRet = true;
   4404     }
   4405 
   4406     if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) {
   4407         m_sOutPortDef.bPopulated = OMX_TRUE;
   4408     }
   4409     return bRet;
   4410 }
   4411 
   4412 /* ======================================================================
   4413    FUNCTION
   4414    omx_venc::ReleaseDone
   4415 
   4416    DESCRIPTION
   4417    Checks if IL client has released all the buffers.
   4418 
   4419    PARAMETERS
   4420    None.
   4421 
   4422    RETURN VALUE
   4423    true/false
   4424 
   4425    ========================================================================== */
   4426 bool omx_video::release_done(void)
   4427 {
   4428     bool bRet = false;
   4429     DEBUG_PRINT_LOW("Inside release_done()");
   4430     if (release_input_done()) {
   4431         if (release_output_done()) {
   4432             bRet = true;
   4433         }
   4434     }
   4435     return bRet;
   4436 }
   4437 
   4438 
   4439 /* ======================================================================
   4440    FUNCTION
   4441    omx_venc::ReleaseOutputDone
   4442 
   4443    DESCRIPTION
   4444    Checks if IL client has released all the buffers.
   4445 
   4446    PARAMETERS
   4447    None.
   4448 
   4449    RETURN VALUE
   4450    true/false
   4451 
   4452    ========================================================================== */
   4453 bool omx_video::release_output_done(void)
   4454 {
   4455     bool bRet = false;
   4456     unsigned i=0,j=0;
   4457 
   4458     DEBUG_PRINT_LOW("Inside release_output_done()");
   4459     if (m_out_mem_ptr) {
   4460         for (; j<m_sOutPortDef.nBufferCountActual; j++) {
   4461             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   4462                 break;
   4463             }
   4464         }
   4465         if (j==m_sOutPortDef.nBufferCountActual) {
   4466             bRet = true;
   4467         }
   4468     } else {
   4469         bRet = true;
   4470     }
   4471     return bRet;
   4472 }
   4473 /* ======================================================================
   4474    FUNCTION
   4475    omx_venc::ReleaseInputDone
   4476 
   4477    DESCRIPTION
   4478    Checks if IL client has released all the buffers.
   4479 
   4480    PARAMETERS
   4481    None.
   4482 
   4483    RETURN VALUE
   4484    true/false
   4485 
   4486    ========================================================================== */
   4487 bool omx_video::release_input_done(void)
   4488 {
   4489     bool bRet = false;
   4490     unsigned i=0,j=0;
   4491 
   4492     DEBUG_PRINT_LOW("Inside release_input_done()");
   4493     if (m_inp_mem_ptr) {
   4494         for (; j<m_sInPortDef.nBufferCountActual; j++) {
   4495             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   4496                 break;
   4497             }
   4498         }
   4499         if (j==m_sInPortDef.nBufferCountActual) {
   4500             bRet = true;
   4501         }
   4502     } else {
   4503         bRet = true;
   4504     }
   4505     return bRet;
   4506 }
   4507 
   4508 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
   4509         OMX_BUFFERHEADERTYPE * buffer)
   4510 {
   4511     VIDC_TRACE_NAME_HIGH("FBD");
   4512 #ifdef _MSM8974_
   4513     int index = buffer - m_out_mem_ptr;
   4514 #endif
   4515     DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %u",
   4516             buffer->pBuffer, (unsigned)buffer->nFlags, (unsigned int)buffer->nFilledLen);
   4517     if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) {
   4518         return OMX_ErrorBadParameter;
   4519     }
   4520 
   4521     pending_output_buffers--;
   4522     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   4523     VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
   4524     VIDC_TRACE_INT_LOW("FBD-size", buffer->nFilledLen);
   4525 
   4526     if (secure_session && m_pCallbacks.FillBufferDone) {
   4527         if (buffer->nFilledLen > 0)
   4528             m_fbd_count++;
   4529         m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
   4530         return OMX_ErrorNone;
   4531     }
   4532     if(!secure_session) {
   4533         extra_data_handle.create_extra_data(buffer);
   4534 #ifndef _MSM8974_
   4535         if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
   4536             DEBUG_PRINT_LOW("parsing extradata");
   4537             extra_data_handle.parse_extra_data(buffer);
   4538         }
   4539 #endif
   4540     }
   4541 
   4542     /* For use buffer we need to copy the data */
   4543     if (m_pCallbacks.FillBufferDone) {
   4544         if (buffer->nFilledLen > 0) {
   4545             m_fbd_count++;
   4546 
   4547             if (dev_get_output_log_flag()) {
   4548                 dev_output_log_buffers((const char*)buffer->pBuffer, buffer->nFilledLen);
   4549             }
   4550         }
   4551         if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
   4552             if (!dev_handle_output_extradata((void *)buffer, index))
   4553                 DEBUG_PRINT_ERROR("Failed to parse output extradata");
   4554 
   4555             dev_extradata_log_buffers((char *)(((unsigned long)buffer->pBuffer + buffer->nOffset +
   4556                         buffer->nFilledLen + 3) & (~3)));
   4557         }
   4558         m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
   4559     } else {
   4560         return OMX_ErrorBadParameter;
   4561     }
   4562     return OMX_ErrorNone;
   4563 }
   4564 
   4565 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE         hComp,
   4566         OMX_BUFFERHEADERTYPE* buffer)
   4567 {
   4568     VIDC_TRACE_NAME_HIGH("EBD");
   4569     int buffer_index  = -1;
   4570 
   4571     buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
   4572     DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer);
   4573     if (buffer == NULL ||
   4574             ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
   4575         DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
   4576         return OMX_ErrorBadParameter;
   4577     }
   4578 
   4579     pending_input_buffers--;
   4580     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   4581 
   4582     if (mUseProxyColorFormat &&
   4583         (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
   4584         if (!pdest_frame  && !input_flush_progress && mUsesColorConversion) {
   4585             pdest_frame = buffer;
   4586             DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
   4587             return push_input_buffer(hComp);
   4588         }
   4589         //check if empty-EOS-buffer is being returned, treat this same as the
   4590         //color-conversion case as we queued a color-conversion buffer to encoder
   4591         bool handleEmptyEosBuffer = (mEmptyEosBuffer == buffer);
   4592         if (mUsesColorConversion || handleEmptyEosBuffer) {
   4593             if (handleEmptyEosBuffer) {
   4594                 mEmptyEosBuffer = NULL;
   4595             }
   4596             // return color-conversion buffer back to the pool
   4597             DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer);
   4598             if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) {
   4599                 DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full");
   4600                 return OMX_ErrorBadParameter;
   4601             }
   4602         } else {
   4603             // We are not dealing with color-conversion, Buffer being returned
   4604             // here is client's buffer, return it back to client
   4605             if (m_pCallbacks.EmptyBufferDone && buffer) {
   4606                 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
   4607                 DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
   4608             }
   4609         }
   4610     } else if (m_pCallbacks.EmptyBufferDone) {
   4611         m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
   4612     }
   4613     return OMX_ErrorNone;
   4614 }
   4615 
   4616 void omx_video::complete_pending_buffer_done_cbs()
   4617 {
   4618     unsigned long p1;
   4619     unsigned long p2;
   4620     unsigned long ident;
   4621     omx_cmd_queue tmp_q, pending_bd_q;
   4622     pthread_mutex_lock(&m_lock);
   4623     // pop all pending GENERATE FDB from ftb queue
   4624     while (m_ftb_q.m_size) {
   4625         m_ftb_q.pop_entry(&p1,&p2,&ident);
   4626         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   4627             pending_bd_q.insert_entry(p1,p2,ident);
   4628         } else {
   4629             tmp_q.insert_entry(p1,p2,ident);
   4630         }
   4631     }
   4632     //return all non GENERATE FDB to ftb queue
   4633     while (tmp_q.m_size) {
   4634         tmp_q.pop_entry(&p1,&p2,&ident);
   4635         m_ftb_q.insert_entry(p1,p2,ident);
   4636     }
   4637     // pop all pending GENERATE EDB from etb queue
   4638     while (m_etb_q.m_size) {
   4639         m_etb_q.pop_entry(&p1,&p2,&ident);
   4640         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   4641             pending_bd_q.insert_entry(p1,p2,ident);
   4642         } else {
   4643             tmp_q.insert_entry(p1,p2,ident);
   4644         }
   4645     }
   4646     //return all non GENERATE FDB to etb queue
   4647     while (tmp_q.m_size) {
   4648         tmp_q.pop_entry(&p1,&p2,&ident);
   4649         m_etb_q.insert_entry(p1,p2,ident);
   4650     }
   4651     pthread_mutex_unlock(&m_lock);
   4652     // process all pending buffer dones
   4653     while (pending_bd_q.m_size) {
   4654         pending_bd_q.pop_entry(&p1,&p2,&ident);
   4655         switch (ident) {
   4656             case OMX_COMPONENT_GENERATE_EBD:
   4657                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   4658                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
   4659                     omx_report_error ();
   4660                 }
   4661                 break;
   4662 
   4663             case OMX_COMPONENT_GENERATE_FBD:
   4664                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   4665                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
   4666                     omx_report_error ();
   4667                 }
   4668                 break;
   4669         }
   4670     }
   4671 }
   4672 
   4673 #ifdef MAX_RES_720P
   4674 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   4675 {
   4676     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4677     if (!profileLevelType)
   4678         return OMX_ErrorBadParameter;
   4679 
   4680     if (profileLevelType->nPortIndex == 1) {
   4681         if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
   4682             if (profileLevelType->nProfileIndex == 0) {
   4683                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   4684                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
   4685             } else if (profileLevelType->nProfileIndex == 1) {
   4686                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   4687                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
   4688             } else if (profileLevelType->nProfileIndex == 2) {
   4689                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   4690                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
   4691             } else {
   4692                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
   4693                         (int)profileLevelType->nProfileIndex);
   4694                 eRet = OMX_ErrorNoMore;
   4695             }
   4696         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) {
   4697             if (profileLevelType->nProfileIndex == 0) {
   4698                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   4699                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   4700             } else {
   4701                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex);
   4702                 eRet = OMX_ErrorNoMore;
   4703             }
   4704         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
   4705             if (profileLevelType->nProfileIndex == 0) {
   4706                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   4707                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4708             } else if (profileLevelType->nProfileIndex == 1) {
   4709                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   4710                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4711             } else {
   4712                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex);
   4713                 eRet = OMX_ErrorNoMore;
   4714             }
   4715         }
   4716     } else {
   4717         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %d", (int)profileLevelType->nPortIndex);
   4718         eRet = OMX_ErrorBadPortIndex;
   4719     }
   4720     DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d",
   4721             (int)profileLevelType->eProfile, (int)profileLevelType->eLevel);
   4722     return eRet;
   4723 }
   4724 #endif
   4725 
   4726 #ifdef MAX_RES_1080P
   4727 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   4728 {
   4729     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4730     if (!profileLevelType)
   4731         return OMX_ErrorBadParameter;
   4732 
   4733     if (profileLevelType->nPortIndex == 1) {
   4734         if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
   4735 #if defined _MSM8974_ && !defined _MSM8226_
   4736             if (profileLevelType->nProfileIndex == 0) {
   4737                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   4738                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4739             } else if (profileLevelType->nProfileIndex == 1) {
   4740                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   4741                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4742             } else if (profileLevelType->nProfileIndex == 2) {
   4743                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   4744                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4745             } else if (profileLevelType->nProfileIndex == 3) {
   4746                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
   4747                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4748             } else if (profileLevelType->nProfileIndex == 4) {
   4749                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   4750                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4751             } else if (profileLevelType->nProfileIndex == 5) {
   4752                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
   4753                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4754             } else if (profileLevelType->nProfileIndex == 6) {
   4755                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
   4756                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4757             } else {
   4758                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   4759                         (unsigned int)profileLevelType->nProfileIndex);
   4760                 eRet = OMX_ErrorNoMore;
   4761             }
   4762 #else
   4763             if (profileLevelType->nProfileIndex == 0) {
   4764                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   4765                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4766 
   4767             } else if (profileLevelType->nProfileIndex == 1) {
   4768                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   4769                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4770             } else if (profileLevelType->nProfileIndex == 2) {
   4771                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   4772                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4773 #ifdef _MSM8226_
   4774             } else if (profileLevelType->nProfileIndex == 3) {
   4775                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
   4776                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4777             } else if (profileLevelType->nProfileIndex == 4) {
   4778                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   4779                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4780 #endif
   4781             } else {
   4782                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
   4783                         (int)profileLevelType->nProfileIndex);
   4784                 eRet = OMX_ErrorNoMore;
   4785             }
   4786 #endif
   4787         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) {
   4788             if (profileLevelType->nProfileIndex == 0) {
   4789                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   4790                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   4791             } else {
   4792                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex);
   4793                 eRet = OMX_ErrorNoMore;
   4794             }
   4795         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
   4796             if (profileLevelType->nProfileIndex == 0) {
   4797                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   4798                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4799             } else if (profileLevelType->nProfileIndex == 1) {
   4800                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   4801                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4802             } else {
   4803                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex);
   4804                 eRet = OMX_ErrorNoMore;
   4805             }
   4806         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) {
   4807             if (profileLevelType->nProfileIndex == 0) {
   4808                 profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
   4809                 profileLevelType->eLevel   = OMX_VIDEO_VP8Level_Version0;
   4810             } else if (profileLevelType->nProfileIndex == 1) {
   4811                 profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
   4812                 profileLevelType->eLevel   = OMX_VIDEO_VP8Level_Version1;
   4813             } else {
   4814                 DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   4815                 (unsigned int)profileLevelType->nProfileIndex);
   4816                 eRet = OMX_ErrorNoMore;
   4817             }
   4818         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC) {
   4819             if (profileLevelType->nProfileIndex == 0) {
   4820                 profileLevelType->eProfile =  OMX_VIDEO_HEVCProfileMain;
   4821                 profileLevelType->eLevel   =  OMX_VIDEO_HEVCMainTierLevel51;
   4822             } else {
   4823                 DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   4824                 (unsigned int)profileLevelType->nProfileIndex);
   4825                 eRet = OMX_ErrorNoMore;
   4826             }
   4827         } else {
   4828             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore");
   4829             eRet = OMX_ErrorNoMore;
   4830         }
   4831     } else {
   4832         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
   4833         eRet = OMX_ErrorBadPortIndex;
   4834     }
   4835     DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
   4836             (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
   4837     return eRet;
   4838 }
   4839 #endif
   4840 
   4841 #ifdef USE_ION
   4842 int omx_video::alloc_map_ion_memory(int size,
   4843         struct ion_allocation_data *alloc_data,
   4844         struct ion_fd_data *fd_data,int flag)
   4845 {
   4846     struct venc_ion buf_ion_info;
   4847     int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
   4848     if (size <=0 || !alloc_data || !fd_data) {
   4849         DEBUG_PRINT_ERROR("Invalid input to alloc_map_ion_memory");
   4850         return -EINVAL;
   4851     }
   4852 
   4853     ion_dev_flags = O_RDONLY;
   4854     ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
   4855     if (ion_device_fd < 0) {
   4856         DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed");
   4857         return ion_device_fd;
   4858     }
   4859 
   4860     if(secure_session) {
   4861         alloc_data->len = (size + (SECURE_ALIGN - 1)) & ~(SECURE_ALIGN - 1);
   4862         alloc_data->align = SECURE_ALIGN;
   4863         alloc_data->flags = flag;
   4864         alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
   4865         if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
   4866             alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
   4867         }
   4868         DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u align %u flags %x",
   4869                 (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
   4870                 alloc_data->flags);
   4871     } else {
   4872         alloc_data->len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
   4873         alloc_data->align = SZ_4K;
   4874         alloc_data->flags = (flag & ION_FLAG_CACHED ? ION_FLAG_CACHED : 0);
   4875 #ifdef MAX_RES_720P
   4876         alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
   4877 #else
   4878         alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
   4879                                  ION_HEAP(ION_IOMMU_HEAP_ID));
   4880 #endif
   4881         DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u align %u flags %x",
   4882                 (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
   4883                 alloc_data->flags);
   4884     }
   4885 
   4886     rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
   4887     if (rc || !alloc_data->handle) {
   4888         DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc);
   4889         alloc_data->handle = 0;
   4890         close(ion_device_fd);
   4891         ion_device_fd = -1;
   4892         return ion_device_fd;
   4893     }
   4894     fd_data->handle = alloc_data->handle;
   4895     rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
   4896     if (rc) {
   4897         DEBUG_PRINT_ERROR("ION MAP failed ");
   4898         buf_ion_info.ion_alloc_data = *alloc_data;
   4899         buf_ion_info.ion_device_fd = ion_device_fd;
   4900         buf_ion_info.fd_ion_data = *fd_data;
   4901         free_ion_memory(&buf_ion_info);
   4902         fd_data->fd =-1;
   4903         ion_device_fd =-1;
   4904     }
   4905     return ion_device_fd;
   4906 }
   4907 
   4908 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
   4909 {
   4910     if (!buf_ion_info) {
   4911         DEBUG_PRINT_ERROR("Invalid input to free_ion_memory");
   4912         return;
   4913     }
   4914     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   4915                 &buf_ion_info->ion_alloc_data.handle)) {
   4916         DEBUG_PRINT_ERROR("ION free failed ");
   4917         return;
   4918     }
   4919     close(buf_ion_info->ion_device_fd);
   4920     buf_ion_info->ion_alloc_data.handle = 0;
   4921     buf_ion_info->ion_device_fd = -1;
   4922     buf_ion_info->fd_ion_data.fd = -1;
   4923 }
   4924 #endif
   4925 
   4926 #ifdef _ANDROID_ICS_
   4927 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
   4928 {
   4929     if (buffer && meta_mode_enable) {
   4930         LEGACY_CAM_METADATA_TYPE *media_ptr;
   4931         struct pmem Input_pmem;
   4932         unsigned int index_pmem = 0;
   4933         bool meta_error = false;
   4934 
   4935         index_pmem = (buffer - m_inp_mem_ptr);
   4936         if (mUsesColorConversion &&
   4937                 (index_pmem < m_sInPortDef.nBufferCountActual)) {
   4938             if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) {
   4939                 DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed");
   4940             }
   4941         } else {
   4942             media_ptr = (LEGACY_CAM_METADATA_TYPE *) buffer->pBuffer;
   4943             if (media_ptr && media_ptr->meta_handle) {
   4944                 if (media_ptr->buffer_type == LEGACY_CAM_SOURCE) {
   4945                     Input_pmem.buffer = media_ptr;
   4946                     Input_pmem.fd = MetaBufferUtil::getFdAt(media_ptr->meta_handle, 0);
   4947                     int size = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_SIZE);
   4948                     int offset = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
   4949                     if (Input_pmem.fd < 0 || size < 0 || offset < 0) {
   4950                         DEBUG_PRINT_ERROR("Invalid meta buffer");
   4951                         meta_error = true;
   4952                     }
   4953                     Input_pmem.size = size;
   4954                     Input_pmem.offset = offset;
   4955                     DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
   4956                             Input_pmem.offset,
   4957                             Input_pmem.size);
   4958                 } else if (media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
   4959                     VideoGrallocMetadata *media_ptr = (VideoGrallocMetadata *)buffer->pBuffer;
   4960                     private_handle_t *handle = (private_handle_t *)media_ptr->pHandle;
   4961                     Input_pmem.buffer = media_ptr;
   4962                     Input_pmem.fd = handle->fd;
   4963                     Input_pmem.offset = 0;
   4964                     Input_pmem.size = handle->size;
   4965                 } else {
   4966                     meta_error = true;
   4967                 }
   4968                 if (!meta_error)
   4969                     meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
   4970                 if (meta_error) {
   4971                     DEBUG_PRINT_HIGH("In batchmode or dev_free_buf failed, flush %d",
   4972                             input_flush_progress);
   4973                 }
   4974             }
   4975         }
   4976     }
   4977 }
   4978 #endif
   4979 omx_video::omx_c2d_conv::omx_c2d_conv()
   4980 {
   4981     c2dcc = NULL;
   4982     mLibHandle = NULL;
   4983     mConvertOpen = NULL;
   4984     mConvertClose = NULL;
   4985     src_format = NV12_128m;
   4986     pthread_mutex_init(&c_lock, NULL);
   4987 }
   4988 
   4989 bool omx_video::omx_c2d_conv::init()
   4990 {
   4991     bool status = true;
   4992     if (mLibHandle || mConvertOpen || mConvertClose) {
   4993         DEBUG_PRINT_ERROR("omx_c2d_conv::init called twice");
   4994         status = false;
   4995     }
   4996     if (status) {
   4997         mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY);
   4998         if (mLibHandle) {
   4999             mConvertOpen = (createC2DColorConverter_t *)
   5000                 dlsym(mLibHandle,"createC2DColorConverter");
   5001             mConvertClose = (destroyC2DColorConverter_t *)
   5002                 dlsym(mLibHandle,"destroyC2DColorConverter");
   5003             if (!mConvertOpen || !mConvertClose)
   5004                 status = false;
   5005         } else
   5006             status = false;
   5007     }
   5008     if (!status && mLibHandle) {
   5009         dlclose(mLibHandle);
   5010         mLibHandle = NULL;
   5011         mConvertOpen = NULL;
   5012         mConvertClose = NULL;
   5013     }
   5014     return status;
   5015 }
   5016 
   5017 bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr,
   5018         int dest_fd, void *dest_base, void *dest_viraddr)
   5019 {
   5020     int result;
   5021     if (!src_viraddr || !dest_viraddr || !c2dcc || !src_base || !dest_base) {
   5022         DEBUG_PRINT_ERROR("Invalid arguments omx_c2d_conv::convert");
   5023         return false;
   5024     }
   5025     pthread_mutex_lock(&c_lock);
   5026     result =  c2dcc->convertC2D(src_fd, src_base, src_viraddr,
   5027             dest_fd, dest_base, dest_viraddr);
   5028     pthread_mutex_unlock(&c_lock);
   5029     DEBUG_PRINT_LOW("Color convert status %d",result);
   5030     return ((result < 0)?false:true);
   5031 }
   5032 
   5033 bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width,
   5034         ColorConvertFormat src, ColorConvertFormat dest, unsigned int src_stride,
   5035         unsigned int flags)
   5036 {
   5037     bool status = false;
   5038     pthread_mutex_lock(&c_lock);
   5039     if (!c2dcc) {
   5040         c2dcc = mConvertOpen(width, height, width, height,
   5041                 src, dest, flags, src_stride);
   5042         if (c2dcc) {
   5043             src_format = src;
   5044             status = true;
   5045         } else
   5046             DEBUG_PRINT_ERROR("mConvertOpen failed");
   5047     }
   5048     pthread_mutex_unlock(&c_lock);
   5049     return status;
   5050 }
   5051 
   5052 void omx_video::omx_c2d_conv::close()
   5053 {
   5054     if (mLibHandle) {
   5055         pthread_mutex_lock(&c_lock);
   5056         if (mConvertClose && c2dcc)
   5057             mConvertClose(c2dcc);
   5058         pthread_mutex_unlock(&c_lock);
   5059         c2dcc = NULL;
   5060     }
   5061 }
   5062 omx_video::omx_c2d_conv::~omx_c2d_conv()
   5063 {
   5064     DEBUG_PRINT_HIGH("Destroy C2D instance");
   5065     if (mLibHandle) {
   5066         if (mConvertClose && c2dcc) {
   5067             pthread_mutex_lock(&c_lock);
   5068             mConvertClose(c2dcc);
   5069             pthread_mutex_unlock(&c_lock);
   5070         }
   5071         dlclose(mLibHandle);
   5072     }
   5073     c2dcc = NULL;
   5074     mLibHandle = NULL;
   5075     mConvertOpen = NULL;
   5076     mConvertClose = NULL;
   5077     pthread_mutex_destroy(&c_lock);
   5078 }
   5079 
   5080 int omx_video::omx_c2d_conv::get_src_format()
   5081 {
   5082     int format = -1;
   5083     if (src_format == NV12_128m) {
   5084         format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;
   5085     } else if (src_format == RGBA8888) {
   5086         format = HAL_PIXEL_FORMAT_RGBA_8888;
   5087     }
   5088     return format;
   5089 }
   5090 
   5091 bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size)
   5092 {
   5093     int cret = 0;
   5094     bool ret = false;
   5095     C2DBuffReq bufferreq;
   5096     if (c2dcc) {
   5097         bufferreq.size = 0;
   5098         pthread_mutex_lock(&c_lock);
   5099         cret = c2dcc->getBuffReq(port,&bufferreq);
   5100         pthread_mutex_unlock(&c_lock);
   5101         DEBUG_PRINT_LOW("Status of getbuffer is %d", cret);
   5102         ret = (cret)?false:true;
   5103         buf_size = bufferreq.size;
   5104     }
   5105     return ret;
   5106 }
   5107 
   5108 bool omx_video::is_conv_needed(int hal_fmt, int hal_flags)
   5109 {
   5110     bool bRet = false;
   5111 
   5112     if (!strncmp(m_platform, "msm8996", 7)) {
   5113         bRet = hal_fmt == HAL_PIXEL_FORMAT_RGBA_8888 &&
   5114             !(hal_flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED);
   5115     } else {
   5116         bRet = hal_fmt == HAL_PIXEL_FORMAT_RGBA_8888;
   5117     }
   5118 
   5119 #ifdef _HW_RGBA
   5120     bRet = false;
   5121 #endif
   5122     DEBUG_PRINT_LOW("RGBA conversion %s", bRet ? "Needed":"Not-Needed");
   5123     return bRet;
   5124 }
   5125 
   5126 void omx_video::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
   5127     DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
   5128             prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
   5129 }
   5130 
   5131 OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
   5132         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5133 {
   5134     VIDC_TRACE_NAME_LOW("ETB-Opaque");
   5135     unsigned nBufIndex = 0;
   5136     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5137     VideoGrallocMetadata *media_buffer; // This method primarily assumes gralloc-metadata
   5138     private_handle_t *handle = NULL;
   5139     DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer);
   5140 
   5141     if (buffer == NULL) {
   5142         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer);
   5143         return OMX_ErrorBadParameter;
   5144     }
   5145 
   5146     if (!dev_buffer_ready_to_queue(buffer)) {
   5147         DEBUG_PRINT_HIGH("Info: ETBProxyA: buffer[%p] is deffered", buffer);
   5148         return OMX_ErrorNone;
   5149     }
   5150 
   5151     nBufIndex = buffer - meta_buffer_hdr;
   5152     if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
   5153         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u",
   5154                 nBufIndex);
   5155         return OMX_ErrorBadParameter;
   5156     }
   5157 
   5158     media_buffer = (VideoGrallocMetadata *)buffer->pBuffer;
   5159     if (!media_buffer) {
   5160         DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
   5161         return OMX_ErrorBadParameter;
   5162     }
   5163     if ((media_buffer->eType == LEGACY_CAM_SOURCE)
   5164             && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
   5165         DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
   5166                 buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
   5167         return OMX_ErrorBadParameter;
   5168     }
   5169 
   5170     if (media_buffer && media_buffer->eType == LEGACY_CAM_SOURCE) {
   5171         return empty_this_buffer_proxy(hComp, buffer);
   5172     }
   5173 
   5174     if ((!media_buffer || !media_buffer->pHandle || media_buffer->eType != kMetadataBufferTypeGrallocSource) &&
   5175             !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   5176         DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
   5177             media_buffer);
   5178         m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
   5179         return OMX_ErrorBadParameter;
   5180     } else if (media_buffer) {
   5181         handle = (private_handle_t *)media_buffer->pHandle;
   5182     }
   5183 
   5184     /*Enable following code once private handle color format is
   5185       updated correctly*/
   5186 
   5187     if (buffer->nFilledLen > 0 && handle) {
   5188         if (c2d_opened && handle->format != c2d_conv.get_src_format()) {
   5189             c2d_conv.close();
   5190             c2d_opened = false;
   5191         }
   5192 
   5193         if (!c2d_opened) {
   5194             mUsesColorConversion = is_conv_needed(handle->format, handle->flags);
   5195             if (mUsesColorConversion) {
   5196                 DEBUG_PRINT_INFO("open Color conv forW: %u, H: %u",
   5197                         (unsigned int)m_sInPortDef.format.video.nFrameWidth,
   5198                         (unsigned int)m_sInPortDef.format.video.nFrameHeight);
   5199                 if (!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
   5200                             m_sInPortDef.format.video.nFrameWidth,
   5201                             RGBA8888, NV12_128m, handle->width, handle->flags)) {
   5202                     m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
   5203                     DEBUG_PRINT_ERROR("Color conv open failed");
   5204                     return OMX_ErrorBadParameter;
   5205                 }
   5206                 c2d_opened = true;
   5207 #ifdef _MSM8974_
   5208                 if (!dev_set_format(NV12_128m))
   5209                     DEBUG_PRINT_ERROR("cannot set color format");
   5210 
   5211                 dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
   5212                     &m_sInPortDef.nBufferCountActual,
   5213                     &m_sInPortDef.nBufferSize,
   5214                     m_sInPortDef.nPortIndex);
   5215 
   5216 #endif
   5217             }
   5218         }
   5219     }
   5220     if (input_flush_progress == true) {
   5221         m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
   5222         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Input flush in progress");
   5223         return OMX_ErrorNone;
   5224     }
   5225 
   5226     if (!psource_frame) {
   5227         psource_frame = buffer;
   5228         ret = push_input_buffer(hComp);
   5229     } else {
   5230         if (!m_opq_meta_q.insert_entry((unsigned long)buffer,0,0)) {
   5231             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full");
   5232             m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
   5233             ret = OMX_ErrorBadParameter;
   5234         }
   5235     }
   5236     return ret;
   5237 }
   5238 
   5239 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp,
   5240         struct pmem &Input_pmem_info)
   5241 {
   5242 
   5243     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5244     unsigned long address = 0,p2,id;
   5245 
   5246     DEBUG_PRINT_LOW("In queue Meta Buffer");
   5247     if (!psource_frame || !pdest_frame) {
   5248         DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
   5249         return OMX_ErrorBadParameter;
   5250     }
   5251 
   5252     if (psource_frame->nFilledLen > 0) {
   5253         if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
   5254             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
   5255             post_event ((unsigned long)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
   5256             ret = OMX_ErrorBadParameter;
   5257         }
   5258     }
   5259 
   5260     if (ret == OMX_ErrorNone)
   5261         ret = empty_this_buffer_proxy(hComp,psource_frame);
   5262 
   5263     if (ret == OMX_ErrorNone) {
   5264         psource_frame = NULL;
   5265         if (!psource_frame && m_opq_meta_q.m_size) {
   5266             m_opq_meta_q.pop_entry(&address,&p2,&id);
   5267             psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
   5268         }
   5269     } else {
   5270         // there has been an error and source frame has been scheduled for an EBD
   5271         psource_frame = NULL;
   5272     }
   5273     return ret;
   5274 }
   5275 
   5276 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
   5277         struct pmem &Input_pmem_info,unsigned long &index)
   5278 {
   5279 
   5280     unsigned char *uva;
   5281     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5282     unsigned long address = 0,p2,id;
   5283 
   5284     DEBUG_PRINT_LOW("In Convert and queue Meta Buffer");
   5285     if (!psource_frame || !pdest_frame) {
   5286         DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
   5287         return OMX_ErrorBadParameter;
   5288     }
   5289     if (secure_session) {
   5290         DEBUG_PRINT_ERROR("cannot convert buffer during secure session");
   5291         return OMX_ErrorInvalidState;
   5292     }
   5293 
   5294     if (!psource_frame->nFilledLen) {
   5295         if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   5296             pdest_frame->nFilledLen = psource_frame->nFilledLen;
   5297             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   5298             pdest_frame->nFlags = psource_frame->nFlags;
   5299             DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer "
   5300                     "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen);
   5301         } else {
   5302             pdest_frame->nOffset = 0;
   5303             pdest_frame->nFilledLen = 0;
   5304             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   5305             pdest_frame->nFlags = psource_frame->nFlags;
   5306             DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
   5307                     pdest_frame, (unsigned int)pdest_frame->nFilledLen);
   5308         }
   5309     } else {
   5310         unsigned int input_buf_size = 0;
   5311         if (!c2d_conv.get_buffer_size(C2D_INPUT, input_buf_size)) {
   5312             DEBUG_PRINT_ERROR("convert_queue_buffer: failed to get C2D i/p buf-size!");
   5313             return OMX_ErrorBadParameter;
   5314         } else if (Input_pmem_info.size < input_buf_size) {
   5315             DEBUG_PRINT_ERROR("convert_queue_buffer: insufficient handle size(%u) v/s min(%u)",
   5316                     Input_pmem_info.size, input_buf_size);
   5317             return OMX_ErrorBadParameter;
   5318         }
   5319         uva = (unsigned char *)mmap(NULL, Input_pmem_info.size,
   5320                 PROT_READ|PROT_WRITE,
   5321                 MAP_SHARED,Input_pmem_info.fd,0);
   5322         if (uva == MAP_FAILED) {
   5323             DEBUG_PRINT_ERROR("convert_queue_buffer: failed to map handle fd(%d) size(%u)",
   5324                     Input_pmem_info.fd, Input_pmem_info.size);
   5325             ret = OMX_ErrorBadParameter;
   5326         } else {
   5327             if (!c2d_conv.convert(Input_pmem_info.fd, uva, uva,
   5328                         m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) {
   5329                 DEBUG_PRINT_ERROR("Color Conversion failed");
   5330                 ret = OMX_ErrorBadParameter;
   5331             } else {
   5332                 unsigned int buf_size = 0;
   5333                 if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size))
   5334                     ret = OMX_ErrorBadParameter;
   5335                 else {
   5336                     pdest_frame->nOffset = 0;
   5337                     pdest_frame->nFilledLen = buf_size;
   5338                     pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   5339                     pdest_frame->nFlags = psource_frame->nFlags;
   5340                     DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
   5341                             pdest_frame, (unsigned int)pdest_frame->nFilledLen);
   5342                 }
   5343             }
   5344             munmap(uva,Input_pmem_info.size);
   5345         }
   5346     }
   5347     if (dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
   5348         DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
   5349         post_event ((unsigned long)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
   5350         ret = OMX_ErrorBadParameter;
   5351     }
   5352     if (ret == OMX_ErrorNone)
   5353         ret = empty_this_buffer_proxy(hComp,pdest_frame);
   5354     if (ret == OMX_ErrorNone) {
   5355         m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
   5356         psource_frame = NULL;
   5357         pdest_frame = NULL;
   5358         if (!psource_frame && m_opq_meta_q.m_size) {
   5359             m_opq_meta_q.pop_entry(&address,&p2,&id);
   5360             psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
   5361         }
   5362         if (!pdest_frame && m_opq_pmem_q.m_size) {
   5363             m_opq_pmem_q.pop_entry(&address,&p2,&id);
   5364             pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
   5365             DEBUG_PRINT_LOW("pdest_frame pop address is %p",pdest_frame);
   5366         }
   5367     } else {
   5368         // there has been an error and source frame has been scheduled for an EBD
   5369         psource_frame = NULL;
   5370     }
   5371     return ret;
   5372 }
   5373 
   5374 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
   5375 {
   5376     unsigned long address = 0,p2,id, index = 0;
   5377     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5378 
   5379     DEBUG_PRINT_LOW("In push input buffer");
   5380     if (!psource_frame && m_opq_meta_q.m_size) {
   5381         m_opq_meta_q.pop_entry(&address,&p2,&id);
   5382         psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
   5383     }
   5384     if (!pdest_frame && m_opq_pmem_q.m_size) {
   5385         m_opq_pmem_q.pop_entry(&address,&p2,&id);
   5386         pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
   5387     }
   5388     while (psource_frame != NULL && pdest_frame != NULL &&
   5389             ret == OMX_ErrorNone) {
   5390         struct pmem Input_pmem_info;
   5391         LEGACY_CAM_METADATA_TYPE *media_buffer;
   5392         index = pdest_frame - m_inp_mem_ptr;
   5393         if (index >= m_sInPortDef.nBufferCountActual) {
   5394             DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u",
   5395                     (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual);
   5396             return OMX_ErrorBadParameter;
   5397         }
   5398 
   5399         //Meta-Buffer with empty filled-length can contain garbage handle
   5400         //Some clients queue such buffers to signal EOS. Handle this case
   5401         // separately by queueing an intermediate color-conversion buffer
   5402         // and propagate the EOS.
   5403         if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   5404             return push_empty_eos_buffer(hComp);
   5405         }
   5406         media_buffer = (LEGACY_CAM_METADATA_TYPE *)psource_frame->pBuffer;
   5407         /*Will enable to verify camcorder in current TIPS can be removed*/
   5408         if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
   5409             Input_pmem_info.buffer = media_buffer;
   5410             Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
   5411             Input_pmem_info.offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
   5412             Input_pmem_info.size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
   5413             m_graphicbuffer_size = Input_pmem_info.size;
   5414             DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
   5415                     Input_pmem_info.offset,
   5416                     Input_pmem_info.size);
   5417             ret = queue_meta_buffer(hComp,Input_pmem_info);
   5418         } else {
   5419             VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)psource_frame->pBuffer;
   5420             private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
   5421             Input_pmem_info.buffer = media_buffer;
   5422             Input_pmem_info.fd = handle->fd;
   5423             Input_pmem_info.offset = 0;
   5424             Input_pmem_info.size = handle->size;
   5425             m_graphicbuffer_size = Input_pmem_info.size;
   5426             if (is_conv_needed(handle->format, handle->flags))
   5427                 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
   5428             else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
   5429                     handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
   5430                     handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
   5431                     handle->format == HAL_PIXEL_FORMAT_RGBA_8888 ||
   5432                     handle->format == QOMX_COLOR_Format32bitRGBA8888Compressed)
   5433                 ret = queue_meta_buffer(hComp,Input_pmem_info);
   5434             else
   5435                 ret = OMX_ErrorBadParameter;
   5436         }
   5437     }
   5438     return ret;
   5439 }
   5440 
   5441 OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp) {
   5442     OMX_BUFFERHEADERTYPE* opqBuf = NULL;
   5443     OMX_ERRORTYPE retVal = OMX_ErrorNone;
   5444     unsigned index = 0;
   5445 
   5446     DEBUG_PRINT_LOW("In push empty eos buffer");
   5447     do {
   5448         if (mUsesColorConversion) {
   5449             if (pdest_frame) {
   5450                 //[1] use a checked out conversion buffer, if one is available
   5451                 opqBuf = pdest_frame;
   5452                 pdest_frame = NULL;
   5453             } else if (m_opq_pmem_q.m_size) {
   5454                 //[2] else pop out one from the queue, if available
   5455                 unsigned long address = 0, p2, id;
   5456                 m_opq_pmem_q.pop_entry(&address,&p2,&id);
   5457                 opqBuf = (OMX_BUFFERHEADERTYPE* ) address;
   5458             }
   5459             index = opqBuf - m_inp_mem_ptr;
   5460         } else {
   5461             opqBuf = (OMX_BUFFERHEADERTYPE* ) psource_frame;
   5462             index = opqBuf - meta_buffer_hdr;
   5463         }
   5464 
   5465         if (!opqBuf || index >= m_sInPortDef.nBufferCountActual) {
   5466             DEBUG_PRINT_ERROR("push_empty_eos_buffer: Could not find a "
   5467                     "color-conversion buffer to queue ! defer until available");
   5468             //[3] else, returning back will defer calling this function again
   5469             //until a conversion buffer is returned by the encoder and also
   5470             //hold on to the client's buffer
   5471             return OMX_ErrorNone;
   5472         }
   5473         struct pmem Input_pmem_info;
   5474         Input_pmem_info.buffer = opqBuf;
   5475         Input_pmem_info.fd = m_pInput_pmem[index].fd;
   5476         Input_pmem_info.offset = 0;
   5477         Input_pmem_info.size = m_pInput_pmem[index].size;
   5478 
   5479         if (dev_use_buf(&Input_pmem_info, PORT_INDEX_IN, 0) != true) {
   5480             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf for empty eos buffer");
   5481             retVal = OMX_ErrorBadParameter;
   5482             break;
   5483         }
   5484 
   5485         //Queue with null pBuffer, as pBuffer in client's hdr can be junk
   5486         //Clone the color-conversion buffer to avoid overwriting original buffer
   5487         OMX_BUFFERHEADERTYPE emptyEosBufHdr;
   5488         memcpy(&emptyEosBufHdr, opqBuf, sizeof(OMX_BUFFERHEADERTYPE));
   5489         emptyEosBufHdr.nFilledLen = 0;
   5490         emptyEosBufHdr.nTimeStamp = psource_frame->nTimeStamp;
   5491         emptyEosBufHdr.nFlags = psource_frame->nFlags;
   5492         emptyEosBufHdr.pBuffer = NULL;
   5493         if (!mUsesColorConversion)
   5494             emptyEosBufHdr.nAllocLen =
   5495             m_graphicbuffer_size ? m_graphicbuffer_size : m_sInPortDef.nBufferSize;
   5496 
   5497         if (dev_empty_buf(&emptyEosBufHdr, 0, index, m_pInput_pmem[index].fd) != true) {
   5498             DEBUG_PRINT_ERROR("ERROR: in dev_empty_buf for empty eos buffer");
   5499             dev_free_buf(&Input_pmem_info, PORT_INDEX_IN);
   5500             retVal = OMX_ErrorBadParameter;
   5501             break;
   5502         }
   5503         mEmptyEosBuffer = opqBuf;
   5504     } while(false);
   5505 
   5506     //return client's buffer regardless since intermediate color-conversion
   5507     //buffer is sent to the the encoder
   5508     m_pCallbacks.EmptyBufferDone(hComp, m_app_data, psource_frame);
   5509     psource_frame = NULL;
   5510     --pending_input_buffers;
   5511     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   5512     return retVal;
   5513 }
   5514 
   5515 // no code beyond this !
   5516 
   5517 // inline import of vendor extensions implementation
   5518 #include "omx_video_extensions.hpp"
   5519