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