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_IndexParamVideoSliceFMO:
   1914         default:
   1915             {
   1916                 DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x", paramIndex);
   1917                 eRet =OMX_ErrorUnsupportedIndex;
   1918                 break;
   1919             }
   1920 
   1921     }
   1922 
   1923     return eRet;
   1924 
   1925 }
   1926 /* ======================================================================
   1927    FUNCTION
   1928    omx_video::GetConfig
   1929 
   1930    DESCRIPTION
   1931    OMX Get Config Method implementation.
   1932 
   1933    PARAMETERS
   1934    <TBD>.
   1935 
   1936    RETURN VALUE
   1937    OMX Error None if successful.
   1938 
   1939    ========================================================================== */
   1940 OMX_ERRORTYPE  omx_video::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   1941         OMX_IN OMX_INDEXTYPE configIndex,
   1942         OMX_INOUT OMX_PTR     configData)
   1943 {
   1944     (void)hComp;
   1945     ////////////////////////////////////////////////////////////////
   1946     // Supported Config Index           Type
   1947     // =============================================================
   1948     // OMX_IndexConfigVideoBitrate      OMX_VIDEO_CONFIG_BITRATETYPE
   1949     // OMX_IndexConfigVideoFramerate    OMX_CONFIG_FRAMERATETYPE
   1950     // OMX_IndexConfigCommonRotate      OMX_CONFIG_ROTATIONTYPE
   1951     ////////////////////////////////////////////////////////////////
   1952 
   1953     if (configData == NULL) {
   1954         DEBUG_PRINT_ERROR("ERROR: param is null");
   1955         return OMX_ErrorBadParameter;
   1956     }
   1957 
   1958     if (m_state == OMX_StateInvalid) {
   1959         DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
   1960         return OMX_ErrorIncorrectStateOperation;
   1961     }
   1962 
   1963     //@todo need to validate params
   1964     switch ((int)configIndex) {
   1965         case OMX_IndexConfigVideoBitrate:
   1966             {
   1967                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE);
   1968                 OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
   1969                 memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
   1970                 break;
   1971             }
   1972         case OMX_IndexConfigVideoFramerate:
   1973             {
   1974                 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE);
   1975                 OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
   1976                 memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
   1977                 break;
   1978             }
   1979         case OMX_IndexConfigCommonRotate:
   1980             {
   1981                 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE);
   1982                 OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
   1983                 memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
   1984                 break;
   1985             }
   1986         case QOMX_IndexConfigVideoIntraperiod:
   1987             {
   1988                 DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod");
   1989                 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE);
   1990                 QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
   1991                 memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
   1992                 break;
   1993             }
   1994         case OMX_IndexConfigVideoAVCIntraPeriod:
   1995             {
   1996                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD);
   1997                 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam =
   1998                     reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData);
   1999                 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod");
   2000                 memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod));
   2001                 break;
   2002             }
   2003         case OMX_IndexConfigCommonDeinterlace:
   2004             {
   2005                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE);
   2006                 OMX_VIDEO_CONFIG_DEINTERLACE *pParam =
   2007                     reinterpret_cast<OMX_VIDEO_CONFIG_DEINTERLACE*>(configData);
   2008                 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigCommonDeinterlace");
   2009                 memcpy(pParam, &m_sConfigDeinterlace, sizeof(m_sConfigDeinterlace));
   2010                 break;
   2011             }
   2012        case OMX_IndexConfigVideoVp8ReferenceFrame:
   2013            {
   2014                 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE);
   2015                OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam =
   2016                    reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData);
   2017                DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame");
   2018                memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame));
   2019                break;
   2020            }
   2021         case OMX_QcomIndexConfigPerfLevel:
   2022             {
   2023                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
   2024                 OMX_U32 perflevel;
   2025                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam =
   2026                     reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData);
   2027                 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel");
   2028                 if (!dev_get_performance_level(&perflevel)) {
   2029                     DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
   2030                         pParam->ePerfLevel);
   2031                 } else {
   2032                     pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
   2033                 }
   2034                 break;
   2035             }
   2036       case OMX_IndexConfigAndroidIntraRefresh:
   2037            {
   2038                VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE);
   2039                OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam =
   2040                    reinterpret_cast<OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*>(configData);
   2041                DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidIntraRefresh");
   2042                memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh));
   2043                break;
   2044            }
   2045         default:
   2046             DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
   2047             return OMX_ErrorUnsupportedIndex;
   2048     }
   2049     return OMX_ErrorNone;
   2050 
   2051 }
   2052 
   2053 #define extn_equals(param, extn) (!strcmp(param, extn))
   2054 
   2055 /* ======================================================================
   2056    FUNCTION
   2057    omx_video::GetExtensionIndex
   2058 
   2059    DESCRIPTION
   2060    OMX GetExtensionIndex method implementaion.  <TBD>
   2061 
   2062    PARAMETERS
   2063    <TBD>.
   2064 
   2065    RETURN VALUE
   2066    OMX Error None if everything successful.
   2067 
   2068    ========================================================================== */
   2069 OMX_ERRORTYPE  omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   2070         OMX_IN OMX_STRING      paramName,
   2071         OMX_OUT OMX_INDEXTYPE* indexType)
   2072 {
   2073     (void)hComp;
   2074     if (m_state == OMX_StateInvalid) {
   2075         DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State");
   2076         return OMX_ErrorInvalidState;
   2077     }
   2078 #ifdef MAX_RES_1080P
   2079     if (extn_equals(paramName, "OMX.QCOM.index.param.SliceDeliveryMode")) {
   2080         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
   2081         return OMX_ErrorNone;
   2082     }
   2083 #endif
   2084 #ifdef _ANDROID_ICS_
   2085     if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
   2086         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
   2087         return OMX_ErrorNone;
   2088     }
   2089 #endif
   2090     if (extn_equals(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) {
   2091         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
   2092         return OMX_ErrorNone;
   2093     }
   2094     return OMX_ErrorNotImplemented;
   2095 }
   2096 
   2097 /* ======================================================================
   2098    FUNCTION
   2099    omx_video::GetState
   2100 
   2101    DESCRIPTION
   2102    Returns the state information back to the caller.<TBD>
   2103 
   2104    PARAMETERS
   2105    <TBD>.
   2106 
   2107    RETURN VALUE
   2108    Error None if everything is successful.
   2109    ========================================================================== */
   2110 OMX_ERRORTYPE  omx_video::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   2111         OMX_OUT OMX_STATETYPE* state)
   2112 {
   2113     (void)hComp;
   2114     *state = m_state;
   2115     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
   2116     return OMX_ErrorNone;
   2117 }
   2118 
   2119 /* ======================================================================
   2120    FUNCTION
   2121    omx_video::ComponentTunnelRequest
   2122 
   2123    DESCRIPTION
   2124    OMX Component Tunnel Request method implementation. <TBD>
   2125 
   2126    PARAMETERS
   2127    None.
   2128 
   2129    RETURN VALUE
   2130    OMX Error None if everything successful.
   2131 
   2132    ========================================================================== */
   2133 OMX_ERRORTYPE  omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
   2134         OMX_IN OMX_U32                        port,
   2135         OMX_IN OMX_HANDLETYPE        peerComponent,
   2136         OMX_IN OMX_U32                    peerPort,
   2137         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   2138 {
   2139     (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup;
   2140     DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented");
   2141     return OMX_ErrorNotImplemented;
   2142 }
   2143 
   2144 /* ======================================================================
   2145    FUNCTION
   2146    omx_video::UseInputBuffer
   2147 
   2148    DESCRIPTION
   2149    Helper function for Use buffer in the input pin
   2150 
   2151    PARAMETERS
   2152    None.
   2153 
   2154    RETURN VALUE
   2155    true/false
   2156 
   2157    ========================================================================== */
   2158 OMX_ERRORTYPE  omx_video::use_input_buffer(
   2159         OMX_IN OMX_HANDLETYPE            hComp,
   2160         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2161         OMX_IN OMX_U32                   port,
   2162         OMX_IN OMX_PTR                   appData,
   2163         OMX_IN OMX_U32                   bytes,
   2164         OMX_IN OMX_U8*                   buffer)
   2165 {
   2166     (void) hComp;
   2167     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2168 
   2169     unsigned   i = 0;
   2170     unsigned char *buf_addr = NULL;
   2171 
   2172     DEBUG_PRINT_HIGH("use_input_buffer: port = %u appData = %p bytes = %u buffer = %p",(unsigned int)port,appData,(unsigned int)bytes,buffer);
   2173     if (bytes != m_sInPortDef.nBufferSize) {
   2174         DEBUG_PRINT_ERROR("ERROR: use_input_buffer: Size Mismatch!! "
   2175                 "bytes[%u] != Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
   2176         return OMX_ErrorBadParameter;
   2177     }
   2178 
   2179     if (!m_inp_mem_ptr) {
   2180         input_use_buffer = true;
   2181         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   2182                         calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
   2183         if (m_inp_mem_ptr == NULL) {
   2184             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
   2185             return OMX_ErrorInsufficientResources;
   2186         }
   2187         DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
   2188 
   2189 
   2190         m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
   2191         if (m_pInput_pmem == NULL) {
   2192             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
   2193             return OMX_ErrorInsufficientResources;
   2194         }
   2195 #ifdef USE_ION
   2196         m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
   2197         if (m_pInput_ion == NULL) {
   2198             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
   2199             return OMX_ErrorInsufficientResources;
   2200         }
   2201 #endif
   2202 
   2203         for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   2204             m_pInput_pmem[i].fd = -1;
   2205 #ifdef USE_ION
   2206             m_pInput_ion[i].ion_device_fd =-1;
   2207             m_pInput_ion[i].fd_ion_data.fd =-1;
   2208             m_pInput_ion[i].ion_alloc_data.handle = 0;
   2209 #endif
   2210         }
   2211 
   2212     }
   2213 
   2214     for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   2215         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   2216             break;
   2217         }
   2218     }
   2219 
   2220     if (i < m_sInPortDef.nBufferCountActual) {
   2221 
   2222         *bufferHdr = (m_inp_mem_ptr + i);
   2223         BITMASK_SET(&m_inp_bm_count,i);
   2224 
   2225         (*bufferHdr)->pBuffer           = (OMX_U8 *)buffer;
   2226         (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   2227         (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
   2228         (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
   2229         (*bufferHdr)->pAppPrivate       = appData;
   2230         (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
   2231 
   2232         if (!m_use_input_pmem) {
   2233 #ifdef USE_ION
   2234 #ifdef _MSM8974_
   2235             m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   2236                     &m_pInput_ion[i].ion_alloc_data,
   2237                     &m_pInput_ion[i].fd_ion_data,0);
   2238 #else
   2239             m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   2240                     &m_pInput_ion[i].ion_alloc_data,
   2241                     &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED);
   2242 #endif
   2243             if (m_pInput_ion[i].ion_device_fd < 0) {
   2244                 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   2245                 return OMX_ErrorInsufficientResources;
   2246             }
   2247             m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
   2248 #else
   2249             m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2250             if (m_pInput_pmem[i].fd == 0) {
   2251                 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2252             }
   2253 
   2254             if (m_pInput_pmem[i] .fd < 0) {
   2255                 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
   2256                 return OMX_ErrorInsufficientResources;
   2257             }
   2258 #endif
   2259             m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   2260             m_pInput_pmem[i].offset = 0;
   2261 
   2262             m_pInput_pmem[i].buffer = NULL;
   2263             if(!secure_session) {
   2264                 m_pInput_pmem[i].buffer = (unsigned char *)mmap(
   2265                     NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
   2266                     MAP_SHARED,m_pInput_pmem[i].fd,0);
   2267 
   2268             if (m_pInput_pmem[i].buffer == MAP_FAILED) {
   2269                     DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
   2270                 m_pInput_pmem[i].buffer = NULL;
   2271                 close(m_pInput_pmem[i].fd);
   2272 #ifdef USE_ION
   2273                 free_ion_memory(&m_pInput_ion[i]);
   2274 #endif
   2275                 return OMX_ErrorInsufficientResources;
   2276             }
   2277             }
   2278 
   2279         } else {
   2280             OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
   2281             DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (unsigned)pParam->offset);
   2282 
   2283             if (pParam) {
   2284                 m_pInput_pmem[i].fd = pParam->pmem_fd;
   2285                 m_pInput_pmem[i].offset = pParam->offset;
   2286                 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   2287                 m_pInput_pmem[i].buffer = (unsigned char *)buffer;
   2288                 DEBUG_PRINT_LOW("DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
   2289                         (unsigned int)pParam->pmem_fd, (unsigned int)pParam->offset);
   2290             } else {
   2291                 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
   2292                 return OMX_ErrorBadParameter;
   2293             }
   2294         }
   2295 
   2296         DEBUG_PRINT_LOW("use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
   2297                 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
   2298         if ( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) {
   2299             DEBUG_PRINT_ERROR("ERROR: dev_use_buf() Failed for i/p buf");
   2300             return OMX_ErrorInsufficientResources;
   2301         }
   2302     } else {
   2303         DEBUG_PRINT_ERROR("ERROR: All buffers are already used, invalid use_buf call for "
   2304                 "index = %u", i);
   2305         eRet = OMX_ErrorInsufficientResources;
   2306     }
   2307 
   2308     return eRet;
   2309 }
   2310 
   2311 
   2312 
   2313 /* ======================================================================
   2314    FUNCTION
   2315    omx_video::UseOutputBuffer
   2316 
   2317    DESCRIPTION
   2318    Helper function for Use buffer in the input pin
   2319 
   2320    PARAMETERS
   2321    None.
   2322 
   2323    RETURN VALUE
   2324    true/false
   2325 
   2326    ========================================================================== */
   2327 OMX_ERRORTYPE  omx_video::use_output_buffer(
   2328         OMX_IN OMX_HANDLETYPE            hComp,
   2329         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2330         OMX_IN OMX_U32                   port,
   2331         OMX_IN OMX_PTR                   appData,
   2332         OMX_IN OMX_U32                   bytes,
   2333         OMX_IN OMX_U8*                   buffer)
   2334 {
   2335     (void)hComp, (void)port;
   2336     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2337     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   2338     unsigned                         i= 0; // Temporary counter
   2339     unsigned char *buf_addr = NULL;
   2340 #ifdef _MSM8974_
   2341     int align_size;
   2342 #endif
   2343 
   2344     DEBUG_PRINT_HIGH("Inside use_output_buffer()");
   2345     if (bytes != m_sOutPortDef.nBufferSize) {
   2346         DEBUG_PRINT_ERROR("ERROR: use_output_buffer: Size Mismatch!! "
   2347                 "bytes[%u] != Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sOutPortDef.nBufferSize);
   2348         return OMX_ErrorBadParameter;
   2349     }
   2350 
   2351     if (!m_out_mem_ptr) {
   2352         output_use_buffer = true;
   2353         int nBufHdrSize        = 0;
   2354 
   2355         DEBUG_PRINT_LOW("Allocating First Output Buffer(%u)",(unsigned int)m_sOutPortDef.nBufferCountActual);
   2356         nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
   2357         /*
   2358          * Memory for output side involves the following:
   2359          * 1. Array of Buffer Headers
   2360          * 2. Bitmask array to hold the buffer allocation details
   2361          * In order to minimize the memory management entire allocation
   2362          * is done in one step.
   2363          */
   2364         //OMX Buffer header
   2365         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   2366         if (m_out_mem_ptr == NULL) {
   2367             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_out_mem_ptr");
   2368             return OMX_ErrorInsufficientResources;
   2369         }
   2370 
   2371         m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
   2372         if (m_pOutput_pmem == NULL) {
   2373             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
   2374             return OMX_ErrorInsufficientResources;
   2375         }
   2376 #ifdef USE_ION
   2377         m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
   2378         if (m_pOutput_ion == NULL) {
   2379             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
   2380             return OMX_ErrorInsufficientResources;
   2381         }
   2382 #endif
   2383         if (m_out_mem_ptr) {
   2384             bufHdr          =  m_out_mem_ptr;
   2385             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   2386             // Settting the entire storage nicely
   2387             for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
   2388                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   2389                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   2390                 bufHdr->nAllocLen          = bytes;
   2391                 bufHdr->nFilledLen         = 0;
   2392                 bufHdr->pAppPrivate        = appData;
   2393                 bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
   2394                 bufHdr->pBuffer            = NULL;
   2395                 bufHdr++;
   2396                 m_pOutput_pmem[i].fd = -1;
   2397 #ifdef USE_ION
   2398                 m_pOutput_ion[i].ion_device_fd =-1;
   2399                 m_pOutput_ion[i].fd_ion_data.fd=-1;
   2400                 m_pOutput_ion[i].ion_alloc_data.handle = 0;
   2401 #endif
   2402             }
   2403         } else {
   2404             DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]",m_out_mem_ptr);
   2405             eRet =  OMX_ErrorInsufficientResources;
   2406         }
   2407     }
   2408 
   2409     for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
   2410         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   2411             break;
   2412         }
   2413     }
   2414 
   2415     if (eRet == OMX_ErrorNone) {
   2416         if (i < m_sOutPortDef.nBufferCountActual) {
   2417             *bufferHdr = (m_out_mem_ptr + i );
   2418             (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
   2419             (*bufferHdr)->pAppPrivate = appData;
   2420 
   2421             if (!m_use_output_pmem) {
   2422 #ifdef USE_ION
   2423 #ifdef _MSM8974_
   2424                 align_size = (m_sOutPortDef.nBufferSize + (SZ_4K - 1)) & ~(SZ_4K - 1);
   2425                 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size,
   2426                         &m_pOutput_ion[i].ion_alloc_data,
   2427                         &m_pOutput_ion[i].fd_ion_data,0);
   2428 #else
   2429                 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(
   2430                         m_sOutPortDef.nBufferSize,
   2431                         &m_pOutput_ion[i].ion_alloc_data,
   2432                         &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED);
   2433 #endif
   2434                 if (m_pOutput_ion[i].ion_device_fd < 0) {
   2435                     DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   2436                     return OMX_ErrorInsufficientResources;
   2437                 }
   2438                 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
   2439 #else
   2440                 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2441 
   2442                 if (m_pOutput_pmem[i].fd == 0) {
   2443                     m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2444                 }
   2445 
   2446                 if (m_pOutput_pmem[i].fd < 0) {
   2447                     DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
   2448                     return OMX_ErrorInsufficientResources;
   2449                 }
   2450 #endif
   2451                 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   2452                 m_pOutput_pmem[i].offset = 0;
   2453 
   2454                 m_pOutput_pmem[i].buffer = NULL;
   2455                 if(!secure_session) {
   2456 #ifdef _MSM8974_
   2457                     m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   2458                         align_size,PROT_READ|PROT_WRITE,
   2459                         MAP_SHARED,m_pOutput_pmem[i].fd,0);
   2460 #else
   2461                     m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   2462                         m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
   2463                         MAP_SHARED,m_pOutput_pmem[i].fd,0);
   2464 #endif
   2465                 if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
   2466                         DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
   2467                     m_pOutput_pmem[i].buffer = NULL;
   2468                     close(m_pOutput_pmem[i].fd);
   2469 #ifdef USE_ION
   2470                     free_ion_memory(&m_pOutput_ion[i]);
   2471 #endif
   2472                     return OMX_ErrorInsufficientResources;
   2473                 }
   2474                 }
   2475             } else {
   2476                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
   2477                 DEBUG_PRINT_LOW("Inside qcom_ext pParam: %p", pParam);
   2478 
   2479                 if (pParam) {
   2480                     DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (int)pParam->offset);
   2481                     m_pOutput_pmem[i].fd = pParam->pmem_fd;
   2482                     m_pOutput_pmem[i].offset = pParam->offset;
   2483                     m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   2484                     m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
   2485                 } else {
   2486                     DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
   2487                     return OMX_ErrorBadParameter;
   2488                 }
   2489                 buf_addr = (unsigned char *)buffer;
   2490             }
   2491 
   2492             DEBUG_PRINT_LOW("use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
   2493                     (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
   2494             if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) {
   2495                 DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
   2496                 return OMX_ErrorInsufficientResources;
   2497             }
   2498 
   2499             BITMASK_SET(&m_out_bm_count,i);
   2500         } else {
   2501             DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
   2502                     "index = %u", i);
   2503             eRet = OMX_ErrorInsufficientResources;
   2504         }
   2505     }
   2506     return eRet;
   2507 }
   2508 
   2509 
   2510 /* ======================================================================
   2511    FUNCTION
   2512    omx_video::UseBuffer
   2513 
   2514    DESCRIPTION
   2515    OMX Use Buffer method implementation.
   2516 
   2517    PARAMETERS
   2518    <TBD>.
   2519 
   2520    RETURN VALUE
   2521    OMX Error None , if everything successful.
   2522 
   2523    ========================================================================== */
   2524 OMX_ERRORTYPE  omx_video::use_buffer(
   2525         OMX_IN OMX_HANDLETYPE            hComp,
   2526         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2527         OMX_IN OMX_U32                   port,
   2528         OMX_IN OMX_PTR                   appData,
   2529         OMX_IN OMX_U32                   bytes,
   2530         OMX_IN OMX_U8*                   buffer)
   2531 {
   2532     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2533     if (m_state == OMX_StateInvalid) {
   2534         DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State");
   2535         return OMX_ErrorInvalidState;
   2536     }
   2537     if (port == PORT_INDEX_IN) {
   2538         eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   2539     } else if (port == PORT_INDEX_OUT) {
   2540         eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   2541     } else {
   2542         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
   2543         eRet = OMX_ErrorBadPortIndex;
   2544     }
   2545 
   2546     if (eRet == OMX_ErrorNone) {
   2547         if (allocate_done()) {
   2548             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   2549                 // Send the callback now
   2550                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   2551                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   2552                         OMX_COMPONENT_GENERATE_EVENT);
   2553             }
   2554         }
   2555         if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
   2556             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   2557                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2558                 post_event(OMX_CommandPortEnable,
   2559                         PORT_INDEX_IN,
   2560                         OMX_COMPONENT_GENERATE_EVENT);
   2561             }
   2562 
   2563         } else if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
   2564             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   2565                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   2566                 post_event(OMX_CommandPortEnable,
   2567                         PORT_INDEX_OUT,
   2568                         OMX_COMPONENT_GENERATE_EVENT);
   2569                 m_event_port_settings_sent = false;
   2570             }
   2571         }
   2572     }
   2573     return eRet;
   2574 }
   2575 
   2576 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   2577 {
   2578     unsigned int index = 0;
   2579     OMX_U8 *temp_buff ;
   2580 
   2581     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
   2582         DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
   2583                 bufferHdr, m_inp_mem_ptr);
   2584         return OMX_ErrorBadParameter;
   2585     }
   2586 
   2587     index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
   2588 #ifdef _ANDROID_ICS_
   2589     if (meta_mode_enable) {
   2590         if (index < m_sInPortDef.nBufferCountActual) {
   2591             memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
   2592             memset(&meta_buffers[index], 0, sizeof(meta_buffers[index]));
   2593         }
   2594         if (!mUseProxyColorFormat)
   2595             return OMX_ErrorNone;
   2596         else {
   2597             c2d_conv.close();
   2598             opaque_buffer_hdr[index] = NULL;
   2599         }
   2600     }
   2601 #endif
   2602     if (index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat &&
   2603             dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
   2604         DEBUG_PRINT_LOW("ERROR: dev_free_buf() Failed for i/p buf");
   2605     }
   2606 
   2607     if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) {
   2608         auto_lock l(m_lock);
   2609 
   2610         if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) {
   2611             DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case");
   2612             if(!secure_session) {
   2613             munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
   2614             } else {
   2615                 free(m_pInput_pmem[index].buffer);
   2616             }
   2617             m_pInput_pmem[index].buffer = NULL;
   2618             close (m_pInput_pmem[index].fd);
   2619 #ifdef USE_ION
   2620             free_ion_memory(&m_pInput_ion[index]);
   2621 #endif
   2622             m_pInput_pmem[index].fd = -1;
   2623         } else if (m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
   2624                     m_use_input_pmem == OMX_FALSE)) {
   2625             DEBUG_PRINT_LOW("FreeBuffer:: i/p Heap UseBuffer case");
   2626             if (dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
   2627                 DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf");
   2628             }
   2629             if(!secure_session) {
   2630                 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
   2631                 m_pInput_pmem[index].buffer = NULL;
   2632             }
   2633             close (m_pInput_pmem[index].fd);
   2634 #ifdef USE_ION
   2635             free_ion_memory(&m_pInput_ion[index]);
   2636 #endif
   2637             m_pInput_pmem[index].fd = -1;
   2638         } else {
   2639             DEBUG_PRINT_ERROR("FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
   2640         }
   2641     }
   2642     return OMX_ErrorNone;
   2643 }
   2644 
   2645 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   2646 {
   2647     unsigned int index = 0;
   2648     OMX_U8 *temp_buff ;
   2649 
   2650     if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
   2651         DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
   2652                 bufferHdr, m_out_mem_ptr);
   2653         return OMX_ErrorBadParameter;
   2654     }
   2655     index = bufferHdr - m_out_mem_ptr;
   2656 
   2657     if (index < m_sOutPortDef.nBufferCountActual &&
   2658             dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
   2659         DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
   2660     }
   2661 
   2662     if (index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) {
   2663         if (m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) {
   2664             DEBUG_PRINT_LOW("FreeBuffer:: o/p AllocateBuffer case");
   2665             if(!secure_session) {
   2666                 munmap (m_pOutput_pmem[index].buffer,
   2667                         m_pOutput_pmem[index].size);
   2668             } else {
   2669                 char *data = (char*) m_pOutput_pmem[index].buffer;
   2670                 native_handle_t *handle = NULL;
   2671                 memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*));
   2672                 native_handle_delete(handle);
   2673                 free(m_pOutput_pmem[index].buffer);
   2674             }
   2675             close (m_pOutput_pmem[index].fd);
   2676 #ifdef USE_ION
   2677             free_ion_memory(&m_pOutput_ion[index]);
   2678 #endif
   2679             m_pOutput_pmem[index].fd = -1;
   2680         } else if ( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
   2681                     && m_use_output_pmem == OMX_FALSE)) {
   2682             DEBUG_PRINT_LOW("FreeBuffer:: o/p Heap UseBuffer case");
   2683             if (dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
   2684                 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
   2685             }
   2686             if(!secure_session) {
   2687                 munmap (m_pOutput_pmem[index].buffer,
   2688                         m_pOutput_pmem[index].size);
   2689             }
   2690             close (m_pOutput_pmem[index].fd);
   2691 #ifdef USE_ION
   2692             free_ion_memory(&m_pOutput_ion[index]);
   2693 #endif
   2694             m_pOutput_pmem[index].fd = -1;
   2695         } else {
   2696             DEBUG_PRINT_LOW("FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
   2697         }
   2698     }
   2699     return OMX_ErrorNone;
   2700 }
   2701 #ifdef _ANDROID_ICS_
   2702 OMX_ERRORTYPE omx_video::allocate_input_meta_buffer(
   2703         OMX_HANDLETYPE       hComp,
   2704         OMX_BUFFERHEADERTYPE **bufferHdr,
   2705         OMX_PTR              appData,
   2706         OMX_U32              bytes)
   2707 {
   2708     unsigned index = 0;
   2709     if (!bufferHdr || bytes < sizeof(encoder_media_buffer_type)) {
   2710         DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %u",
   2711                 bufferHdr, (unsigned int)bytes);
   2712         return OMX_ErrorBadParameter;
   2713     }
   2714 
   2715     if (!m_inp_mem_ptr && !mUseProxyColorFormat) {
   2716         m_inp_mem_ptr = meta_buffer_hdr;
   2717         DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p",
   2718                 meta_buffer_hdr, m_inp_mem_ptr);
   2719     }
   2720     for (index = 0; ((index < m_sInPortDef.nBufferCountActual) &&
   2721                 meta_buffer_hdr[index].pBuffer); index++);
   2722     if (index == m_sInPortDef.nBufferCountActual) {
   2723         DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer");
   2724         return OMX_ErrorBadParameter;
   2725     }
   2726     if (mUseProxyColorFormat) {
   2727         if (opaque_buffer_hdr[index]) {
   2728             DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
   2729             return OMX_ErrorBadParameter;
   2730         }
   2731         if (allocate_input_buffer(hComp,&opaque_buffer_hdr[index],
   2732                     PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) {
   2733             DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
   2734             return OMX_ErrorBadParameter;
   2735         }
   2736     }
   2737     BITMASK_SET(&m_inp_bm_count,index);
   2738     *bufferHdr = &meta_buffer_hdr[index];
   2739     memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
   2740     meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]);
   2741     meta_buffer_hdr[index].nAllocLen = sizeof(meta_buffers[index]);
   2742     meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION;
   2743     meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN;
   2744     meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index];
   2745     meta_buffer_hdr[index].pAppPrivate = appData;
   2746     if (mUseProxyColorFormat) {
   2747         m_opq_pmem_q.insert_entry((unsigned long)opaque_buffer_hdr[index],0,0);
   2748         DEBUG_PRINT_HIGH("opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]);
   2749     }
   2750     return OMX_ErrorNone;
   2751 }
   2752 #endif
   2753 /* ======================================================================
   2754    FUNCTION
   2755    omx_venc::AllocateInputBuffer
   2756 
   2757    DESCRIPTION
   2758    Helper function for allocate buffer in the input pin
   2759 
   2760    PARAMETERS
   2761    None.
   2762 
   2763    RETURN VALUE
   2764    true/false
   2765 
   2766    ========================================================================== */
   2767 OMX_ERRORTYPE  omx_video::allocate_input_buffer(
   2768         OMX_IN OMX_HANDLETYPE            hComp,
   2769         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2770         OMX_IN OMX_U32                   port,
   2771         OMX_IN OMX_PTR                   appData,
   2772         OMX_IN OMX_U32                   bytes)
   2773 {
   2774     (void)hComp, (void)port;
   2775     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2776     unsigned   i = 0;
   2777 
   2778     DEBUG_PRINT_HIGH("allocate_input_buffer()::");
   2779     if (bytes != m_sInPortDef.nBufferSize) {
   2780         DEBUG_PRINT_ERROR("ERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]",
   2781                 (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
   2782         return OMX_ErrorBadParameter;
   2783     }
   2784 
   2785     if (!m_inp_mem_ptr) {
   2786         DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
   2787                 (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountActual);
   2788         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   2789                         calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
   2790         if (m_inp_mem_ptr == NULL) {
   2791             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
   2792             return OMX_ErrorInsufficientResources;
   2793         }
   2794 
   2795         DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
   2796         m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
   2797 
   2798         if (m_pInput_pmem == NULL) {
   2799             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
   2800             return OMX_ErrorInsufficientResources;
   2801         }
   2802 #ifdef USE_ION
   2803         m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
   2804         if (m_pInput_ion == NULL) {
   2805             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
   2806             return OMX_ErrorInsufficientResources;
   2807         }
   2808 #endif
   2809         for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   2810             m_pInput_pmem[i].fd = -1;
   2811 #ifdef USE_ION
   2812             m_pInput_ion[i].ion_device_fd =-1;
   2813             m_pInput_ion[i].fd_ion_data.fd =-1;
   2814             m_pInput_ion[i].ion_alloc_data.handle = 0;
   2815 #endif
   2816         }
   2817     }
   2818 
   2819     for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
   2820         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   2821             break;
   2822         }
   2823     }
   2824     if (i < m_sInPortDef.nBufferCountActual) {
   2825 
   2826         *bufferHdr = (m_inp_mem_ptr + i);
   2827         (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   2828         (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
   2829         (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
   2830         (*bufferHdr)->pAppPrivate       = appData;
   2831         (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
   2832         // make fd available to app layer, help with testing
   2833         (*bufferHdr)->pInputPortPrivate = (OMX_PTR)&m_pInput_pmem[i];
   2834 
   2835 #ifdef USE_ION
   2836 #ifdef _MSM8974_
   2837         m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   2838                 &m_pInput_ion[i].ion_alloc_data,
   2839                 &m_pInput_ion[i].fd_ion_data,0);
   2840 #else
   2841         m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
   2842                 &m_pInput_ion[i].ion_alloc_data,
   2843                 &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED);
   2844 #endif
   2845         if (m_pInput_ion[i].ion_device_fd < 0) {
   2846             DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   2847             return OMX_ErrorInsufficientResources;
   2848         }
   2849 
   2850         m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
   2851 #else
   2852         m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2853 
   2854         if (m_pInput_pmem[i].fd == 0) {
   2855             m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   2856         }
   2857 
   2858         if (m_pInput_pmem[i].fd < 0) {
   2859             DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
   2860             return OMX_ErrorInsufficientResources;
   2861         }
   2862 #endif
   2863         m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   2864         m_pInput_pmem[i].offset = 0;
   2865 
   2866         m_pInput_pmem[i].buffer = NULL;
   2867         if(!secure_session) {
   2868             m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   2869                 m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
   2870                 MAP_SHARED,m_pInput_pmem[i].fd,0);
   2871         if (m_pInput_pmem[i].buffer == MAP_FAILED) {
   2872                 DEBUG_PRINT_ERROR("ERROR: mmap FAILED= %d", errno);
   2873             m_pInput_pmem[i].buffer = NULL;
   2874             close(m_pInput_pmem[i].fd);
   2875 #ifdef USE_ION
   2876             free_ion_memory(&m_pInput_ion[i]);
   2877 #endif
   2878             return OMX_ErrorInsufficientResources;
   2879         }
   2880         } else {
   2881             //This should only be used for passing reference to source type and
   2882             //secure handle fd struct native_handle_t*
   2883             m_pInput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*));
   2884             if (m_pInput_pmem[i].buffer == NULL) {
   2885                 DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__);
   2886                 return OMX_ErrorInsufficientResources;
   2887             }
   2888         }
   2889 
   2890         (*bufferHdr)->pBuffer           = (OMX_U8 *)m_pInput_pmem[i].buffer;
   2891         DEBUG_PRINT_LOW("Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer);
   2892         BITMASK_SET(&m_inp_bm_count,i);
   2893         //here change the I/P param here from buf_adr to pmem
   2894         if (!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) {
   2895             DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for i/p buf");
   2896             return OMX_ErrorInsufficientResources;
   2897         }
   2898     } else {
   2899         DEBUG_PRINT_ERROR("ERROR: All i/p buffers are allocated, invalid allocate buf call"
   2900                 "for index [%d]", i);
   2901         eRet = OMX_ErrorInsufficientResources;
   2902     }
   2903 
   2904     return eRet;
   2905 }
   2906 
   2907 
   2908 /* ======================================================================
   2909    FUNCTION
   2910    omx_venc::AllocateOutputBuffer
   2911 
   2912    DESCRIPTION
   2913    Helper fn for AllocateBuffer in the output pin
   2914 
   2915    PARAMETERS
   2916    <TBD>.
   2917 
   2918    RETURN VALUE
   2919    OMX Error None if everything went well.
   2920 
   2921    ========================================================================== */
   2922 OMX_ERRORTYPE  omx_video::allocate_output_buffer(
   2923         OMX_IN OMX_HANDLETYPE            hComp,
   2924         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2925         OMX_IN OMX_U32                   port,
   2926         OMX_IN OMX_PTR                   appData,
   2927         OMX_IN OMX_U32                   bytes)
   2928 {
   2929     (void)hComp, (void)port;
   2930     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2931     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   2932     unsigned                         i= 0; // Temporary counter
   2933 #ifdef _MSM8974_
   2934     int align_size;
   2935 #endif
   2936     DEBUG_PRINT_HIGH("allocate_output_buffer()for %u bytes", (unsigned int)bytes);
   2937     if (!m_out_mem_ptr) {
   2938         int nBufHdrSize        = 0;
   2939         DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
   2940                 (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountActual);
   2941         nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
   2942 
   2943         /*
   2944          * Memory for output side involves the following:
   2945          * 1. Array of Buffer Headers
   2946          * 2. Bitmask array to hold the buffer allocation details
   2947          * In order to minimize the memory management entire allocation
   2948          * is done in one step.
   2949          */
   2950         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   2951 
   2952 #ifdef USE_ION
   2953         m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
   2954         if (m_pOutput_ion == NULL) {
   2955             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
   2956             return OMX_ErrorInsufficientResources;
   2957         }
   2958 #endif
   2959         m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
   2960         if (m_pOutput_pmem == NULL) {
   2961             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
   2962             return OMX_ErrorInsufficientResources;
   2963         }
   2964         if (m_out_mem_ptr && m_pOutput_pmem) {
   2965             bufHdr          =  m_out_mem_ptr;
   2966 
   2967             for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
   2968                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   2969                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   2970                 // Set the values when we determine the right HxW param
   2971                 bufHdr->nAllocLen          = m_sOutPortDef.nBufferSize;
   2972                 bufHdr->nFilledLen         = 0;
   2973                 bufHdr->pAppPrivate        = appData;
   2974                 bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
   2975                 // make fd available to app layer, help with testing
   2976                 bufHdr->pOutputPortPrivate = (OMX_PTR)&m_pOutput_pmem[i];
   2977                 bufHdr->pBuffer            = NULL;
   2978                 bufHdr++;
   2979                 m_pOutput_pmem[i].fd = -1;
   2980 #ifdef USE_ION
   2981                 m_pOutput_ion[i].ion_device_fd =-1;
   2982                 m_pOutput_ion[i].fd_ion_data.fd=-1;
   2983                 m_pOutput_ion[i].ion_alloc_data.handle = 0;
   2984 #endif
   2985             }
   2986         } else {
   2987             DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
   2988             eRet = OMX_ErrorInsufficientResources;
   2989         }
   2990     }
   2991 
   2992     DEBUG_PRINT_HIGH("actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferCountActual);
   2993     for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
   2994         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   2995             DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
   2996             break;
   2997         }
   2998     }
   2999     if (eRet == OMX_ErrorNone) {
   3000         if (i < m_sOutPortDef.nBufferCountActual) {
   3001 #ifdef USE_ION
   3002 #ifdef _MSM8974_
   3003             align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096;
   3004             m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size,
   3005                     &m_pOutput_ion[i].ion_alloc_data,
   3006                     &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED);
   3007 #else
   3008             m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize,
   3009                     &m_pOutput_ion[i].ion_alloc_data,
   3010                     &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED);
   3011 #endif
   3012             if (m_pOutput_ion[i].ion_device_fd < 0) {
   3013                 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
   3014                 return OMX_ErrorInsufficientResources;
   3015             }
   3016 
   3017             m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
   3018 #else
   3019             m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   3020             if (m_pOutput_pmem[i].fd == 0) {
   3021                 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
   3022             }
   3023 
   3024             if (m_pOutput_pmem[i].fd < 0) {
   3025                 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() failed");
   3026                 return OMX_ErrorInsufficientResources;
   3027             }
   3028 #endif
   3029             m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   3030             m_pOutput_pmem[i].offset = 0;
   3031 
   3032             m_pOutput_pmem[i].buffer = NULL;
   3033             if(!secure_session) {
   3034 #ifdef _MSM8974_
   3035                 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   3036                     align_size,PROT_READ|PROT_WRITE,
   3037                     MAP_SHARED,m_pOutput_pmem[i].fd,0);
   3038 #else
   3039                 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
   3040                     m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
   3041                     MAP_SHARED,m_pOutput_pmem[i].fd,0);
   3042 #endif
   3043             if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
   3044                     DEBUG_PRINT_ERROR("ERROR: MMAP_FAILED in o/p alloc buffer");
   3045                 m_pOutput_pmem[i].buffer = NULL;
   3046                 close (m_pOutput_pmem[i].fd);
   3047 #ifdef USE_ION
   3048                 free_ion_memory(&m_pOutput_ion[i]);
   3049 #endif
   3050                 return OMX_ErrorInsufficientResources;
   3051             }
   3052             }
   3053             else {
   3054                 //This should only be used for passing reference to source type and
   3055                 //secure handle fd struct native_handle_t*
   3056                 m_pOutput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*));
   3057                 if (m_pOutput_pmem[i].buffer == NULL) {
   3058                     DEBUG_PRINT_ERROR("%s: Failed to allocate native-handle", __func__);
   3059                     return OMX_ErrorInsufficientResources;
   3060                 }
   3061                 native_handle_t *handle = native_handle_create(1, 0);
   3062                 handle->data[0] = m_pOutput_pmem[i].fd;
   3063                 char *data = (char*) m_pOutput_pmem[i].buffer;
   3064                 OMX_U32 type = 1;
   3065                 memcpy(data, &type, sizeof(OMX_U32));
   3066                 memcpy(data + sizeof(OMX_U32), &handle, sizeof(native_handle_t*));
   3067             }
   3068 
   3069             *bufferHdr = (m_out_mem_ptr + i );
   3070             (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
   3071             (*bufferHdr)->pAppPrivate = appData;
   3072 
   3073             BITMASK_SET(&m_out_bm_count,i);
   3074 
   3075             if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) {
   3076                 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for o/p buf");
   3077                 return OMX_ErrorInsufficientResources;
   3078             }
   3079         } else {
   3080             DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call"
   3081                     "for index [%d] actual: %u", i, (unsigned int)m_sOutPortDef.nBufferCountActual);
   3082         }
   3083     }
   3084 
   3085     return eRet;
   3086 }
   3087 
   3088 
   3089 // AllocateBuffer  -- API Call
   3090 /* ======================================================================
   3091    FUNCTION
   3092    omx_video::AllocateBuffer
   3093 
   3094    DESCRIPTION
   3095    Returns zero if all the buffers released..
   3096 
   3097    PARAMETERS
   3098    None.
   3099 
   3100    RETURN VALUE
   3101    true/false
   3102 
   3103    ========================================================================== */
   3104 OMX_ERRORTYPE  omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   3105         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3106         OMX_IN OMX_U32                        port,
   3107         OMX_IN OMX_PTR                     appData,
   3108         OMX_IN OMX_U32                       bytes)
   3109 {
   3110 
   3111     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   3112 
   3113     DEBUG_PRINT_LOW("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port);
   3114     if (m_state == OMX_StateInvalid) {
   3115         DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
   3116         return OMX_ErrorInvalidState;
   3117     }
   3118 
   3119     // What if the client calls again.
   3120     if (port == PORT_INDEX_IN) {
   3121 #ifdef _ANDROID_ICS_
   3122         if (meta_mode_enable)
   3123             eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
   3124         else
   3125 #endif
   3126             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   3127     } else if (port == PORT_INDEX_OUT) {
   3128         eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   3129     } else {
   3130         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
   3131         eRet = OMX_ErrorBadPortIndex;
   3132     }
   3133     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   3134     if (eRet == OMX_ErrorNone) {
   3135         if (allocate_done()) {
   3136             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   3137                 // Send the callback now
   3138                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   3139                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   3140                         OMX_COMPONENT_GENERATE_EVENT);
   3141             }
   3142         }
   3143         if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
   3144             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   3145                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   3146                 post_event(OMX_CommandPortEnable,
   3147                         PORT_INDEX_IN,
   3148                         OMX_COMPONENT_GENERATE_EVENT);
   3149             }
   3150         }
   3151         if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
   3152             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   3153                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   3154                 post_event(OMX_CommandPortEnable,
   3155                         PORT_INDEX_OUT,
   3156                         OMX_COMPONENT_GENERATE_EVENT);
   3157                 m_event_port_settings_sent = false;
   3158             }
   3159         }
   3160     }
   3161     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
   3162     return eRet;
   3163 }
   3164 
   3165 
   3166 // Free Buffer - API call
   3167 /* ======================================================================
   3168    FUNCTION
   3169    omx_video::FreeBuffer
   3170 
   3171    DESCRIPTION
   3172 
   3173    PARAMETERS
   3174    None.
   3175 
   3176    RETURN VALUE
   3177    true/false
   3178 
   3179    ========================================================================== */
   3180 OMX_ERRORTYPE  omx_video::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   3181         OMX_IN OMX_U32                 port,
   3182         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   3183 {
   3184     (void)hComp;
   3185     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3186     unsigned int nPortIndex;
   3187 
   3188     DEBUG_PRINT_LOW("In for encoder free_buffer");
   3189 
   3190     if (m_state == OMX_StateIdle &&
   3191             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   3192         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
   3193     } else if ((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
   3194             (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) {
   3195         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
   3196     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   3197         DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled");
   3198         post_event(OMX_EventError,
   3199                 OMX_ErrorPortUnpopulated,
   3200                 OMX_COMPONENT_GENERATE_EVENT);
   3201         return eRet;
   3202     } else {
   3203         DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers");
   3204         post_event(OMX_EventError,
   3205                 OMX_ErrorPortUnpopulated,
   3206                 OMX_COMPONENT_GENERATE_EVENT);
   3207     }
   3208 
   3209     if (port == PORT_INDEX_IN) {
   3210         // check if the buffer is valid
   3211         nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
   3212 
   3213         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
   3214                 nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
   3215         if (nPortIndex < m_sInPortDef.nBufferCountActual &&
   3216                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
   3217             // Clear the bit associated with it.
   3218             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   3219             free_input_buffer (buffer);
   3220             m_sInPortDef.bPopulated = OMX_FALSE;
   3221 
   3222             /*Free the Buffer Header*/
   3223             if (release_input_done()
   3224 #ifdef _ANDROID_ICS_
   3225                     && !meta_mode_enable
   3226 #endif
   3227                ) {
   3228                 input_use_buffer = false;
   3229                 if (m_inp_mem_ptr) {
   3230                     DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr");
   3231                     free (m_inp_mem_ptr);
   3232                     m_inp_mem_ptr = NULL;
   3233                 }
   3234                 if (m_pInput_pmem) {
   3235                     DEBUG_PRINT_LOW("Freeing m_pInput_pmem");
   3236                     free(m_pInput_pmem);
   3237                     m_pInput_pmem = NULL;
   3238                 }
   3239 #ifdef USE_ION
   3240                 if (m_pInput_ion) {
   3241                     DEBUG_PRINT_LOW("Freeing m_pInput_ion");
   3242                     free(m_pInput_ion);
   3243                     m_pInput_ion = NULL;
   3244                 }
   3245 #endif
   3246             }
   3247         } else {
   3248             DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid");
   3249             eRet = OMX_ErrorBadPortIndex;
   3250         }
   3251 
   3252         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   3253                 && release_input_done()) {
   3254             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   3255             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   3256             post_event(OMX_CommandPortDisable,
   3257                     PORT_INDEX_IN,
   3258                     OMX_COMPONENT_GENERATE_EVENT);
   3259         }
   3260     } else if (port == PORT_INDEX_OUT) {
   3261         // check if the buffer is valid
   3262         nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
   3263 
   3264         DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u",
   3265                 nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
   3266         if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
   3267                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
   3268             // Clear the bit associated with it.
   3269             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   3270             m_sOutPortDef.bPopulated = OMX_FALSE;
   3271             free_output_buffer (buffer);
   3272 
   3273             if (release_output_done()) {
   3274                 output_use_buffer = false;
   3275                 if (m_out_mem_ptr) {
   3276                     DEBUG_PRINT_LOW("Freeing m_out_mem_ptr");
   3277                     free (m_out_mem_ptr);
   3278                     m_out_mem_ptr = NULL;
   3279                 }
   3280                 if (m_pOutput_pmem) {
   3281                     DEBUG_PRINT_LOW("Freeing m_pOutput_pmem");
   3282                     free(m_pOutput_pmem);
   3283                     m_pOutput_pmem = NULL;
   3284                 }
   3285 #ifdef USE_ION
   3286                 if (m_pOutput_ion) {
   3287                     DEBUG_PRINT_LOW("Freeing m_pOutput_ion");
   3288                     free(m_pOutput_ion);
   3289                     m_pOutput_ion = NULL;
   3290                 }
   3291 #endif
   3292             }
   3293         } else {
   3294             DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid");
   3295             eRet = OMX_ErrorBadPortIndex;
   3296         }
   3297         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   3298                 && release_output_done() ) {
   3299             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
   3300 
   3301             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   3302             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   3303             post_event(OMX_CommandPortDisable,
   3304                     PORT_INDEX_OUT,
   3305                     OMX_COMPONENT_GENERATE_EVENT);
   3306 
   3307         }
   3308     } else {
   3309         eRet = OMX_ErrorBadPortIndex;
   3310     }
   3311     if ((eRet == OMX_ErrorNone) &&
   3312             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   3313         if (release_done()) {
   3314             if (dev_stop() != 0) {
   3315                 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED");
   3316                 eRet = OMX_ErrorHardware;
   3317             }
   3318             // Send the callback now
   3319             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   3320             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   3321                     OMX_COMPONENT_GENERATE_EVENT);
   3322         } else {
   3323             DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers input %" PRIx64" output %" PRIx64,
   3324                     m_out_bm_count, m_inp_bm_count);
   3325         }
   3326     }
   3327 
   3328     return eRet;
   3329 }
   3330 
   3331 
   3332 /* ======================================================================
   3333    FUNCTION
   3334    omx_video::EmptyThisBuffer
   3335 
   3336    DESCRIPTION
   3337    This routine is used to push the encoded video frames to
   3338    the video decoder.
   3339 
   3340    PARAMETERS
   3341    None.
   3342 
   3343    RETURN VALUE
   3344    OMX Error None if everything went successful.
   3345 
   3346    ========================================================================== */
   3347 OMX_ERRORTYPE  omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   3348         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   3349 {
   3350     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   3351     unsigned int nBufferIndex ;
   3352 
   3353     DEBUG_PRINT_LOW("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer);
   3354     if (m_state != OMX_StateExecuting &&
   3355             m_state != OMX_StatePause &&
   3356             m_state != OMX_StateIdle) {
   3357         DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State");
   3358         return OMX_ErrorInvalidState;
   3359     }
   3360 
   3361     if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
   3362         DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid");
   3363         return OMX_ErrorBadParameter;
   3364     }
   3365 
   3366     if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
   3367         DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid");
   3368         return OMX_ErrorVersionMismatch;
   3369     }
   3370 
   3371     if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) {
   3372         DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer");
   3373         return OMX_ErrorBadPortIndex;
   3374     }
   3375     if (!m_sInPortDef.bEnabled) {
   3376         DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled");
   3377         return OMX_ErrorIncorrectStateOperation;
   3378     }
   3379 
   3380     nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
   3381 
   3382     if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
   3383         DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
   3384         return OMX_ErrorBadParameter;
   3385     }
   3386 
   3387     m_etb_count++;
   3388     DEBUG_PRINT_LOW("DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
   3389     post_event ((unsigned long)hComp,(unsigned long)buffer,m_input_msg_id);
   3390     return OMX_ErrorNone;
   3391 }
   3392 /* ======================================================================
   3393    FUNCTION
   3394    omx_video::empty_this_buffer_proxy
   3395 
   3396    DESCRIPTION
   3397    This routine is used to push the encoded video frames to
   3398    the video decoder.
   3399 
   3400    PARAMETERS
   3401    None.
   3402 
   3403    RETURN VALUE
   3404    OMX Error None if everything went successful.
   3405 
   3406    ========================================================================== */
   3407 OMX_ERRORTYPE  omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
   3408         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   3409 {
   3410     (void)hComp;
   3411     OMX_U8 *pmem_data_buf = NULL;
   3412     int push_cnt = 0;
   3413     unsigned nBufIndex = 0;
   3414     OMX_ERRORTYPE ret = OMX_ErrorNone;
   3415     encoder_media_buffer_type *media_buffer = NULL;
   3416 
   3417 #ifdef _MSM8974_
   3418     int fd = 0;
   3419 #endif
   3420     DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer);
   3421     if (buffer == NULL) {
   3422         DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer);
   3423         return OMX_ErrorBadParameter;
   3424     }
   3425 
   3426     // Buffer sanity checks
   3427     if (meta_mode_enable && !mUsesColorConversion) {
   3428         //For color-conversion case, we have an internal buffer and not a meta buffer
   3429         bool met_error = false;
   3430         nBufIndex = buffer - meta_buffer_hdr;
   3431         if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
   3432             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex);
   3433             return OMX_ErrorBadParameter;
   3434         }
   3435         media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer;
   3436         if (media_buffer) {
   3437             if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource &&
   3438                     media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
   3439                 met_error = true;
   3440             } else {
   3441                 if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
   3442                     if (media_buffer->meta_handle == NULL)
   3443                         met_error = true;
   3444                     else if ((media_buffer->meta_handle->numFds != 1 &&
   3445                                 media_buffer->meta_handle->numInts != 2))
   3446                         met_error = true;
   3447                 }
   3448             }
   3449         } else
   3450             met_error = true;
   3451         if (met_error) {
   3452             DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call");
   3453             post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
   3454             return OMX_ErrorBadParameter;
   3455         }
   3456     } else {
   3457         nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   3458         if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
   3459             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex);
   3460             return OMX_ErrorBadParameter;
   3461         }
   3462     }
   3463 
   3464     pending_input_buffers++;
   3465     if (input_flush_progress == true) {
   3466         post_event ((unsigned long)buffer,0,
   3467                 OMX_COMPONENT_GENERATE_EBD);
   3468         DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress");
   3469         return OMX_ErrorNone;
   3470     }
   3471 #ifdef _MSM8974_
   3472     if (!meta_mode_enable) {
   3473         fd = m_pInput_pmem[nBufIndex].fd;
   3474     }
   3475 #endif
   3476 #ifdef _ANDROID_ICS_
   3477     if (meta_mode_enable && !mUseProxyColorFormat) {
   3478         // Camera or Gralloc-source meta-buffers queued with pre-announced color-format
   3479         struct pmem Input_pmem_info;
   3480         if (!media_buffer) {
   3481             DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
   3482             return OMX_ErrorBadParameter;
   3483         }
   3484         if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
   3485             Input_pmem_info.buffer = media_buffer;
   3486             Input_pmem_info.fd = media_buffer->meta_handle->data[0];
   3487 #ifdef _MSM8974_
   3488             fd = Input_pmem_info.fd;
   3489 #endif
   3490             Input_pmem_info.offset = media_buffer->meta_handle->data[1];
   3491             Input_pmem_info.size = media_buffer->meta_handle->data[2];
   3492             DEBUG_PRINT_LOW("ETB (meta-Camera) fd = %d, offset = %d, size = %d",
   3493                     Input_pmem_info.fd, Input_pmem_info.offset,
   3494                     Input_pmem_info.size);
   3495         } else {
   3496             private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
   3497             Input_pmem_info.buffer = media_buffer;
   3498             Input_pmem_info.fd = handle->fd;
   3499 #ifdef _MSM8974_
   3500             fd = Input_pmem_info.fd;
   3501 #endif
   3502             Input_pmem_info.offset = 0;
   3503             Input_pmem_info.size = handle->size;
   3504             DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
   3505                     Input_pmem_info.fd, Input_pmem_info.offset,
   3506                     Input_pmem_info.size);
   3507         }
   3508         if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
   3509             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
   3510             post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
   3511             return OMX_ErrorBadParameter;
   3512         }
   3513     } else if (meta_mode_enable && !mUsesColorConversion) {
   3514         // Graphic-source meta-buffers queued with opaque color-format
   3515         if (media_buffer->buffer_type == kMetadataBufferTypeGrallocSource) {
   3516             private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
   3517             fd = handle->fd;
   3518             DEBUG_PRINT_LOW("ETB (opaque-gralloc) fd = %d, size = %d",
   3519                     fd, handle->size);
   3520         } else {
   3521             DEBUG_PRINT_ERROR("ERROR: Invalid bufferType for buffer with Opaque"
   3522                     " color format");
   3523             post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
   3524             return OMX_ErrorBadParameter;
   3525         }
   3526     } else if (input_use_buffer && !m_use_input_pmem &&  m_pInput_pmem[nBufIndex].buffer)
   3527 #else
   3528     if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
   3529 #endif
   3530     {
   3531         DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");
   3532 
   3533         auto_lock l(m_lock);
   3534         pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
   3535         if (pmem_data_buf) {
   3536             memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
   3537                     buffer->nFilledLen);
   3538         }
   3539         DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
   3540     } else if (mUseProxyColorFormat) {
   3541         // Gralloc-source buffers with color-conversion
   3542         fd = m_pInput_pmem[nBufIndex].fd;
   3543         DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u",
   3544                 fd, (unsigned int)buffer->nFilledLen);
   3545     } else if (m_sInPortDef.format.video.eColorFormat ==
   3546                     OMX_COLOR_FormatYUV420SemiPlanar) {
   3547             //For the case where YUV420SP buffers are qeueued to component
   3548             //by sources other than camera (Apps via MediaCodec), conversion
   3549             //to vendor flavoured NV12 color format is required.
   3550             if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth,
   3551                                     m_sInPortDef.format.video.nFrameHeight)) {
   3552                     DEBUG_PRINT_ERROR("Failed to adjust buffer color");
   3553                     post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
   3554                     return OMX_ErrorUndefined;
   3555             }
   3556     }
   3557 #ifdef _MSM8974_
   3558     if (dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true)
   3559 #else
   3560     if (dev_empty_buf(buffer, pmem_data_buf,0,0) != true)
   3561 #endif
   3562     {
   3563         DEBUG_PRINT_ERROR("ERROR: ETBProxy: dev_empty_buf failed");
   3564 #ifdef _ANDROID_ICS_
   3565         omx_release_meta_buffer(buffer);
   3566 #endif
   3567         post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
   3568         /*Generate an async error and move to invalid state*/
   3569         pending_input_buffers--;
   3570         if (hw_overload) {
   3571             return OMX_ErrorInsufficientResources;
   3572         }
   3573         return OMX_ErrorBadParameter;
   3574     }
   3575     return ret;
   3576 }
   3577 
   3578 /* ======================================================================
   3579    FUNCTION
   3580    omx_video::FillThisBuffer
   3581 
   3582    DESCRIPTION
   3583    IL client uses this method to release the frame buffer
   3584    after displaying them.
   3585 
   3586    PARAMETERS
   3587    None.
   3588 
   3589    RETURN VALUE
   3590    true/false
   3591 
   3592    ========================================================================== */
   3593 OMX_ERRORTYPE  omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   3594         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   3595 {
   3596     DEBUG_PRINT_LOW("FTB: buffer->pBuffer[%p]", buffer->pBuffer);
   3597     if (m_state != OMX_StateExecuting &&
   3598             m_state != OMX_StatePause &&
   3599             m_state != OMX_StateIdle) {
   3600         DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State");
   3601         return OMX_ErrorInvalidState;
   3602     }
   3603 
   3604     if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
   3605         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size");
   3606         return OMX_ErrorBadParameter;
   3607     }
   3608 
   3609     if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
   3610         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid");
   3611         return OMX_ErrorVersionMismatch;
   3612     }
   3613 
   3614     if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) {
   3615         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index");
   3616         return OMX_ErrorBadPortIndex;
   3617     }
   3618 
   3619     if (!m_sOutPortDef.bEnabled) {
   3620         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled");
   3621         return OMX_ErrorIncorrectStateOperation;
   3622     }
   3623 
   3624     post_event((unsigned long) hComp, (unsigned long)buffer,OMX_COMPONENT_GENERATE_FTB);
   3625     return OMX_ErrorNone;
   3626 }
   3627 
   3628 /* ======================================================================
   3629    FUNCTION
   3630    omx_video::fill_this_buffer_proxy
   3631 
   3632    DESCRIPTION
   3633    IL client uses this method to release the frame buffer
   3634    after displaying them.
   3635 
   3636    PARAMETERS
   3637    None.
   3638 
   3639    RETURN VALUE
   3640    true/false
   3641 
   3642    ========================================================================== */
   3643 OMX_ERRORTYPE  omx_video::fill_this_buffer_proxy(
   3644         OMX_IN OMX_HANDLETYPE        hComp,
   3645         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   3646 {
   3647     (void)hComp;
   3648     OMX_U8 *pmem_data_buf = NULL;
   3649     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   3650 
   3651     DEBUG_PRINT_LOW("FTBProxy: bufferAdd->pBuffer[%p]", bufferAdd->pBuffer);
   3652 
   3653     if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) {
   3654         DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params");
   3655         return OMX_ErrorBadParameter;
   3656     }
   3657 
   3658     pending_output_buffers++;
   3659     /*Return back the output buffer to client*/
   3660     if ( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) {
   3661         DEBUG_PRINT_LOW("o/p port is Disabled or Flush in Progress");
   3662         post_event ((unsigned long)bufferAdd,0,
   3663                 OMX_COMPONENT_GENERATE_FBD);
   3664         return OMX_ErrorNone;
   3665     }
   3666 
   3667     if (output_use_buffer && !m_use_output_pmem) {
   3668         DEBUG_PRINT_LOW("Heap UseBuffer case");
   3669         pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
   3670     }
   3671 
   3672     if (dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) {
   3673         DEBUG_PRINT_ERROR("ERROR: dev_fill_buf() Failed");
   3674         post_event ((unsigned long)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
   3675         pending_output_buffers--;
   3676         return OMX_ErrorBadParameter;
   3677     }
   3678 
   3679     return OMX_ErrorNone;
   3680 }
   3681 
   3682 /* ======================================================================
   3683    FUNCTION
   3684    omx_video::SetCallbacks
   3685 
   3686    DESCRIPTION
   3687    Set the callbacks.
   3688 
   3689    PARAMETERS
   3690    None.
   3691 
   3692    RETURN VALUE
   3693    OMX Error None if everything successful.
   3694 
   3695    ========================================================================== */
   3696 OMX_ERRORTYPE  omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   3697         OMX_IN OMX_CALLBACKTYPE* callbacks,
   3698         OMX_IN OMX_PTR             appData)
   3699 {
   3700     (void)hComp;
   3701     m_pCallbacks       = *callbacks;
   3702     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
   3703             m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
   3704     m_app_data =    appData;
   3705     return OMX_ErrorNotImplemented;
   3706 }
   3707 
   3708 
   3709 /* ======================================================================
   3710    FUNCTION
   3711    omx_venc::UseEGLImage
   3712 
   3713    DESCRIPTION
   3714    OMX Use EGL Image method implementation <TBD>.
   3715 
   3716    PARAMETERS
   3717    <TBD>.
   3718 
   3719    RETURN VALUE
   3720    Not Implemented error.
   3721 
   3722    ========================================================================== */
   3723 OMX_ERRORTYPE  omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE   hComp,
   3724         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3725         OMX_IN OMX_U32                        port,
   3726         OMX_IN OMX_PTR                     appData,
   3727         OMX_IN void*                      eglImage)
   3728 {
   3729     (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage;
   3730     DEBUG_PRINT_ERROR("ERROR: use_EGL_image:  Not Implemented");
   3731     return OMX_ErrorNotImplemented;
   3732 }
   3733 
   3734 /* ======================================================================
   3735    FUNCTION
   3736    omx_venc::ComponentRoleEnum
   3737 
   3738    DESCRIPTION
   3739    OMX Component Role Enum method implementation.
   3740 
   3741    PARAMETERS
   3742    <TBD>.
   3743 
   3744    RETURN VALUE
   3745    OMX Error None if everything is successful.
   3746    ========================================================================== */
   3747 OMX_ERRORTYPE  omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   3748         OMX_OUT OMX_U8*        role,
   3749         OMX_IN OMX_U32        index)
   3750 {
   3751     (void)hComp;
   3752     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3753     if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3754         if ((0 == index) && role) {
   3755             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   3756             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3757         } else {
   3758             eRet = OMX_ErrorNoMore;
   3759         }
   3760     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   3761         if ((0 == index) && role) {
   3762             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   3763             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3764         } else {
   3765             DEBUG_PRINT_ERROR("ERROR: No more roles");
   3766             eRet = OMX_ErrorNoMore;
   3767         }
   3768     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3769         if ((0 == index) && role) {
   3770             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   3771             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3772         } else {
   3773             DEBUG_PRINT_ERROR("ERROR: No more roles");
   3774             eRet = OMX_ErrorNoMore;
   3775         }
   3776     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
   3777         if ((0 == index) && role) {
   3778             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   3779             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3780         } else {
   3781             DEBUG_PRINT_ERROR("ERROR: No more roles");
   3782             eRet = OMX_ErrorNoMore;
   3783         }
   3784     }
   3785     if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3786         if ((0 == index) && role) {
   3787             strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   3788             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3789         } else {
   3790             eRet = OMX_ErrorNoMore;
   3791         }
   3792     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   3793         if ((0 == index) && role) {
   3794             strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
   3795             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3796         } else {
   3797             DEBUG_PRINT_ERROR("ERROR: No more roles");
   3798             eRet = OMX_ErrorNoMore;
   3799         }
   3800     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3801         if ((0 == index) && role) {
   3802             strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
   3803             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3804         } else {
   3805             DEBUG_PRINT_ERROR("ERROR: No more roles");
   3806             eRet = OMX_ErrorNoMore;
   3807         }
   3808     }
   3809 #ifdef _MSM8974_
   3810     else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   3811         if ((0 == index) && role) {
   3812             strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   3813             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   3814         } else {
   3815             DEBUG_PRINT_ERROR("ERROR: No more roles");
   3816             eRet = OMX_ErrorNoMore;
   3817         }
   3818     }
   3819 #endif
   3820     else if ((!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) ||
   3821             (!strncmp((char*)m_nkind, "OMX.qti.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE))) {
   3822         if ((0 == index) && role) {
   3823             strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   3824             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
   3825         } else {
   3826             DEBUG_PRINT_ERROR("ERROR: No more roles");
   3827             eRet = OMX_ErrorNoMore;
   3828         }
   3829     }
   3830     else {
   3831         DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
   3832         eRet = OMX_ErrorInvalidComponentName;
   3833     }
   3834     return eRet;
   3835 }
   3836 
   3837 
   3838 
   3839 
   3840 /* ======================================================================
   3841    FUNCTION
   3842    omx_venc::AllocateDone
   3843 
   3844    DESCRIPTION
   3845    Checks if entire buffer pool is allocated by IL Client or not.
   3846    Need this to move to IDLE state.
   3847 
   3848    PARAMETERS
   3849    None.
   3850 
   3851    RETURN VALUE
   3852    true/false.
   3853 
   3854    ========================================================================== */
   3855 bool omx_video::allocate_done(void)
   3856 {
   3857     bool bRet = false;
   3858     bool bRet_In = false;
   3859     bool bRet_Out = false;
   3860 
   3861     bRet_In = allocate_input_done();
   3862     bRet_Out = allocate_output_done();
   3863 
   3864     if (bRet_In && bRet_Out) {
   3865         bRet = true;
   3866     }
   3867 
   3868     return bRet;
   3869 }
   3870 /* ======================================================================
   3871    FUNCTION
   3872    omx_venc::AllocateInputDone
   3873 
   3874    DESCRIPTION
   3875    Checks if I/P buffer pool is allocated by IL Client or not.
   3876 
   3877    PARAMETERS
   3878    None.
   3879 
   3880    RETURN VALUE
   3881    true/false.
   3882 
   3883    ========================================================================== */
   3884 bool omx_video::allocate_input_done(void)
   3885 {
   3886     bool bRet = false;
   3887     unsigned i=0;
   3888 
   3889     if (m_inp_mem_ptr == NULL) {
   3890         return bRet;
   3891     }
   3892     if (m_inp_mem_ptr ) {
   3893         for (; i<m_sInPortDef.nBufferCountActual; i++) {
   3894             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   3895                 break;
   3896             }
   3897         }
   3898     }
   3899     if (i==m_sInPortDef.nBufferCountActual) {
   3900         bRet = true;
   3901     }
   3902     if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) {
   3903         m_sInPortDef.bPopulated = OMX_TRUE;
   3904     }
   3905     return bRet;
   3906 }
   3907 /* ======================================================================
   3908    FUNCTION
   3909    omx_venc::AllocateOutputDone
   3910 
   3911    DESCRIPTION
   3912    Checks if entire O/P buffer pool is allocated by IL Client or not.
   3913 
   3914    PARAMETERS
   3915    None.
   3916 
   3917    RETURN VALUE
   3918    true/false.
   3919 
   3920    ========================================================================== */
   3921 bool omx_video::allocate_output_done(void)
   3922 {
   3923     bool bRet = false;
   3924     unsigned j=0;
   3925 
   3926     if (m_out_mem_ptr == NULL) {
   3927         return bRet;
   3928     }
   3929 
   3930     if (m_out_mem_ptr ) {
   3931         for (; j<m_sOutPortDef.nBufferCountActual; j++) {
   3932             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   3933                 break;
   3934             }
   3935         }
   3936     }
   3937 
   3938     if (j==m_sOutPortDef.nBufferCountActual) {
   3939         bRet = true;
   3940     }
   3941 
   3942     if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) {
   3943         m_sOutPortDef.bPopulated = OMX_TRUE;
   3944     }
   3945     return bRet;
   3946 }
   3947 
   3948 /* ======================================================================
   3949    FUNCTION
   3950    omx_venc::ReleaseDone
   3951 
   3952    DESCRIPTION
   3953    Checks if IL client has released all the buffers.
   3954 
   3955    PARAMETERS
   3956    None.
   3957 
   3958    RETURN VALUE
   3959    true/false
   3960 
   3961    ========================================================================== */
   3962 bool omx_video::release_done(void)
   3963 {
   3964     bool bRet = false;
   3965     DEBUG_PRINT_LOW("Inside release_done()");
   3966     if (release_input_done()) {
   3967         if (release_output_done()) {
   3968             bRet = true;
   3969         }
   3970     }
   3971     return bRet;
   3972 }
   3973 
   3974 
   3975 /* ======================================================================
   3976    FUNCTION
   3977    omx_venc::ReleaseOutputDone
   3978 
   3979    DESCRIPTION
   3980    Checks if IL client has released all the buffers.
   3981 
   3982    PARAMETERS
   3983    None.
   3984 
   3985    RETURN VALUE
   3986    true/false
   3987 
   3988    ========================================================================== */
   3989 bool omx_video::release_output_done(void)
   3990 {
   3991     bool bRet = false;
   3992     unsigned i=0,j=0;
   3993 
   3994     DEBUG_PRINT_LOW("Inside release_output_done()");
   3995     if (m_out_mem_ptr) {
   3996         for (; j<m_sOutPortDef.nBufferCountActual; j++) {
   3997             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   3998                 break;
   3999             }
   4000         }
   4001         if (j==m_sOutPortDef.nBufferCountActual) {
   4002             bRet = true;
   4003         }
   4004     } else {
   4005         bRet = true;
   4006     }
   4007     return bRet;
   4008 }
   4009 /* ======================================================================
   4010    FUNCTION
   4011    omx_venc::ReleaseInputDone
   4012 
   4013    DESCRIPTION
   4014    Checks if IL client has released all the buffers.
   4015 
   4016    PARAMETERS
   4017    None.
   4018 
   4019    RETURN VALUE
   4020    true/false
   4021 
   4022    ========================================================================== */
   4023 bool omx_video::release_input_done(void)
   4024 {
   4025     bool bRet = false;
   4026     unsigned i=0,j=0;
   4027 
   4028     DEBUG_PRINT_LOW("Inside release_input_done()");
   4029     if (m_inp_mem_ptr) {
   4030         for (; j<m_sInPortDef.nBufferCountActual; j++) {
   4031             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   4032                 break;
   4033             }
   4034         }
   4035         if (j==m_sInPortDef.nBufferCountActual) {
   4036             bRet = true;
   4037         }
   4038     } else {
   4039         bRet = true;
   4040     }
   4041     return bRet;
   4042 }
   4043 
   4044 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
   4045         OMX_BUFFERHEADERTYPE * buffer)
   4046 {
   4047 #ifdef _MSM8974_
   4048     int index = buffer - m_out_mem_ptr;
   4049 #endif
   4050     DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %u",
   4051             buffer->pBuffer, (unsigned)buffer->nFlags, (unsigned int)buffer->nFilledLen);
   4052     if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) {
   4053         return OMX_ErrorBadParameter;
   4054     }
   4055 
   4056     pending_output_buffers--;
   4057 
   4058     if(!secure_session) {
   4059     extra_data_handle.create_extra_data(buffer);
   4060 #ifndef _MSM8974_
   4061     if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
   4062         DEBUG_PRINT_LOW("parsing extradata");
   4063         extra_data_handle.parse_extra_data(buffer);
   4064     }
   4065 #endif
   4066     }
   4067 
   4068     /* For use buffer we need to copy the data */
   4069     if (m_pCallbacks.FillBufferDone) {
   4070         if (buffer->nFilledLen > 0) {
   4071             m_fbd_count++;
   4072 
   4073             if (dev_get_output_log_flag()) {
   4074                 dev_output_log_buffers((const char*)buffer->pBuffer, buffer->nFilledLen);
   4075             }
   4076         }
   4077 #ifdef _MSM8974_
   4078         if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
   4079             if (!dev_handle_extradata((void *)buffer, index))
   4080                 DEBUG_PRINT_ERROR("Failed to parse extradata");
   4081 
   4082             dev_extradata_log_buffers((char *)(((unsigned long)buffer->pBuffer + buffer->nOffset +
   4083                         buffer->nFilledLen + 3) & (~3)));
   4084         }
   4085 #endif
   4086         m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
   4087     } else {
   4088         return OMX_ErrorBadParameter;
   4089     }
   4090     return OMX_ErrorNone;
   4091 }
   4092 
   4093 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE         hComp,
   4094         OMX_BUFFERHEADERTYPE* buffer)
   4095 {
   4096     int buffer_index  = -1;
   4097 
   4098     buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
   4099     DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer);
   4100     if (buffer == NULL ||
   4101             ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
   4102         DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
   4103         return OMX_ErrorBadParameter;
   4104     }
   4105 
   4106     pending_input_buffers--;
   4107 
   4108     if (mUseProxyColorFormat &&
   4109         (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
   4110         if (!pdest_frame  && !input_flush_progress && mUsesColorConversion) {
   4111             pdest_frame = buffer;
   4112             DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
   4113             return push_input_buffer(hComp);
   4114         }
   4115         //check if empty-EOS-buffer is being returned, treat this same as the
   4116         //color-conversion case as we queued a color-conversion buffer to encoder
   4117         bool handleEmptyEosBuffer = (mEmptyEosBuffer == buffer);
   4118         if (mUsesColorConversion || handleEmptyEosBuffer) {
   4119             if (handleEmptyEosBuffer) {
   4120                 mEmptyEosBuffer = NULL;
   4121             }
   4122             // return color-conversion buffer back to the pool
   4123             DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer);
   4124             if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) {
   4125                 DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full");
   4126                 return OMX_ErrorBadParameter;
   4127             }
   4128         } else {
   4129             // We are not dealing with color-conversion, Buffer being returned
   4130             // here is client's buffer, return it back to client
   4131             if (m_pCallbacks.EmptyBufferDone && buffer) {
   4132                 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
   4133                 DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
   4134             }
   4135         }
   4136     } else if (m_pCallbacks.EmptyBufferDone) {
   4137         m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
   4138     }
   4139     return OMX_ErrorNone;
   4140 }
   4141 
   4142 void omx_video::complete_pending_buffer_done_cbs()
   4143 {
   4144     unsigned long p1;
   4145     unsigned long p2;
   4146     unsigned long ident;
   4147     omx_cmd_queue tmp_q, pending_bd_q;
   4148     pthread_mutex_lock(&m_lock);
   4149     // pop all pending GENERATE FDB from ftb queue
   4150     while (m_ftb_q.m_size) {
   4151         m_ftb_q.pop_entry(&p1,&p2,&ident);
   4152         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   4153             pending_bd_q.insert_entry(p1,p2,ident);
   4154         } else {
   4155             tmp_q.insert_entry(p1,p2,ident);
   4156         }
   4157     }
   4158     //return all non GENERATE FDB to ftb queue
   4159     while (tmp_q.m_size) {
   4160         tmp_q.pop_entry(&p1,&p2,&ident);
   4161         m_ftb_q.insert_entry(p1,p2,ident);
   4162     }
   4163     // pop all pending GENERATE EDB from etb queue
   4164     while (m_etb_q.m_size) {
   4165         m_etb_q.pop_entry(&p1,&p2,&ident);
   4166         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   4167             pending_bd_q.insert_entry(p1,p2,ident);
   4168         } else {
   4169             tmp_q.insert_entry(p1,p2,ident);
   4170         }
   4171     }
   4172     //return all non GENERATE FDB to etb queue
   4173     while (tmp_q.m_size) {
   4174         tmp_q.pop_entry(&p1,&p2,&ident);
   4175         m_etb_q.insert_entry(p1,p2,ident);
   4176     }
   4177     pthread_mutex_unlock(&m_lock);
   4178     // process all pending buffer dones
   4179     while (pending_bd_q.m_size) {
   4180         pending_bd_q.pop_entry(&p1,&p2,&ident);
   4181         switch (ident) {
   4182             case OMX_COMPONENT_GENERATE_EBD:
   4183                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   4184                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
   4185                     omx_report_error ();
   4186                 }
   4187                 break;
   4188 
   4189             case OMX_COMPONENT_GENERATE_FBD:
   4190                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   4191                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
   4192                     omx_report_error ();
   4193                 }
   4194                 break;
   4195         }
   4196     }
   4197 }
   4198 
   4199 #ifdef MAX_RES_720P
   4200 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   4201 {
   4202     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4203     if (!profileLevelType)
   4204         return OMX_ErrorBadParameter;
   4205 
   4206     if (profileLevelType->nPortIndex == 1) {
   4207         if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
   4208             if (profileLevelType->nProfileIndex == 0) {
   4209                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   4210                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
   4211             } else if (profileLevelType->nProfileIndex == 1) {
   4212                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   4213                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
   4214             } else if (profileLevelType->nProfileIndex == 2) {
   4215                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   4216                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
   4217             } else {
   4218                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
   4219                         (int)profileLevelType->nProfileIndex);
   4220                 eRet = OMX_ErrorNoMore;
   4221             }
   4222         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) {
   4223             if (profileLevelType->nProfileIndex == 0) {
   4224                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   4225                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   4226             } else {
   4227                 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex);
   4228                 eRet = OMX_ErrorNoMore;
   4229             }
   4230         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
   4231             if (profileLevelType->nProfileIndex == 0) {
   4232                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   4233                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4234             } else if (profileLevelType->nProfileIndex == 1) {
   4235                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   4236                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4237             } else {
   4238                 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex);
   4239                 eRet = OMX_ErrorNoMore;
   4240             }
   4241         }
   4242     } else {
   4243         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %d", (int)profileLevelType->nPortIndex);
   4244         eRet = OMX_ErrorBadPortIndex;
   4245     }
   4246     DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d",
   4247             (int)profileLevelType->eProfile, (int)profileLevelType->eLevel);
   4248     return eRet;
   4249 }
   4250 #endif
   4251 
   4252 #ifdef MAX_RES_1080P
   4253 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   4254 {
   4255     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4256     if (!profileLevelType)
   4257         return OMX_ErrorBadParameter;
   4258 
   4259     if (profileLevelType->nPortIndex == 1) {
   4260         if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
   4261 #if defined _MSM8974_ && !defined _MSM8226_
   4262             if (profileLevelType->nProfileIndex == 0) {
   4263                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   4264                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4265             } else if (profileLevelType->nProfileIndex == 1) {
   4266                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   4267                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4268             } else if (profileLevelType->nProfileIndex == 2) {
   4269                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   4270                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4271             } else if (profileLevelType->nProfileIndex == 3) {
   4272                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   4273                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
   4274             } else {
   4275                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   4276                         (unsigned int)profileLevelType->nProfileIndex);
   4277                 eRet = OMX_ErrorNoMore;
   4278             }
   4279 #else
   4280             if (profileLevelType->nProfileIndex == 0) {
   4281                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   4282                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4283 
   4284             } else if (profileLevelType->nProfileIndex == 1) {
   4285                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   4286                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4287             } else if (profileLevelType->nProfileIndex == 2) {
   4288                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   4289                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4290 #ifdef _MSM8226_
   4291             } else if (profileLevelType->nProfileIndex == 3) {
   4292                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   4293                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   4294 #endif
   4295             } else {
   4296                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
   4297                         (int)profileLevelType->nProfileIndex);
   4298                 eRet = OMX_ErrorNoMore;
   4299             }
   4300 #endif
   4301         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) {
   4302             if (profileLevelType->nProfileIndex == 0) {
   4303                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   4304                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   4305             } else {
   4306                 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex);
   4307                 eRet = OMX_ErrorNoMore;
   4308             }
   4309         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
   4310             if (profileLevelType->nProfileIndex == 0) {
   4311                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   4312                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4313             } else if (profileLevelType->nProfileIndex == 1) {
   4314                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   4315                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   4316             } else {
   4317                 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex);
   4318                 eRet = OMX_ErrorNoMore;
   4319             }
   4320         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) {
   4321             if (profileLevelType->nProfileIndex == 0) {
   4322                 profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
   4323                 profileLevelType->eLevel   = OMX_VIDEO_VP8Level_Version0;
   4324             } else if (profileLevelType->nProfileIndex == 1) {
   4325                 profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
   4326                 profileLevelType->eLevel   = OMX_VIDEO_VP8Level_Version1;
   4327             } else {
   4328                 DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   4329                 (unsigned int)profileLevelType->nProfileIndex);
   4330                 eRet = OMX_ErrorNoMore;
   4331             }
   4332         } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC) {
   4333             if (profileLevelType->nProfileIndex == 0) {
   4334                 profileLevelType->eProfile =  OMX_VIDEO_HEVCProfileMain;
   4335                 profileLevelType->eLevel   =  OMX_VIDEO_HEVCMainTierLevel52;
   4336             } else if (profileLevelType->nProfileIndex == 1) {
   4337                 profileLevelType->eProfile =  OMX_VIDEO_HEVCProfileMain10;
   4338                 profileLevelType->eLevel   =  OMX_VIDEO_HEVCMainTierLevel52;
   4339             } else {
   4340                 DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   4341                 (unsigned int)profileLevelType->nProfileIndex);
   4342                 eRet = OMX_ErrorNoMore;
   4343             }
   4344         } else {
   4345             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore");
   4346             eRet = OMX_ErrorNoMore;
   4347         }
   4348     } else {
   4349         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
   4350         eRet = OMX_ErrorBadPortIndex;
   4351     }
   4352     DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
   4353             (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
   4354     return eRet;
   4355 }
   4356 #endif
   4357 
   4358 #ifdef USE_ION
   4359 int omx_video::alloc_map_ion_memory(int size,
   4360         struct ion_allocation_data *alloc_data,
   4361         struct ion_fd_data *fd_data,int flag)
   4362 {
   4363     struct venc_ion buf_ion_info;
   4364     int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
   4365     if (size <=0 || !alloc_data || !fd_data) {
   4366         DEBUG_PRINT_ERROR("Invalid input to alloc_map_ion_memory");
   4367         return -EINVAL;
   4368     }
   4369 
   4370     ion_dev_flags = O_RDONLY;
   4371     ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
   4372     if (ion_device_fd < 0) {
   4373         DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed");
   4374         return ion_device_fd;
   4375     }
   4376 
   4377     if(secure_session) {
   4378         alloc_data->len = (size + (SZ_1M - 1)) & ~(SZ_1M - 1);
   4379         alloc_data->align = SZ_1M;
   4380         alloc_data->flags = ION_SECURE;
   4381         alloc_data->ION_HEAP_MASK = ION_HEAP(ION_CP_MM_HEAP_ID);
   4382         DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u align %u flags %x",
   4383                 (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
   4384                 alloc_data->flags);
   4385     } else {
   4386         alloc_data->len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
   4387         alloc_data->align = SZ_4K;
   4388         alloc_data->flags = (flag & ION_FLAG_CACHED ? ION_FLAG_CACHED : 0);
   4389 #ifdef MAX_RES_720P
   4390         alloc_data->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID);
   4391 #else
   4392         alloc_data->ION_HEAP_MASK = (ION_HEAP(MEM_HEAP_ID) |
   4393             ION_HEAP(ION_IOMMU_HEAP_ID));
   4394 #endif
   4395         DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u align %u flags %x",
   4396                 (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
   4397                 alloc_data->flags);
   4398     }
   4399 
   4400     rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
   4401     if (rc || !alloc_data->handle) {
   4402         DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc);
   4403         alloc_data->handle = 0;
   4404         close(ion_device_fd);
   4405         ion_device_fd = -1;
   4406         return ion_device_fd;
   4407     }
   4408     fd_data->handle = alloc_data->handle;
   4409     rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
   4410     if (rc) {
   4411         DEBUG_PRINT_ERROR("ION MAP failed ");
   4412         buf_ion_info.ion_alloc_data = *alloc_data;
   4413         buf_ion_info.ion_device_fd = ion_device_fd;
   4414         buf_ion_info.fd_ion_data = *fd_data;
   4415         free_ion_memory(&buf_ion_info);
   4416         fd_data->fd =-1;
   4417         ion_device_fd =-1;
   4418     }
   4419     return ion_device_fd;
   4420 }
   4421 
   4422 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
   4423 {
   4424     if (!buf_ion_info) {
   4425         DEBUG_PRINT_ERROR("Invalid input to free_ion_memory");
   4426         return;
   4427     }
   4428     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   4429                 &buf_ion_info->ion_alloc_data.handle)) {
   4430         DEBUG_PRINT_ERROR("ION free failed ");
   4431         return;
   4432     }
   4433     close(buf_ion_info->ion_device_fd);
   4434     buf_ion_info->ion_alloc_data.handle = 0;
   4435     buf_ion_info->ion_device_fd = -1;
   4436     buf_ion_info->fd_ion_data.fd = -1;
   4437 }
   4438 #endif
   4439 
   4440 #ifdef _ANDROID_ICS_
   4441 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
   4442 {
   4443     if (buffer && meta_mode_enable) {
   4444         encoder_media_buffer_type *media_ptr;
   4445         struct pmem Input_pmem;
   4446         unsigned int index_pmem = 0;
   4447         bool meta_error = false;
   4448 
   4449         index_pmem = (buffer - m_inp_mem_ptr);
   4450         if (mUsesColorConversion &&
   4451                 (index_pmem < m_sInPortDef.nBufferCountActual)) {
   4452             if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) {
   4453                 DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed");
   4454             }
   4455         } else {
   4456             media_ptr = (encoder_media_buffer_type *) buffer->pBuffer;
   4457             if (media_ptr && media_ptr->meta_handle) {
   4458                 if (media_ptr->buffer_type == kMetadataBufferTypeCameraSource &&
   4459                         media_ptr->meta_handle->numFds == 1 &&
   4460                         media_ptr->meta_handle->numInts >= 2) {
   4461                     Input_pmem.fd = media_ptr->meta_handle->data[0];
   4462                     Input_pmem.buffer = media_ptr;
   4463                     Input_pmem.size = media_ptr->meta_handle->data[2];
   4464                     Input_pmem.offset = media_ptr->meta_handle->data[1];
   4465                     DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
   4466                             Input_pmem.offset,
   4467                             Input_pmem.size);
   4468                 } else if (media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
   4469                     private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle;
   4470                     Input_pmem.buffer = media_ptr;
   4471                     Input_pmem.fd = handle->fd;
   4472                     Input_pmem.offset = 0;
   4473                     Input_pmem.size = handle->size;
   4474                 } else {
   4475                     meta_error = true;
   4476                     DEBUG_PRINT_ERROR(" Meta Error set in EBD");
   4477                 }
   4478                 if (!meta_error)
   4479                     meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
   4480                 if (meta_error) {
   4481                     DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d",
   4482                             input_flush_progress);
   4483                 }
   4484             }
   4485         }
   4486     }
   4487 }
   4488 #endif
   4489 omx_video::omx_c2d_conv::omx_c2d_conv()
   4490 {
   4491     c2dcc = NULL;
   4492     mLibHandle = NULL;
   4493     mConvertOpen = NULL;
   4494     mConvertClose = NULL;
   4495     src_format = NV12_128m;
   4496     pthread_mutex_init(&c_lock, NULL);
   4497 }
   4498 
   4499 bool omx_video::omx_c2d_conv::init()
   4500 {
   4501     bool status = true;
   4502     if (mLibHandle || mConvertOpen || mConvertClose) {
   4503         DEBUG_PRINT_ERROR("omx_c2d_conv::init called twice");
   4504         status = false;
   4505     }
   4506     if (status) {
   4507         mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY);
   4508         if (mLibHandle) {
   4509             mConvertOpen = (createC2DColorConverter_t *)
   4510                 dlsym(mLibHandle,"createC2DColorConverter");
   4511             mConvertClose = (destroyC2DColorConverter_t *)
   4512                 dlsym(mLibHandle,"destroyC2DColorConverter");
   4513             if (!mConvertOpen || !mConvertClose)
   4514                 status = false;
   4515         } else
   4516             status = false;
   4517     }
   4518     if (!status && mLibHandle) {
   4519         dlclose(mLibHandle);
   4520         mLibHandle = NULL;
   4521         mConvertOpen = NULL;
   4522         mConvertClose = NULL;
   4523     }
   4524     return status;
   4525 }
   4526 
   4527 bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr,
   4528         int dest_fd, void *dest_base, void *dest_viraddr)
   4529 {
   4530     int result;
   4531     if (!src_viraddr || !dest_viraddr || !c2dcc || !src_base || !dest_base) {
   4532         DEBUG_PRINT_ERROR("Invalid arguments omx_c2d_conv::convert");
   4533         return false;
   4534     }
   4535     pthread_mutex_lock(&c_lock);
   4536     result =  c2dcc->convertC2D(src_fd, src_base, src_viraddr,
   4537             dest_fd, dest_base, dest_viraddr);
   4538     pthread_mutex_unlock(&c_lock);
   4539     DEBUG_PRINT_LOW("Color convert status %d",result);
   4540     return ((result < 0)?false:true);
   4541 }
   4542 
   4543 bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width,
   4544         ColorConvertFormat src, ColorConvertFormat dest,unsigned int src_stride)
   4545 {
   4546     bool status = false;
   4547     pthread_mutex_lock(&c_lock);
   4548     if (!c2dcc) {
   4549         c2dcc = mConvertOpen(width, height, width, height,
   4550                 src,dest,0,src_stride);
   4551         if (c2dcc) {
   4552             src_format = src;
   4553             status = true;
   4554         } else
   4555             DEBUG_PRINT_ERROR("mConvertOpen failed");
   4556     }
   4557     pthread_mutex_unlock(&c_lock);
   4558     return status;
   4559 }
   4560 
   4561 void omx_video::omx_c2d_conv::close()
   4562 {
   4563     if (mLibHandle) {
   4564         pthread_mutex_lock(&c_lock);
   4565         if (mConvertClose && c2dcc)
   4566             mConvertClose(c2dcc);
   4567         pthread_mutex_unlock(&c_lock);
   4568         c2dcc = NULL;
   4569     }
   4570 }
   4571 omx_video::omx_c2d_conv::~omx_c2d_conv()
   4572 {
   4573     DEBUG_PRINT_HIGH("Destroy C2D instance");
   4574     if (mLibHandle) {
   4575         if (mConvertClose && c2dcc) {
   4576             pthread_mutex_lock(&c_lock);
   4577             mConvertClose(c2dcc);
   4578             pthread_mutex_unlock(&c_lock);
   4579         }
   4580         dlclose(mLibHandle);
   4581     }
   4582     c2dcc = NULL;
   4583     mLibHandle = NULL;
   4584     mConvertOpen = NULL;
   4585     mConvertClose = NULL;
   4586     pthread_mutex_destroy(&c_lock);
   4587 }
   4588 
   4589 int omx_video::omx_c2d_conv::get_src_format()
   4590 {
   4591     int format = -1;
   4592     if (src_format == NV12_128m) {
   4593         format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;
   4594     } else if (src_format == RGBA8888) {
   4595         format = HAL_PIXEL_FORMAT_RGBA_8888;
   4596     }
   4597     return format;
   4598 }
   4599 
   4600 bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size)
   4601 {
   4602     int cret = 0;
   4603     bool ret = false;
   4604     C2DBuffReq bufferreq;
   4605     if (c2dcc) {
   4606         bufferreq.size = 0;
   4607         pthread_mutex_lock(&c_lock);
   4608         cret = c2dcc->getBuffReq(port,&bufferreq);
   4609         pthread_mutex_unlock(&c_lock);
   4610         DEBUG_PRINT_LOW("Status of getbuffer is %d", cret);
   4611         ret = (cret)?false:true;
   4612         buf_size = bufferreq.size;
   4613     }
   4614     return ret;
   4615 }
   4616 
   4617 OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
   4618         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   4619 {
   4620     unsigned nBufIndex = 0;
   4621     OMX_ERRORTYPE ret = OMX_ErrorNone;
   4622     encoder_media_buffer_type *media_buffer;
   4623     private_handle_t *handle = NULL;
   4624     DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer);
   4625 
   4626     if (buffer == NULL) {
   4627         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer);
   4628         return OMX_ErrorBadParameter;
   4629     }
   4630     nBufIndex = buffer - meta_buffer_hdr;
   4631     if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
   4632         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u",
   4633                 nBufIndex);
   4634         return OMX_ErrorBadParameter;
   4635     }
   4636     media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
   4637     if ((!media_buffer || !media_buffer->meta_handle) &&
   4638             !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   4639         DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
   4640             media_buffer);
   4641         m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
   4642         return OMX_ErrorBadParameter;
   4643     } else if (media_buffer) {
   4644         handle = (private_handle_t *)media_buffer->meta_handle;
   4645     }
   4646 
   4647     if (buffer->nFilledLen > 0 && handle) {
   4648         /*Enable following code once private handle color format is
   4649             updated correctly*/
   4650         if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
   4651             mUsesColorConversion = true;
   4652         else
   4653             mUsesColorConversion = false;
   4654 
   4655         if (c2d_opened && handle->format != c2d_conv.get_src_format()) {
   4656             c2d_conv.close();
   4657             c2d_opened = false;
   4658         }
   4659         if (!c2d_opened) {
   4660             if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
   4661                 DEBUG_PRINT_INFO("open Color conv for RGBA888 W: %u, H: %u",
   4662                         (unsigned int)m_sInPortDef.format.video.nFrameWidth,
   4663                         (unsigned int)m_sInPortDef.format.video.nFrameHeight);
   4664                 if (!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
   4665                             m_sInPortDef.format.video.nFrameWidth,
   4666                             RGBA8888, NV12_128m, handle->width)) {
   4667                     m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
   4668                     DEBUG_PRINT_ERROR("Color conv open failed");
   4669                     return OMX_ErrorBadParameter;
   4670                 }
   4671                 c2d_opened = true;
   4672 #ifdef _MSM8974_
   4673                 if (!dev_set_format(handle->format))
   4674                     DEBUG_PRINT_ERROR("cannot set color format for RGBA8888");
   4675 #endif
   4676             } else if (handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE &&
   4677                     handle->format != QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m &&
   4678                     handle->format != QOMX_COLOR_FormatYVU420SemiPlanar) {
   4679                 DEBUG_PRINT_ERROR("Incorrect color format");
   4680                 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
   4681                 return OMX_ErrorBadParameter;
   4682             }
   4683         }
   4684     }
   4685     if (input_flush_progress == true) {
   4686         m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
   4687         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Input flush in progress");
   4688         return OMX_ErrorNone;
   4689     }
   4690 
   4691     if (!psource_frame) {
   4692         psource_frame = buffer;
   4693         ret = push_input_buffer(hComp);
   4694     } else {
   4695         if (!m_opq_meta_q.insert_entry((unsigned long)buffer,0,0)) {
   4696             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full");
   4697             m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
   4698             ret = OMX_ErrorBadParameter;
   4699         }
   4700     }
   4701     return ret;
   4702 }
   4703 
   4704 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp,
   4705         struct pmem &Input_pmem_info)
   4706 {
   4707 
   4708     OMX_ERRORTYPE ret = OMX_ErrorNone;
   4709     unsigned long address = 0,p2,id;
   4710 
   4711     DEBUG_PRINT_LOW("In queue Meta Buffer");
   4712     if (!psource_frame || !pdest_frame) {
   4713         DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
   4714         return OMX_ErrorBadParameter;
   4715     }
   4716 
   4717     if (psource_frame->nFilledLen > 0) {
   4718         if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
   4719             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
   4720             post_event ((unsigned long)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
   4721             ret = OMX_ErrorBadParameter;
   4722         }
   4723     }
   4724 
   4725     if (ret == OMX_ErrorNone)
   4726         ret = empty_this_buffer_proxy(hComp,psource_frame);
   4727 
   4728     if (ret == OMX_ErrorNone) {
   4729         psource_frame = NULL;
   4730         if (!psource_frame && m_opq_meta_q.m_size) {
   4731             m_opq_meta_q.pop_entry(&address,&p2,&id);
   4732             psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
   4733         }
   4734     } else {
   4735         // there has been an error and source frame has been scheduled for an EBD
   4736         psource_frame = NULL;
   4737     }
   4738     return ret;
   4739 }
   4740 
   4741 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
   4742         struct pmem &Input_pmem_info,unsigned long &index)
   4743 {
   4744 
   4745     unsigned char *uva;
   4746     OMX_ERRORTYPE ret = OMX_ErrorNone;
   4747     unsigned long address = 0,p2,id;
   4748 
   4749     DEBUG_PRINT_LOW("In Convert and queue Meta Buffer");
   4750     if (!psource_frame || !pdest_frame) {
   4751         DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
   4752         return OMX_ErrorBadParameter;
   4753     }
   4754     if (secure_session) {
   4755         DEBUG_PRINT_ERROR("cannot convert buffer during secure session");
   4756         return OMX_ErrorInvalidState;
   4757     }
   4758 
   4759     if (!psource_frame->nFilledLen) {
   4760         if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   4761             pdest_frame->nFilledLen = psource_frame->nFilledLen;
   4762             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   4763             pdest_frame->nFlags = psource_frame->nFlags;
   4764             DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer "
   4765                     "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen);
   4766         } else {
   4767             pdest_frame->nOffset = 0;
   4768             pdest_frame->nFilledLen = 0;
   4769             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   4770             pdest_frame->nFlags = psource_frame->nFlags;
   4771             DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
   4772                     pdest_frame, (unsigned int)pdest_frame->nFilledLen);
   4773         }
   4774     } else {
   4775         uva = (unsigned char *)mmap(NULL, Input_pmem_info.size,
   4776                 PROT_READ|PROT_WRITE,
   4777                 MAP_SHARED,Input_pmem_info.fd,0);
   4778         if (uva == MAP_FAILED) {
   4779             ret = OMX_ErrorBadParameter;
   4780         } else {
   4781             if (!c2d_conv.convert(Input_pmem_info.fd, uva, uva,
   4782                         m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) {
   4783                 DEBUG_PRINT_ERROR("Color Conversion failed");
   4784                 ret = OMX_ErrorBadParameter;
   4785             } else {
   4786                 unsigned int buf_size = 0;
   4787                 if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size))
   4788                     ret = OMX_ErrorBadParameter;
   4789                 else {
   4790                     pdest_frame->nOffset = 0;
   4791                     pdest_frame->nFilledLen = buf_size;
   4792                     pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   4793                     pdest_frame->nFlags = psource_frame->nFlags;
   4794                     DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
   4795                             pdest_frame, (unsigned int)pdest_frame->nFilledLen);
   4796                 }
   4797             }
   4798             munmap(uva,Input_pmem_info.size);
   4799         }
   4800     }
   4801     if (dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
   4802         DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
   4803         post_event ((unsigned long)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
   4804         ret = OMX_ErrorBadParameter;
   4805     }
   4806     if (ret == OMX_ErrorNone)
   4807         ret = empty_this_buffer_proxy(hComp,pdest_frame);
   4808     if (ret == OMX_ErrorNone) {
   4809         m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
   4810         psource_frame = NULL;
   4811         pdest_frame = NULL;
   4812         if (!psource_frame && m_opq_meta_q.m_size) {
   4813             m_opq_meta_q.pop_entry(&address,&p2,&id);
   4814             psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
   4815         }
   4816         if (!pdest_frame && m_opq_pmem_q.m_size) {
   4817             m_opq_pmem_q.pop_entry(&address,&p2,&id);
   4818             pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
   4819             DEBUG_PRINT_LOW("pdest_frame pop address is %p",pdest_frame);
   4820         }
   4821     } else {
   4822         // there has been an error and source frame has been scheduled for an EBD
   4823         psource_frame = NULL;
   4824     }
   4825     return ret;
   4826 }
   4827 
   4828 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
   4829 {
   4830     unsigned long address = 0,p2,id, index = 0;
   4831     OMX_ERRORTYPE ret = OMX_ErrorNone;
   4832 
   4833     DEBUG_PRINT_LOW("In push input buffer");
   4834     if (!psource_frame && m_opq_meta_q.m_size) {
   4835         m_opq_meta_q.pop_entry(&address,&p2,&id);
   4836         psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
   4837     }
   4838     if (!pdest_frame && m_opq_pmem_q.m_size) {
   4839         m_opq_pmem_q.pop_entry(&address,&p2,&id);
   4840         pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
   4841     }
   4842     while (psource_frame != NULL && pdest_frame != NULL &&
   4843             ret == OMX_ErrorNone) {
   4844         struct pmem Input_pmem_info;
   4845         encoder_media_buffer_type *media_buffer;
   4846         index = pdest_frame - m_inp_mem_ptr;
   4847         if (index >= m_sInPortDef.nBufferCountActual) {
   4848             DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u",
   4849                     (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual);
   4850             return OMX_ErrorBadParameter;
   4851         }
   4852 
   4853         //Meta-Buffer with empty filled-length can contain garbage handle
   4854         //Some clients queue such buffers to signal EOS. Handle this case
   4855         // separately by queueing an intermediate color-conversion buffer
   4856         // and propagate the EOS.
   4857         if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   4858             return push_empty_eos_buffer(hComp, psource_frame);
   4859         }
   4860         media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer;
   4861         /*Will enable to verify camcorder in current TIPS can be removed*/
   4862         if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
   4863             Input_pmem_info.buffer = media_buffer;
   4864             Input_pmem_info.fd = media_buffer->meta_handle->data[0];
   4865             Input_pmem_info.offset = media_buffer->meta_handle->data[1];
   4866             Input_pmem_info.size = media_buffer->meta_handle->data[2];
   4867             DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
   4868                     Input_pmem_info.offset,
   4869                     Input_pmem_info.size);
   4870             ret = queue_meta_buffer(hComp,Input_pmem_info);
   4871         } else {
   4872             private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
   4873             Input_pmem_info.buffer = media_buffer;
   4874             Input_pmem_info.fd = handle->fd;
   4875             Input_pmem_info.offset = 0;
   4876             Input_pmem_info.size = handle->size;
   4877             if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
   4878                 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
   4879             else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
   4880                     handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)
   4881                 ret = queue_meta_buffer(hComp,Input_pmem_info);
   4882             else
   4883                 ret = OMX_ErrorBadParameter;
   4884         }
   4885     }
   4886     return ret;
   4887 }
   4888 
   4889 OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp,
   4890         OMX_BUFFERHEADERTYPE* buffer) {
   4891     OMX_BUFFERHEADERTYPE* opqBuf = NULL;
   4892     OMX_ERRORTYPE retVal = OMX_ErrorNone;
   4893     unsigned index = 0;
   4894 
   4895     DEBUG_PRINT_LOW("In push empty eos buffer");
   4896     do {
   4897         if (mUsesColorConversion) {
   4898         if (pdest_frame) {
   4899             //[1] use a checked out conversion buffer, if one is available
   4900             opqBuf = pdest_frame;
   4901             pdest_frame = NULL;
   4902         } else if (m_opq_pmem_q.m_size) {
   4903             //[2] else pop out one from the queue, if available
   4904             unsigned long address = 0, p2, id;
   4905             m_opq_pmem_q.pop_entry(&address,&p2,&id);
   4906             opqBuf = (OMX_BUFFERHEADERTYPE* ) address;
   4907         }
   4908             index = opqBuf - m_inp_mem_ptr;
   4909         } else {
   4910             opqBuf = (OMX_BUFFERHEADERTYPE* ) buffer;
   4911             index = opqBuf - meta_buffer_hdr;
   4912         }
   4913 
   4914         if (!opqBuf || index >= m_sInPortDef.nBufferCountActual) {
   4915             DEBUG_PRINT_ERROR("push_empty_eos_buffer: Could not find a "
   4916                     "color-conversion buffer to queue ! defer until available");
   4917             //[3] else, returning back will defer calling this function again
   4918             //until a conversion buffer is returned by the encoder and also
   4919             //hold on to the client's buffer
   4920             return OMX_ErrorNone;
   4921         }
   4922         struct pmem Input_pmem_info;
   4923         Input_pmem_info.buffer = opqBuf;
   4924         Input_pmem_info.fd = m_pInput_pmem[index].fd;
   4925         Input_pmem_info.offset = 0;
   4926         Input_pmem_info.size = m_pInput_pmem[index].size;
   4927 
   4928         if (dev_use_buf(&Input_pmem_info, PORT_INDEX_IN, 0) != true) {
   4929             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf for empty eos buffer");
   4930             retVal = OMX_ErrorBadParameter;
   4931             break;
   4932         }
   4933 
   4934         //Queue with null pBuffer, as pBuffer in client's hdr can be junk
   4935         //Clone the color-conversion buffer to avoid overwriting original buffer
   4936         OMX_BUFFERHEADERTYPE emptyEosBufHdr;
   4937         memcpy(&emptyEosBufHdr, opqBuf, sizeof(OMX_BUFFERHEADERTYPE));
   4938         emptyEosBufHdr.nFilledLen = 0;
   4939         emptyEosBufHdr.nTimeStamp = buffer->nTimeStamp;
   4940         emptyEosBufHdr.nFlags = buffer->nFlags;
   4941         emptyEosBufHdr.pBuffer = NULL;
   4942         if (!mUsesColorConversion)
   4943             emptyEosBufHdr.nAllocLen = m_sInPortDef.nBufferSize;
   4944         if (dev_empty_buf(&emptyEosBufHdr, 0, index, m_pInput_pmem[index].fd) != true) {
   4945             DEBUG_PRINT_ERROR("ERROR: in dev_empty_buf for empty eos buffer");
   4946             dev_free_buf(&Input_pmem_info, PORT_INDEX_IN);
   4947             retVal = OMX_ErrorBadParameter;
   4948             break;
   4949         }
   4950         mEmptyEosBuffer = opqBuf;
   4951     } while(false);
   4952 
   4953     //return client's buffer regardless since intermediate color-conversion
   4954     //buffer is sent to the the encoder
   4955     m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
   4956     --pending_input_buffers;
   4957     return retVal;
   4958 }
   4959 
   4960