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