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