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