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