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