Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora 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 
     48 #define H264_SUPPORTED_WIDTH (480)
     49 #define H264_SUPPORTED_HEIGHT (368)
     50 
     51 #define MPEG4_SUPPORTED_WIDTH (480)
     52 #define MPEG4_SUPPORTED_HEIGHT (368)
     53 
     54 #define VC1_SP_MP_START_CODE        0xC5000000
     55 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
     56 #define VC1_AP_START_CODE           0x00000100
     57 #define VC1_AP_START_CODE_MASK      0xFFFFFF00
     58 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
     59 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
     60 #define VC1_SIMPLE_PROFILE          0
     61 #define VC1_MAIN_PROFILE            1
     62 #define VC1_ADVANCE_PROFILE         3
     63 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
     64 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
     65 #define VC1_STRUCT_C_LEN            4
     66 #define VC1_STRUCT_C_POS            8
     67 #define VC1_STRUCT_A_POS            12
     68 #define VC1_STRUCT_B_POS            24
     69 #define VC1_SEQ_LAYER_SIZE          36
     70 
     71 typedef struct OMXComponentCapabilityFlagsType
     72 {
     73     ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
     74     OMX_BOOL iIsOMXComponentMultiThreaded;
     75     OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
     76     OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
     77     OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
     78     OMX_BOOL iOMXComponentSupportsPartialFrames;
     79     OMX_BOOL iOMXComponentUsesNALStartCodes;
     80     OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
     81     OMX_BOOL iOMXComponentUsesFullAVCFrames;
     82 
     83 } OMXComponentCapabilityFlagsType;
     84 #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347
     85 
     86 void* message_thread(void *input)
     87 {
     88   omx_video* omx = reinterpret_cast<omx_video*>(input);
     89   unsigned char id;
     90   int n;
     91 
     92   DEBUG_PRINT_LOW("omx_venc: message thread start\n");
     93   while(1)
     94   {
     95     n = read(omx->m_pipe_in, &id, 1);
     96     if(0 == n)
     97     {
     98       break;
     99     }
    100 
    101     if(1 == n)
    102     {
    103       omx->process_event_cb(omx, id);
    104     }
    105 #ifdef QLE_BUILD
    106     if(n < 0) break;
    107 #else
    108     if((n < 0) && (errno != EINTR)) break;
    109 #endif
    110   }
    111   DEBUG_PRINT_LOW("omx_venc: message thread stop\n");
    112   return 0;
    113 }
    114 
    115 void post_message(omx_video *omx, unsigned char id)
    116 {
    117   DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id);
    118   write(omx->m_pipe_out, &id, 1);
    119 }
    120 
    121 // omx_cmd_queue destructor
    122 omx_video::omx_cmd_queue::~omx_cmd_queue()
    123 {
    124   // Nothing to do
    125 }
    126 
    127 // omx cmd queue constructor
    128 omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    129 {
    130   memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    131 }
    132 
    133 // omx cmd queue insert
    134 bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
    135 {
    136   bool ret = true;
    137   if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
    138   {
    139     m_q[m_write].id       = id;
    140     m_q[m_write].param1   = p1;
    141     m_q[m_write].param2   = p2;
    142     m_write++;
    143     m_size ++;
    144     if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
    145     {
    146       m_write = 0;
    147     }
    148   }
    149   else
    150   {
    151     ret = false;
    152     DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n");
    153   }
    154   return ret;
    155 }
    156 
    157 // omx cmd queue pop
    158 bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
    159 {
    160   bool ret = true;
    161   if(m_size > 0)
    162   {
    163     *id = m_q[m_read].id;
    164     *p1 = m_q[m_read].param1;
    165     *p2 = m_q[m_read].param2;
    166     // Move the read pointer ahead
    167     ++m_read;
    168     --m_size;
    169     if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
    170     {
    171       m_read = 0;
    172     }
    173   }
    174   else
    175   {
    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 , "/dev/pmem_adsp");
    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(): m_state(OMX_StateInvalid),
    211                         m_app_data(NULL),
    212                         m_inp_mem_ptr(NULL),
    213                         m_out_mem_ptr(NULL),
    214                         pending_input_buffers(0),
    215                         pending_output_buffers(0),
    216                         m_out_bm_count(0),
    217                         m_inp_bm_count(0),
    218                         m_flags(0),
    219                         m_event_port_settings_sent(false),
    220                         output_flush_progress (false),
    221                         input_flush_progress (false),
    222                         input_use_buffer (false),
    223                         output_use_buffer (false),
    224                         m_use_input_pmem(OMX_FALSE),
    225                         m_use_output_pmem(OMX_FALSE),
    226                         m_etb_count(0),
    227                         m_fbd_count(0)
    228 {
    229   DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()");
    230   memset(&m_cmp,0,sizeof(m_cmp));
    231   memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
    232 
    233   pthread_mutex_init(&m_lock, NULL);
    234   sem_init(&m_cmd_lock,0,0);
    235 }
    236 
    237 
    238 /* ======================================================================
    239 FUNCTION
    240   omx_venc::~omx_venc
    241 
    242 DESCRIPTION
    243   Destructor
    244 
    245 PARAMETERS
    246   None
    247 
    248 RETURN VALUE
    249   None.
    250 ========================================================================== */
    251 omx_video::~omx_video()
    252 {
    253   DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()");
    254   if(m_pipe_in) close(m_pipe_in);
    255   if(m_pipe_out) close(m_pipe_out);
    256   DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n");
    257   pthread_join(msg_thread_id,NULL);
    258   DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n");
    259   pthread_join(async_thread_id,NULL);
    260   pthread_mutex_destroy(&m_lock);
    261   sem_destroy(&m_cmd_lock);
    262   DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count,
    263       m_fbd_count);
    264   DEBUG_PRINT_HIGH("omx_video: Destructor exit\n");
    265   DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n");
    266 }
    267 
    268 /* ======================================================================
    269 FUNCTION
    270   omx_venc::OMXCntrlProcessMsgCb
    271 
    272 DESCRIPTION
    273   IL Client callbacks are generated through this routine. The decoder
    274   provides the thread context for this routine.
    275 
    276 PARAMETERS
    277   ctxt -- Context information related to the self.
    278   id   -- Event identifier. This could be any of the following:
    279           1. Command completion event
    280           2. Buffer done callback event
    281           3. Frame done callback event
    282 
    283 RETURN VALUE
    284   None.
    285 
    286 ========================================================================== */
    287 void omx_video::process_event_cb(void *ctxt, unsigned char id)
    288 {
    289   unsigned p1; // Parameter - 1
    290   unsigned p2; // Parameter - 2
    291   unsigned ident;
    292   unsigned qsize=0; // qsize
    293   omx_video *pThis = (omx_video *) ctxt;
    294 
    295   if(!pThis)
    296   {
    297     DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n");
    298     return;
    299   }
    300 
    301   // Protect the shared queue data structure
    302   do
    303   {
    304     /*Read the message id's from the queue*/
    305 
    306     pthread_mutex_lock(&pThis->m_lock);
    307     qsize = pThis->m_cmd_q.m_size;
    308     if(qsize)
    309     {
    310       pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
    311     }
    312 
    313     if(qsize == 0)
    314     {
    315       qsize = pThis->m_ftb_q.m_size;
    316       if(qsize)
    317       {
    318         pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
    319       }
    320     }
    321 
    322     if(qsize == 0)
    323     {
    324       qsize = pThis->m_etb_q.m_size;
    325       if(qsize)
    326       {
    327         pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
    328       }
    329     }
    330 
    331     pthread_mutex_unlock(&pThis->m_lock);
    332 
    333     /*process message if we have one*/
    334     if(qsize > 0)
    335     {
    336       id = ident;
    337       switch(id)
    338       {
    339       case OMX_COMPONENT_GENERATE_EVENT:
    340         if(pThis->m_pCallbacks.EventHandler)
    341         {
    342           switch(p1)
    343           {
    344           case OMX_CommandStateSet:
    345             pThis->m_state = (OMX_STATETYPE) p2;
    346             DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state);
    347             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    348                                              OMX_EventCmdComplete, p1, p2, NULL);
    349             break;
    350 
    351           case OMX_EventError:
    352             DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2);
    353             if(p2 == OMX_StateInvalid)
    354             {
    355               pThis->m_state = (OMX_STATETYPE) p2;
    356               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    357                                                OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
    358             }
    359             else if(p2 == OMX_ErrorHardware)
    360             {
    361               pThis->m_state = OMX_StateInvalid;
    362               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    363                                                OMX_EventError,OMX_ErrorHardware,0,NULL);
    364               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    365                                                OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
    366 
    367             }
    368             else
    369             {
    370               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    371                                                OMX_EventError, p2, NULL, NULL );
    372 
    373             }
    374             break;
    375 
    376           case OMX_CommandPortDisable:
    377             DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \
    378                         "state \n", p2);
    379             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    380                                              OMX_EventCmdComplete, p1, p2, NULL );
    381             break;
    382           case OMX_CommandPortEnable:
    383             DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \
    384                         , p2);
    385             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
    386                                              OMX_EventCmdComplete, p1, p2, NULL );
    387             break;
    388 
    389           default:
    390             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    391                                              OMX_EventCmdComplete, p1, p2, NULL );
    392             break;
    393 
    394           }
    395         }
    396         else
    397         {
    398           DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n");
    399         }
    400         break;
    401 
    402       case OMX_COMPONENT_GENERATE_ETB:
    403         if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    404                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
    405         {
    406           DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
    407           pThis->omx_report_error ();
    408         }
    409         break;
    410 
    411       case OMX_COMPONENT_GENERATE_FTB:
    412         if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    413                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
    414         {
    415           DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n");
    416           pThis->omx_report_error ();
    417         }
    418         break;
    419 
    420       case OMX_COMPONENT_GENERATE_COMMAND:
    421         pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
    422                                   (OMX_U32)p2,(OMX_PTR)NULL);
    423         break;
    424 
    425       case OMX_COMPONENT_GENERATE_EBD:
    426         if( pThis->empty_buffer_done(&pThis->m_cmp,
    427                                      (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
    428         {
    429           DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
    430           pThis->omx_report_error ();
    431         }
    432         break;
    433 
    434       case OMX_COMPONENT_GENERATE_FBD:
    435         if( pThis->fill_buffer_done(&pThis->m_cmp,
    436                                     (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
    437         {
    438           DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
    439           pThis->omx_report_error ();
    440         }
    441         break;
    442 
    443       case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
    444 
    445         pThis->input_flush_progress = false;
    446         DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count);
    447         m_etb_count = 0;
    448         if(pThis->m_pCallbacks.EventHandler)
    449         {
    450           /*Check if we need generate event for Flush done*/
    451           if(BITMASK_PRESENT(&pThis->m_flags,
    452                              OMX_COMPONENT_INPUT_FLUSH_PENDING))
    453           {
    454             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
    455             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    456                                              OMX_EventCmdComplete,OMX_CommandFlush,
    457                                              PORT_INDEX_IN,NULL );
    458           }
    459           else if(BITMASK_PRESENT(&pThis->m_flags,
    460                                   OMX_COMPONENT_IDLE_PENDING))
    461           {
    462             if(!pThis->output_flush_progress)
    463             {
    464               printf("\n dev_stop called after input flush complete\n");
    465               if(dev_stop() != 0)
    466               {
    467                 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n");
    468                 pThis->omx_report_error ();
    469               }
    470             }
    471           }
    472         }
    473 
    474         break;
    475 
    476       case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
    477 
    478         pThis->output_flush_progress = false;
    479         DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count);
    480         m_fbd_count = 0;
    481         if(pThis->m_pCallbacks.EventHandler)
    482         {
    483           /*Check if we need generate event for Flush done*/
    484           if(BITMASK_PRESENT(&pThis->m_flags,
    485                              OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
    486           {
    487             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
    488 
    489             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    490                                              OMX_EventCmdComplete,OMX_CommandFlush,
    491                                              PORT_INDEX_OUT,NULL );
    492           }
    493           else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
    494           {
    495             printf("\n dev_stop called after Output flush complete\n");
    496             if(!pThis->input_flush_progress)
    497             {
    498               if(dev_stop() != 0)
    499               {
    500                 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n");
    501                 pThis->omx_report_error ();
    502               }
    503             }
    504           }
    505         }
    506         break;
    507 
    508       case OMX_COMPONENT_GENERATE_START_DONE:
    509         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg");
    510 
    511         if(pThis->m_pCallbacks.EventHandler)
    512         {
    513           DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
    514           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
    515           {
    516             DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \
    517                              executing");
    518             // Send the callback now
    519             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
    520             pThis->m_state = OMX_StateExecuting;
    521             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    522                                              OMX_EventCmdComplete,OMX_CommandStateSet,
    523                                              OMX_StateExecuting, NULL);
    524           }
    525           else if(BITMASK_PRESENT(&pThis->m_flags,
    526                                   OMX_COMPONENT_PAUSE_PENDING))
    527           {
    528             if(dev_pause())
    529             {
    530               DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n");
    531               pThis->omx_report_error ();
    532             }
    533           }
    534         }
    535         else
    536         {
    537           DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
    538         }
    539         break;
    540 
    541       case OMX_COMPONENT_GENERATE_PAUSE_DONE:
    542         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
    543         if(pThis->m_pCallbacks.EventHandler)
    544         {
    545           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
    546           {
    547             //Send the callback now
    548             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
    549             pThis->m_state = OMX_StatePause;
    550             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    551                                              OMX_EventCmdComplete,OMX_CommandStateSet,
    552                                              OMX_StatePause, NULL);
    553           }
    554         }
    555 
    556         break;
    557 
    558       case OMX_COMPONENT_GENERATE_RESUME_DONE:
    559         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg");
    560         if(pThis->m_pCallbacks.EventHandler)
    561         {
    562           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
    563           {
    564             // Send the callback now
    565             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
    566             pThis->m_state = OMX_StateExecuting;
    567             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    568                                              OMX_EventCmdComplete,OMX_CommandStateSet,
    569                                              OMX_StateExecuting,NULL);
    570           }
    571         }
    572 
    573         break;
    574 
    575       case OMX_COMPONENT_GENERATE_STOP_DONE:
    576         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg");
    577         if(pThis->m_pCallbacks.EventHandler)
    578         {
    579           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
    580           {
    581             // Send the callback now
    582             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
    583             pThis->m_state = OMX_StateIdle;
    584             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
    585                                              OMX_EventCmdComplete,OMX_CommandStateSet,
    586                                              OMX_StateIdle,NULL);
    587           }
    588         }
    589 
    590         break;
    591 
    592       case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
    593         DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n");
    594         pThis->omx_report_error ();
    595         break;
    596 
    597       default:
    598         break;
    599       }
    600     }
    601 
    602     pthread_mutex_lock(&pThis->m_lock);
    603     qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
    604             pThis->m_etb_q.m_size;
    605 
    606     pthread_mutex_unlock(&pThis->m_lock);
    607 
    608   }
    609   while(qsize>0);
    610   printf("\n exited the while loop\n");
    611 
    612 }
    613 
    614 
    615 
    616 
    617 /* ======================================================================
    618 FUNCTION
    619   omx_venc::GetComponentVersion
    620 
    621 DESCRIPTION
    622   Returns the component version.
    623 
    624 PARAMETERS
    625   TBD.
    626 
    627 RETURN VALUE
    628   OMX_ErrorNone.
    629 
    630 ========================================================================== */
    631 OMX_ERRORTYPE  omx_video::get_component_version
    632 (
    633 OMX_IN OMX_HANDLETYPE hComp,
    634 OMX_OUT OMX_STRING componentName,
    635 OMX_OUT OMX_VERSIONTYPE* componentVersion,
    636 OMX_OUT OMX_VERSIONTYPE* specVersion,
    637 OMX_OUT OMX_UUIDTYPE* componentUUID
    638 )
    639 {
    640   if(m_state == OMX_StateInvalid)
    641   {
    642     DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n");
    643     return OMX_ErrorInvalidState;
    644   }
    645   /* TBD -- Return the proper version */
    646   return OMX_ErrorNone;
    647 }
    648 /* ======================================================================
    649 FUNCTION
    650   omx_venc::SendCommand
    651 
    652 DESCRIPTION
    653   Returns zero if all the buffers released..
    654 
    655 PARAMETERS
    656   None.
    657 
    658 RETURN VALUE
    659   true/false
    660 
    661 ========================================================================== */
    662 OMX_ERRORTYPE  omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
    663                                        OMX_IN OMX_COMMANDTYPE cmd,
    664                                        OMX_IN OMX_U32 param1,
    665                                        OMX_IN OMX_PTR cmdData
    666                                       )
    667 {
    668   if(m_state == OMX_StateInvalid)
    669   {
    670     DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
    671     return OMX_ErrorInvalidState;
    672   }
    673 
    674   if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable)
    675   {
    676     if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH))
    677     {
    678       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n");
    679       return OMX_ErrorBadPortIndex;
    680     }
    681   }
    682   if(cmd == OMX_CommandMarkBuffer)
    683   {
    684     if(param1 != PORT_INDEX_IN)
    685     {
    686       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n");
    687       return OMX_ErrorBadPortIndex;
    688     }
    689     if(!cmdData)
    690     {
    691       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
    692       return OMX_ErrorBadParameter;
    693     }
    694   }
    695 
    696   post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
    697   sem_wait(&m_cmd_lock);
    698   return OMX_ErrorNone;
    699 }
    700 
    701 /* ======================================================================
    702 FUNCTION
    703   omx_venc::SendCommand
    704 
    705 DESCRIPTION
    706   Returns zero if all the buffers released..
    707 
    708 PARAMETERS
    709   None.
    710 
    711 RETURN VALUE
    712   true/false
    713 
    714 ========================================================================== */
    715 OMX_ERRORTYPE  omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
    716                                              OMX_IN OMX_COMMANDTYPE cmd,
    717                                              OMX_IN OMX_U32 param1,
    718                                              OMX_IN OMX_PTR cmdData
    719                                             )
    720 {
    721   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    722   OMX_STATETYPE eState = (OMX_STATETYPE) param1;
    723   int bFlag = 1;
    724 
    725   if(cmd == OMX_CommandStateSet)
    726   {
    727     /***************************/
    728     /* Current State is Loaded */
    729     /***************************/
    730     if(m_state == OMX_StateLoaded)
    731     {
    732       if(eState == OMX_StateIdle)
    733       {
    734         //if all buffers are allocated or all ports disabled
    735         if(allocate_done() ||
    736            ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE))
    737         {
    738           DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n");
    739         }
    740         else
    741         {
    742           DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n");
    743           BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
    744           // Skip the event notification
    745           bFlag = 0;
    746         }
    747       }
    748       /* Requesting transition from Loaded to Loaded */
    749       else if(eState == OMX_StateLoaded)
    750       {
    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       {
    759         /* Since error is None , we will post an event
    760            at the end of this function definition */
    761         DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n");
    762       }
    763       /* Requesting transition from Loaded to Executing */
    764       else if(eState == OMX_StateExecuting)
    765       {
    766         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n");
    767         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    768                    OMX_COMPONENT_GENERATE_EVENT);
    769         eRet = OMX_ErrorIncorrectStateTransition;
    770       }
    771       /* Requesting transition from Loaded to Pause */
    772       else if(eState == OMX_StatePause)
    773       {
    774         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n");
    775         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    776                    OMX_COMPONENT_GENERATE_EVENT);
    777         eRet = OMX_ErrorIncorrectStateTransition;
    778       }
    779       /* Requesting transition from Loaded to Invalid */
    780       else if(eState == OMX_StateInvalid)
    781       {
    782         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n");
    783         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
    784         eRet = OMX_ErrorInvalidState;
    785       }
    786       else
    787       {
    788         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid(%d Not Handled)\n",\
    789                           eState);
    790         eRet = OMX_ErrorBadParameter;
    791       }
    792     }
    793 
    794     /***************************/
    795     /* Current State is IDLE */
    796     /***************************/
    797     else if(m_state == OMX_StateIdle)
    798     {
    799       if(eState == OMX_StateLoaded)
    800       {
    801         if(release_done())
    802         {
    803           /*
    804              Since error is None , we will post an event at the end
    805              of this function definition
    806           */
    807           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n");
    808           if(dev_stop() != 0)
    809           {
    810             DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded");
    811             eRet = OMX_ErrorHardware;
    812           }
    813         }
    814         else
    815         {
    816           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n");
    817           BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
    818           // Skip the event notification
    819           bFlag = 0;
    820         }
    821       }
    822       /* Requesting transition from Idle to Executing */
    823       else if(eState == OMX_StateExecuting)
    824       {
    825         if( dev_start() )
    826         {
    827           DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n");
    828           omx_report_error ();
    829           eRet = OMX_ErrorHardware;
    830         }
    831         else
    832         {
    833           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
    834           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
    835           bFlag = 0;
    836         }
    837 
    838       }
    839       /* Requesting transition from Idle to Idle */
    840       else if(eState == OMX_StateIdle)
    841       {
    842         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n");
    843         post_event(OMX_EventError,OMX_ErrorSameState,\
    844                    OMX_COMPONENT_GENERATE_EVENT);
    845         eRet = OMX_ErrorSameState;
    846       }
    847       /* Requesting transition from Idle to WaitForResources */
    848       else if(eState == OMX_StateWaitForResources)
    849       {
    850         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n");
    851         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    852                    OMX_COMPONENT_GENERATE_EVENT);
    853         eRet = OMX_ErrorIncorrectStateTransition;
    854       }
    855       /* Requesting transition from Idle to Pause */
    856       else if(eState == OMX_StatePause)
    857       {
    858         /*To pause the Video core we need to start the driver*/
    859         if( dev_start() )
    860         {
    861           DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n");
    862           omx_report_error ();
    863           eRet = OMX_ErrorHardware;
    864         }
    865         else
    866         {
    867           BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
    868           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
    869           bFlag = 0;
    870         }
    871       }
    872       /* Requesting transition from Idle to Invalid */
    873       else if(eState == OMX_StateInvalid)
    874       {
    875         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n");
    876         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
    877         eRet = OMX_ErrorInvalidState;
    878       }
    879       else
    880       {
    881         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState);
    882         eRet = OMX_ErrorBadParameter;
    883       }
    884     }
    885 
    886     /******************************/
    887     /* Current State is Executing */
    888     /******************************/
    889     else if(m_state == OMX_StateExecuting)
    890     {
    891       /* Requesting transition from Executing to Idle */
    892       if(eState == OMX_StateIdle)
    893       {
    894         /* Since error is None , we will post an event
    895         at the end of this function definition
    896         */
    897         DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n");
    898         //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
    899         BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
    900         execute_omx_flush(OMX_ALL);
    901         bFlag = 0;
    902       }
    903       /* Requesting transition from Executing to Paused */
    904       else if(eState == OMX_StatePause)
    905       {
    906 
    907         if(dev_pause())
    908         {
    909           DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n");
    910           post_event(OMX_EventError,OMX_ErrorHardware,\
    911                      OMX_COMPONENT_GENERATE_EVENT);
    912           eRet = OMX_ErrorHardware;
    913         }
    914         else
    915         {
    916           BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
    917           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
    918           bFlag = 0;
    919         }
    920       }
    921       /* Requesting transition from Executing to Loaded */
    922       else if(eState == OMX_StateLoaded)
    923       {
    924         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n");
    925         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    926                    OMX_COMPONENT_GENERATE_EVENT);
    927         eRet = OMX_ErrorIncorrectStateTransition;
    928       }
    929       /* Requesting transition from Executing to WaitForResources */
    930       else if(eState == OMX_StateWaitForResources)
    931       {
    932         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n");
    933         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    934                    OMX_COMPONENT_GENERATE_EVENT);
    935         eRet = OMX_ErrorIncorrectStateTransition;
    936       }
    937       /* Requesting transition from Executing to Executing */
    938       else if(eState == OMX_StateExecuting)
    939       {
    940         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n");
    941         post_event(OMX_EventError,OMX_ErrorSameState,\
    942                    OMX_COMPONENT_GENERATE_EVENT);
    943         eRet = OMX_ErrorSameState;
    944       }
    945       /* Requesting transition from Executing to Invalid */
    946       else if(eState == OMX_StateInvalid)
    947       {
    948         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n");
    949         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
    950         eRet = OMX_ErrorInvalidState;
    951       }
    952       else
    953       {
    954         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState);
    955         eRet = OMX_ErrorBadParameter;
    956       }
    957     }
    958     /***************************/
    959     /* Current State is Pause  */
    960     /***************************/
    961     else if(m_state == OMX_StatePause)
    962     {
    963       /* Requesting transition from Pause to Executing */
    964       if(eState == OMX_StateExecuting)
    965       {
    966         DEBUG_PRINT_LOW("\n Pause --> Executing \n");
    967         if( dev_resume() )
    968         {
    969           post_event(OMX_EventError,OMX_ErrorHardware,\
    970                      OMX_COMPONENT_GENERATE_EVENT);
    971           eRet = OMX_ErrorHardware;
    972         }
    973         else
    974         {
    975           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
    976           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
    977           bFlag = 0;
    978         }
    979       }
    980       /* Requesting transition from Pause to Idle */
    981       else if(eState == OMX_StateIdle)
    982       {
    983         /* Since error is None , we will post an event
    984         at the end of this function definition */
    985         DEBUG_PRINT_LOW("\n Pause --> Idle \n");
    986         BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
    987         execute_omx_flush(OMX_ALL);
    988         bFlag = 0;
    989       }
    990       /* Requesting transition from Pause to loaded */
    991       else if(eState == OMX_StateLoaded)
    992       {
    993         DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n");
    994         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
    995                    OMX_COMPONENT_GENERATE_EVENT);
    996         eRet = OMX_ErrorIncorrectStateTransition;
    997       }
    998       /* Requesting transition from Pause to WaitForResources */
    999       else if(eState == OMX_StateWaitForResources)
   1000       {
   1001         DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n");
   1002         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1003                    OMX_COMPONENT_GENERATE_EVENT);
   1004         eRet = OMX_ErrorIncorrectStateTransition;
   1005       }
   1006       /* Requesting transition from Pause to Pause */
   1007       else if(eState == OMX_StatePause)
   1008       {
   1009         DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n");
   1010         post_event(OMX_EventError,OMX_ErrorSameState,\
   1011                    OMX_COMPONENT_GENERATE_EVENT);
   1012         eRet = OMX_ErrorSameState;
   1013       }
   1014       /* Requesting transition from Pause to Invalid */
   1015       else if(eState == OMX_StateInvalid)
   1016       {
   1017         DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n");
   1018         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1019         eRet = OMX_ErrorInvalidState;
   1020       }
   1021       else
   1022       {
   1023         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState);
   1024         eRet = OMX_ErrorBadParameter;
   1025       }
   1026     }
   1027     /***************************/
   1028     /* Current State is WaitForResources  */
   1029     /***************************/
   1030     else if(m_state == OMX_StateWaitForResources)
   1031     {
   1032       /* Requesting transition from WaitForResources to Loaded */
   1033       if(eState == OMX_StateLoaded)
   1034       {
   1035         /* Since error is None , we will post an event
   1036         at the end of this function definition */
   1037         DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n");
   1038       }
   1039       /* Requesting transition from WaitForResources to WaitForResources */
   1040       else if(eState == OMX_StateWaitForResources)
   1041       {
   1042         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n");
   1043         post_event(OMX_EventError,OMX_ErrorSameState,
   1044                    OMX_COMPONENT_GENERATE_EVENT);
   1045         eRet = OMX_ErrorSameState;
   1046       }
   1047       /* Requesting transition from WaitForResources to Executing */
   1048       else if(eState == OMX_StateExecuting)
   1049       {
   1050         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n");
   1051         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1052                    OMX_COMPONENT_GENERATE_EVENT);
   1053         eRet = OMX_ErrorIncorrectStateTransition;
   1054       }
   1055       /* Requesting transition from WaitForResources to Pause */
   1056       else if(eState == OMX_StatePause)
   1057       {
   1058         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n");
   1059         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1060                    OMX_COMPONENT_GENERATE_EVENT);
   1061         eRet = OMX_ErrorIncorrectStateTransition;
   1062       }
   1063       /* Requesting transition from WaitForResources to Invalid */
   1064       else if(eState == OMX_StateInvalid)
   1065       {
   1066         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n");
   1067         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1068         eRet = OMX_ErrorInvalidState;
   1069       }
   1070       /* Requesting transition from WaitForResources to Loaded -
   1071       is NOT tested by Khronos TS */
   1072 
   1073     }
   1074     else
   1075     {
   1076       DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState);
   1077       eRet = OMX_ErrorBadParameter;
   1078     }
   1079   }
   1080   /********************************/
   1081   /* Current State is Invalid */
   1082   /*******************************/
   1083   else if(m_state == OMX_StateInvalid)
   1084   {
   1085     /* State Transition from Inavlid to any state */
   1086     if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
   1087                   || OMX_StateIdle || OMX_StateExecuting
   1088                   || OMX_StatePause || OMX_StateInvalid))
   1089     {
   1090       DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n");
   1091       post_event(OMX_EventError,OMX_ErrorInvalidState,\
   1092                  OMX_COMPONENT_GENERATE_EVENT);
   1093       eRet = OMX_ErrorInvalidState;
   1094     }
   1095   }
   1096   else if(cmd == OMX_CommandFlush)
   1097   {
   1098     if(0 == param1 || OMX_ALL == param1)
   1099     {
   1100       BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   1101     }
   1102     if(1 == param1 || OMX_ALL == param1)
   1103     {
   1104       //generate output flush event only.
   1105       BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1106     }
   1107 
   1108     execute_omx_flush(param1);
   1109     bFlag = 0;
   1110   }
   1111   else if( cmd == OMX_CommandPortEnable)
   1112   {
   1113     if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
   1114     {
   1115       m_sInPortDef.bEnabled = OMX_TRUE;
   1116 
   1117       if( (m_state == OMX_StateLoaded &&
   1118            !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   1119           || allocate_input_done())
   1120       {
   1121         post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
   1122                    OMX_COMPONENT_GENERATE_EVENT);
   1123       }
   1124       else
   1125       {
   1126         DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
   1127         BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   1128         // Skip the event notification
   1129         bFlag = 0;
   1130       }
   1131     }
   1132     if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
   1133     {
   1134       m_sOutPortDef.bEnabled = OMX_TRUE;
   1135 
   1136       if( (m_state == OMX_StateLoaded &&
   1137            !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   1138           || (allocate_output_done()))
   1139       {
   1140         post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
   1141                    OMX_COMPONENT_GENERATE_EVENT);
   1142 
   1143       }
   1144       else
   1145       {
   1146         DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
   1147         BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   1148         // Skip the event notification
   1149         bFlag = 0;
   1150       }
   1151     }
   1152   }
   1153   else if(cmd == OMX_CommandPortDisable)
   1154   {
   1155     if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
   1156     {
   1157       m_sInPortDef.bEnabled = OMX_FALSE;
   1158       if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   1159          && release_input_done())
   1160       {
   1161         post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
   1162                    OMX_COMPONENT_GENERATE_EVENT);
   1163       }
   1164       else
   1165       {
   1166         BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   1167         if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
   1168         {
   1169           execute_omx_flush(PORT_INDEX_IN);
   1170         }
   1171 
   1172         // Skip the event notification
   1173         bFlag = 0;
   1174       }
   1175     }
   1176     if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
   1177     {
   1178       m_sOutPortDef.bEnabled = OMX_FALSE;
   1179 
   1180       if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   1181          && release_output_done())
   1182       {
   1183         post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
   1184                    OMX_COMPONENT_GENERATE_EVENT);
   1185       }
   1186       else
   1187       {
   1188         BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1189         if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
   1190         {
   1191           execute_omx_flush(PORT_INDEX_OUT);
   1192         }
   1193         // Skip the event notification
   1194         bFlag = 0;
   1195 
   1196       }
   1197     }
   1198   }
   1199   else
   1200   {
   1201     DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd);
   1202     eRet = OMX_ErrorNotImplemented;
   1203   }
   1204   if(eRet == OMX_ErrorNone && bFlag)
   1205   {
   1206     post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   1207   }
   1208   sem_post(&m_cmd_lock);
   1209   return eRet;
   1210 }
   1211 
   1212 /* ======================================================================
   1213 FUNCTION
   1214   omx_venc::ExecuteOmxFlush
   1215 
   1216 DESCRIPTION
   1217   Executes the OMX flush.
   1218 
   1219 PARAMETERS
   1220   flushtype - input flush(1)/output flush(0)/ both.
   1221 
   1222 RETURN VALUE
   1223   true/false
   1224 
   1225 ========================================================================== */
   1226 bool omx_video::execute_omx_flush(OMX_U32 flushType)
   1227 {
   1228   bool bRet = false;
   1229   DEBUG_PRINT_LOW("\n execute_omx_flush -  %d\n", flushType);
   1230   if(flushType == 0 || flushType == OMX_ALL)
   1231   {
   1232     input_flush_progress = true;
   1233     //flush input only
   1234     bRet = execute_input_flush();
   1235   }
   1236   if(flushType == 1 || flushType == OMX_ALL)
   1237   {
   1238     //flush output only
   1239     output_flush_progress = true;
   1240     bRet = execute_output_flush();
   1241   }
   1242   return bRet;
   1243 }
   1244 /*=========================================================================
   1245 FUNCTION : execute_output_flush
   1246 
   1247 DESCRIPTION
   1248   Executes the OMX flush at OUTPUT PORT.
   1249 
   1250 PARAMETERS
   1251   None.
   1252 
   1253 RETURN VALUE
   1254   true/false
   1255 ==========================================================================*/
   1256 bool omx_video::execute_output_flush(void)
   1257 {
   1258   unsigned      p1 = 0; // Parameter - 1
   1259   unsigned      p2 = 0; // Parameter - 2
   1260   unsigned      ident = 0;
   1261   bool bRet = true;
   1262 
   1263   /*Generate FBD for all Buffers in the FTBq*/
   1264   DEBUG_PRINT_LOW("\n execute_output_flush\n");
   1265   pthread_mutex_lock(&m_lock);
   1266   while(m_ftb_q.m_size)
   1267   {
   1268     m_ftb_q.pop_entry(&p1,&p2,&ident);
   1269 
   1270     if(ident == OMX_COMPONENT_GENERATE_FTB )
   1271     {
   1272       pending_output_buffers++;
   1273       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1274     }
   1275     else if(ident == OMX_COMPONENT_GENERATE_FBD)
   1276     {
   1277       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1278     }
   1279   }
   1280 
   1281   pthread_mutex_unlock(&m_lock);
   1282   /*Check if there are buffers with the Driver*/
   1283   if(dev_flush(PORT_INDEX_OUT))
   1284   {
   1285     DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed");
   1286     return false;
   1287   }
   1288 
   1289   return bRet;
   1290 }
   1291 /*=========================================================================
   1292 FUNCTION : execute_input_flush
   1293 
   1294 DESCRIPTION
   1295   Executes the OMX flush at INPUT PORT.
   1296 
   1297 PARAMETERS
   1298   None.
   1299 
   1300 RETURN VALUE
   1301   true/false
   1302 ==========================================================================*/
   1303 bool omx_video::execute_input_flush(void)
   1304 {
   1305   unsigned      p1 = 0; // Parameter - 1
   1306   unsigned      p2 = 0; // Parameter - 2
   1307   unsigned      ident = 0;
   1308   bool bRet = true;
   1309 
   1310   /*Generate EBD for all Buffers in the ETBq*/
   1311   DEBUG_PRINT_LOW("\n execute_input_flush\n");
   1312 
   1313   pthread_mutex_lock(&m_lock);
   1314   while(m_etb_q.m_size)
   1315   {
   1316     m_etb_q.pop_entry(&p1,&p2,&ident);
   1317     if(ident == OMX_COMPONENT_GENERATE_ETB)
   1318     {
   1319       pending_input_buffers++;
   1320       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1321     }
   1322     else if(ident == OMX_COMPONENT_GENERATE_EBD)
   1323     {
   1324       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1325     }
   1326   }
   1327 
   1328   pthread_mutex_unlock(&m_lock);
   1329   /*Check if there are buffers with the Driver*/
   1330   if(dev_flush(PORT_INDEX_IN))
   1331   {
   1332     DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed");
   1333     return false;
   1334   }
   1335 
   1336   return bRet;
   1337 }
   1338 
   1339 
   1340 /* ======================================================================
   1341 FUNCTION
   1342   omx_venc::SendCommandEvent
   1343 
   1344 DESCRIPTION
   1345   Send the event to decoder pipe.  This is needed to generate the callbacks
   1346   in decoder thread context.
   1347 
   1348 PARAMETERS
   1349   None.
   1350 
   1351 RETURN VALUE
   1352   true/false
   1353 
   1354 ========================================================================== */
   1355 bool omx_video::post_event(unsigned int p1,
   1356                            unsigned int p2,
   1357                            unsigned int id)
   1358 {
   1359   bool bRet      =                      false;
   1360 
   1361 
   1362   pthread_mutex_lock(&m_lock);
   1363 
   1364   if( id == OMX_COMPONENT_GENERATE_FTB || \
   1365       (id == OMX_COMPONENT_GENERATE_FRAME_DONE))
   1366   {
   1367     m_ftb_q.insert_entry(p1,p2,id);
   1368   }
   1369   else if((id == OMX_COMPONENT_GENERATE_ETB) \
   1370           || (id == OMX_COMPONENT_GENERATE_EBD))
   1371   {
   1372     m_etb_q.insert_entry(p1,p2,id);
   1373   }
   1374   else
   1375   {
   1376     m_cmd_q.insert_entry(p1,p2,id);
   1377   }
   1378 
   1379   bRet = true;
   1380   DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
   1381   post_message(this, id);
   1382   pthread_mutex_unlock(&m_lock);
   1383 
   1384   return bRet;
   1385 }
   1386 
   1387 /* ======================================================================
   1388 FUNCTION
   1389   omx_venc::GetParameter
   1390 
   1391 DESCRIPTION
   1392   OMX Get Parameter method implementation
   1393 
   1394 PARAMETERS
   1395   <TBD>.
   1396 
   1397 RETURN VALUE
   1398   Error None if successful.
   1399 
   1400 ========================================================================== */
   1401 OMX_ERRORTYPE  omx_video::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   1402                                         OMX_IN OMX_INDEXTYPE paramIndex,
   1403                                         OMX_INOUT OMX_PTR     paramData)
   1404 {
   1405   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1406   unsigned int height=0,width = 0;
   1407 
   1408   DEBUG_PRINT_LOW("get_parameter: \n");
   1409   if(m_state == OMX_StateInvalid)
   1410   {
   1411     DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n");
   1412     return OMX_ErrorInvalidState;
   1413   }
   1414   if(paramData == NULL)
   1415   {
   1416     DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n");
   1417     return OMX_ErrorBadParameter;
   1418   }
   1419   switch(paramIndex)
   1420   {
   1421   case OMX_IndexParamPortDefinition:
   1422     {
   1423       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   1424       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   1425 
   1426       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
   1427       if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN)
   1428       {
   1429         DEBUG_PRINT_LOW("\n i/p actual cnt = %d\n", m_sInPortDef.nBufferCountActual);
   1430         DEBUG_PRINT_LOW("\n i/p min cnt = %d\n", m_sInPortDef.nBufferCountMin);
   1431         memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
   1432       }
   1433       else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
   1434       {
   1435         DEBUG_PRINT_LOW("\n o/p actual cnt = %d\n", m_sOutPortDef.nBufferCountActual);
   1436         DEBUG_PRINT_LOW("\n o/p min cnt = %d\n", m_sOutPortDef.nBufferCountMin);
   1437         memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
   1438       }
   1439       else
   1440       {
   1441         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1442         eRet = OMX_ErrorBadPortIndex;
   1443       }
   1444       break;
   1445     }
   1446   case OMX_IndexParamVideoInit:
   1447     {
   1448       OMX_PORT_PARAM_TYPE *portParamType =
   1449       (OMX_PORT_PARAM_TYPE *) paramData;
   1450       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
   1451 
   1452       memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
   1453       break;
   1454     }
   1455   case OMX_IndexParamVideoPortFormat:
   1456     {
   1457       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   1458       (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   1459       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
   1460 
   1461       if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
   1462       {
   1463         memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
   1464       }
   1465       else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
   1466       {
   1467         memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
   1468       }
   1469       else
   1470       {
   1471         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1472         eRet = OMX_ErrorBadPortIndex;
   1473       }
   1474       break;
   1475     }
   1476   case OMX_IndexParamVideoBitrate:
   1477     {
   1478       OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
   1479       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n");
   1480 
   1481       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
   1482       {
   1483         memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
   1484       }
   1485       else
   1486       {
   1487         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1488         eRet = OMX_ErrorBadPortIndex;
   1489       }
   1490 
   1491       break;
   1492     }
   1493   case OMX_IndexParamVideoMpeg4:
   1494     {
   1495       OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
   1496       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n");
   1497       memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
   1498       break;
   1499     }
   1500   case OMX_IndexParamVideoH263:
   1501     {
   1502       OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
   1503       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n");
   1504       memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
   1505       break;
   1506     }
   1507   case OMX_IndexParamVideoAvc:
   1508     {
   1509       OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
   1510       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n");
   1511       memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
   1512       break;
   1513     }
   1514   case OMX_IndexParamVideoProfileLevelQuerySupported:
   1515     {
   1516 
   1517       OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   1518       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n");
   1519       //TODO include all the profiles and corresponding levels
   1520       if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
   1521       {
   1522         static const OMX_U32 MPEG4Profile[][2] =
   1523         { { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level0},
   1524           { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level0b},
   1525           { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level1},
   1526           { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level2},
   1527           { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level3}};
   1528 
   1529         static const OMX_U32 nSupport = sizeof(MPEG4Profile) / (sizeof(OMX_U32) * 2);
   1530         if(pParam->nProfileIndex >= 0 && pParam->nProfileIndex < nSupport)
   1531         {
   1532           pParam->eProfile = (OMX_VIDEO_MPEG4PROFILETYPE) MPEG4Profile[pParam->nProfileIndex][0];
   1533           pParam->eLevel = (OMX_VIDEO_MPEG4LEVELTYPE) MPEG4Profile[pParam->nProfileIndex][1];
   1534         }
   1535         else
   1536         {
   1537           eRet = OMX_ErrorNoMore;
   1538         }
   1539       }
   1540       else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
   1541       {
   1542         static const OMX_U32 H263Profile[][2] =
   1543         { { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level10},
   1544           { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level20},
   1545           { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level30},
   1546           { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level45},
   1547           { (OMX_U32) OMX_VIDEO_H263ProfileISWV2, (OMX_U32) OMX_VIDEO_H263Level10},
   1548           { (OMX_U32) OMX_VIDEO_H263ProfileISWV2, (OMX_U32) OMX_VIDEO_H263Level45}};
   1549 
   1550         static const OMX_U32 nSupport = sizeof(H263Profile) / (sizeof(OMX_U32) * 2);
   1551         if(pParam->nProfileIndex >= 0 && pParam->nProfileIndex < nSupport)
   1552         {
   1553           pParam->eProfile = (OMX_VIDEO_H263PROFILETYPE) H263Profile[pParam->nProfileIndex][0];
   1554           pParam->eLevel = (OMX_VIDEO_H263LEVELTYPE) H263Profile[pParam->nProfileIndex][1];
   1555         }
   1556         else
   1557         {
   1558           eRet = OMX_ErrorNoMore;
   1559         }
   1560       }
   1561       else if(m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC)
   1562       {
   1563         //TODO
   1564       }
   1565       break;
   1566     }
   1567   case OMX_IndexParamVideoProfileLevelCurrent:
   1568     {
   1569       OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   1570       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n");
   1571       memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
   1572       break;
   1573     }
   1574     /*Component should support this port definition*/
   1575   case OMX_IndexParamAudioInit:
   1576     {
   1577       OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
   1578       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
   1579       memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
   1580       break;
   1581     }
   1582     /*Component should support this port definition*/
   1583   case OMX_IndexParamImageInit:
   1584     {
   1585       OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
   1586       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
   1587       memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
   1588       break;
   1589 
   1590     }
   1591     /*Component should support this port definition*/
   1592   case OMX_IndexParamOtherInit:
   1593     {
   1594       DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex);
   1595       eRet =OMX_ErrorUnsupportedIndex;
   1596       break;
   1597     }
   1598   case OMX_IndexParamStandardComponentRole:
   1599     {
   1600       OMX_PARAM_COMPONENTROLETYPE *comp_role;
   1601       comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   1602       comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   1603       comp_role->nSize = sizeof(*comp_role);
   1604 
   1605       DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex);
   1606       if(NULL != comp_role->cRole)
   1607       {
   1608         strncpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
   1609       }
   1610       else
   1611       {
   1612         DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex);
   1613         eRet =OMX_ErrorBadParameter;
   1614       }
   1615       break;
   1616     }
   1617     /* Added for parameter test */
   1618   case OMX_IndexParamPriorityMgmt:
   1619     {
   1620 
   1621       OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
   1622       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
   1623       memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
   1624       break;
   1625     }
   1626     /* Added for parameter test */
   1627   case OMX_IndexParamCompBufferSupplier:
   1628     {
   1629       OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   1630       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
   1631       if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN)
   1632       {
   1633         memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier));
   1634       }
   1635       else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT)
   1636       {
   1637         memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier));
   1638       }
   1639       else
   1640       {
   1641         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
   1642         eRet = OMX_ErrorBadPortIndex;
   1643       }
   1644       break;
   1645     }
   1646 
   1647   case OMX_IndexParamVideoQuantization:
   1648     {
   1649       OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
   1650       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n");
   1651       memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
   1652       break;
   1653     }
   1654 
   1655   case OMX_QcomIndexPortDefn:
   1656     //TODO
   1657     break;
   1658   case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
   1659    {
   1660         OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
   1661         DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n");
   1662         pParam->iIsOMXComponentMultiThreaded = OMX_TRUE;
   1663         pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE;
   1664         pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
   1665         pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
   1666         pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE;
   1667         pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE;
   1668         pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE;
   1669         pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
   1670         m_use_input_pmem = OMX_TRUE;
   1671         DEBUG_PRINT_LOW("Supporting capability index in encoder node");
   1672         break;
   1673    }
   1674   case OMX_IndexParamVideoSliceFMO:
   1675     {
   1676         OMX_VIDEO_PARAM_AVCSLICEFMO *avc_slice_fmo = (OMX_VIDEO_PARAM_AVCSLICEFMO*)paramData;
   1677         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoSliceFMO\n");
   1678         if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\
   1679           OMX_MAX_STRINGNAME_SIZE))
   1680         {
   1681            memcpy(avc_slice_fmo, &m_sAVCSliceFMO, sizeof(m_sAVCSliceFMO));
   1682         }
   1683         else
   1684         {
   1685           DEBUG_PRINT_ERROR("ERROR: get_parameter: AVCSliceFMO queried non-AVC codec\n");
   1686           eRet = OMX_ErrorBadParameter;
   1687         }
   1688         break;
   1689     }
   1690   default:
   1691     {
   1692       DEBUG_PRINT_ERROR("ERROR: get_parameter: unknown param %08x\n", paramIndex);
   1693       eRet =OMX_ErrorUnsupportedIndex;
   1694       break;
   1695     }
   1696 
   1697   }
   1698 
   1699   return eRet;
   1700 
   1701 }
   1702 /* ======================================================================
   1703 FUNCTION
   1704   omx_video::GetConfig
   1705 
   1706 DESCRIPTION
   1707   OMX Get Config Method implementation.
   1708 
   1709 PARAMETERS
   1710   <TBD>.
   1711 
   1712 RETURN VALUE
   1713   OMX Error None if successful.
   1714 
   1715 ========================================================================== */
   1716 OMX_ERRORTYPE  omx_video::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   1717                                      OMX_IN OMX_INDEXTYPE configIndex,
   1718                                      OMX_INOUT OMX_PTR     configData)
   1719 {
   1720   ////////////////////////////////////////////////////////////////
   1721   // Supported Config Index           Type
   1722   // =============================================================
   1723   // OMX_IndexConfigVideoBitrate      OMX_VIDEO_CONFIG_BITRATETYPE
   1724   // OMX_IndexConfigVideoFramerate    OMX_CONFIG_FRAMERATETYPE
   1725   // OMX_IndexConfigCommonRotate      OMX_CONFIG_ROTATIONTYPE
   1726   ////////////////////////////////////////////////////////////////
   1727 
   1728   if(configData == NULL)
   1729   {
   1730     DEBUG_PRINT_ERROR("ERROR: param is null");
   1731     return OMX_ErrorBadParameter;
   1732   }
   1733 
   1734   if(m_state == OMX_StateInvalid)
   1735   {
   1736     DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
   1737     return OMX_ErrorIncorrectStateOperation;
   1738   }
   1739 
   1740   //@todo need to validate params
   1741   switch(configIndex)
   1742   {
   1743   case OMX_IndexConfigVideoBitrate:
   1744     {
   1745       OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
   1746       memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
   1747       break;
   1748     }
   1749   case OMX_IndexConfigVideoFramerate:
   1750     {
   1751       OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
   1752       if(m_state != OMX_StateLoaded)
   1753       {
   1754         // we only allow this at init time!
   1755         DEBUG_PRINT_ERROR("ERROR: frame rate can only be configured in loaded state");
   1756         return OMX_ErrorIncorrectStateOperation;
   1757       }
   1758       memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
   1759       break;
   1760     }
   1761   case OMX_IndexConfigCommonRotate:
   1762     {
   1763       OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
   1764       if(m_state != OMX_StateLoaded)
   1765       {
   1766         // we only allow this at init time!
   1767         DEBUG_PRINT_ERROR("ERROR: frame rate can only be configured in loaded state",0,0,0);
   1768         return OMX_ErrorIncorrectStateOperation;
   1769       }
   1770       memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
   1771       break;
   1772     }
   1773   default:
   1774     DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
   1775     return OMX_ErrorUnsupportedIndex;
   1776   }
   1777   return OMX_ErrorNone;
   1778 
   1779 }
   1780 
   1781 /* ======================================================================
   1782 FUNCTION
   1783   omx_video::GetExtensionIndex
   1784 
   1785 DESCRIPTION
   1786   OMX GetExtensionIndex method implementaion.  <TBD>
   1787 
   1788 PARAMETERS
   1789   <TBD>.
   1790 
   1791 RETURN VALUE
   1792   OMX Error None if everything successful.
   1793 
   1794 ========================================================================== */
   1795 OMX_ERRORTYPE  omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   1796                                               OMX_IN OMX_STRING      paramName,
   1797                                               OMX_OUT OMX_INDEXTYPE* indexType)
   1798 {
   1799   DEBUG_PRINT_ERROR("ERROR: get_extension_index: Error, Not implemented\n");
   1800   if(m_state == OMX_StateInvalid)
   1801   {
   1802     DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n");
   1803     return OMX_ErrorInvalidState;
   1804   }
   1805   return OMX_ErrorNotImplemented;
   1806 }
   1807 
   1808 /* ======================================================================
   1809 FUNCTION
   1810   omx_video::GetState
   1811 
   1812 DESCRIPTION
   1813   Returns the state information back to the caller.<TBD>
   1814 
   1815 PARAMETERS
   1816   <TBD>.
   1817 
   1818 RETURN VALUE
   1819   Error None if everything is successful.
   1820 ========================================================================== */
   1821 OMX_ERRORTYPE  omx_video::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   1822                                     OMX_OUT OMX_STATETYPE* state)
   1823 {
   1824   *state = m_state;
   1825   DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
   1826   return OMX_ErrorNone;
   1827 }
   1828 
   1829 /* ======================================================================
   1830 FUNCTION
   1831   omx_video::ComponentTunnelRequest
   1832 
   1833 DESCRIPTION
   1834   OMX Component Tunnel Request method implementation. <TBD>
   1835 
   1836 PARAMETERS
   1837   None.
   1838 
   1839 RETURN VALUE
   1840   OMX Error None if everything successful.
   1841 
   1842 ========================================================================== */
   1843 OMX_ERRORTYPE  omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE                hComp,
   1844                                                    OMX_IN OMX_U32                        port,
   1845                                                    OMX_IN OMX_HANDLETYPE        peerComponent,
   1846                                                    OMX_IN OMX_U32                    peerPort,
   1847                                                    OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   1848 {
   1849   DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n");
   1850   return OMX_ErrorNotImplemented;
   1851 }
   1852 
   1853 /* ======================================================================
   1854 FUNCTION
   1855   omx_video::UseInputBuffer
   1856 
   1857 DESCRIPTION
   1858   Helper function for Use buffer in the input pin
   1859 
   1860 PARAMETERS
   1861   None.
   1862 
   1863 RETURN VALUE
   1864   true/false
   1865 
   1866 ========================================================================== */
   1867 OMX_ERRORTYPE  omx_video::use_input_buffer(
   1868                                           OMX_IN OMX_HANDLETYPE            hComp,
   1869                                           OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   1870                                           OMX_IN OMX_U32                   port,
   1871                                           OMX_IN OMX_PTR                   appData,
   1872                                           OMX_IN OMX_U32                   bytes,
   1873                                           OMX_IN OMX_U8*                   buffer)
   1874 {
   1875   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1876 
   1877   unsigned   i = 0;
   1878   unsigned char *buf_addr = NULL;
   1879 
   1880   DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer);
   1881   if(bytes != m_sInPortDef.nBufferSize)
   1882   {
   1883     DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! "
   1884                       "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sInPortDef.nBufferSize);
   1885     return OMX_ErrorBadParameter;
   1886   }
   1887 
   1888   if(!m_inp_mem_ptr)
   1889   {
   1890     input_use_buffer = true;
   1891     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   1892                     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
   1893     if(m_inp_mem_ptr == NULL)
   1894     {
   1895       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
   1896       return OMX_ErrorInsufficientResources;
   1897     }
   1898 
   1899     m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
   1900     if(m_pInput_pmem == NULL)
   1901     {
   1902       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
   1903       return OMX_ErrorInsufficientResources;
   1904     }
   1905     for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
   1906     {
   1907       m_pInput_pmem[i].fd = -1;
   1908     }
   1909 
   1910   }
   1911 
   1912   for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
   1913   {
   1914     if(BITMASK_ABSENT(&m_inp_bm_count,i))
   1915     {
   1916       break;
   1917     }
   1918   }
   1919 
   1920   if(i < m_sInPortDef.nBufferCountActual)
   1921   {
   1922 
   1923     *bufferHdr = (m_inp_mem_ptr + i);
   1924     BITMASK_SET(&m_inp_bm_count,i);
   1925 
   1926     (*bufferHdr)->pBuffer           = (OMX_U8 *)buffer;
   1927     (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   1928     (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
   1929     (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
   1930     (*bufferHdr)->pAppPrivate       = appData;
   1931     (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
   1932 
   1933     if(!m_use_input_pmem)
   1934     {
   1935       m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   1936       if(m_pInput_pmem[i].fd == 0)
   1937       {
   1938         m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   1939       }
   1940 
   1941       if(m_pInput_pmem[i] .fd < 0)
   1942       {
   1943         DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
   1944         return OMX_ErrorInsufficientResources;
   1945       }
   1946       m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   1947       m_pInput_pmem[i].offset = 0;
   1948       m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
   1949                                                       MAP_SHARED,m_pInput_pmem[i].fd,0);
   1950 
   1951       if(m_pInput_pmem[i].buffer == MAP_FAILED)
   1952       {
   1953         DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
   1954         return OMX_ErrorInsufficientResources;
   1955       }
   1956     }
   1957     else
   1958     {
   1959       OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
   1960       DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
   1961 
   1962       if(pParam)
   1963       {
   1964         m_pInput_pmem[i].fd = pParam->pmem_fd;
   1965         m_pInput_pmem[i].offset = pParam->offset;
   1966         m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   1967         m_pInput_pmem[i].buffer = (unsigned char *)buffer;
   1968         DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
   1969             pParam->pmem_fd, pParam->offset);
   1970       }
   1971       else
   1972       {
   1973         DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
   1974         return OMX_ErrorBadParameter;
   1975       }
   1976     }
   1977 
   1978     DEBUG_PRINT_LOW("\n use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
   1979                 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
   1980     if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN) != true)
   1981     {
   1982       DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf");
   1983       return OMX_ErrorInsufficientResources;
   1984     }
   1985   }
   1986   else
   1987   {
   1988     DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for "
   1989                       "index = %u", i);
   1990     eRet = OMX_ErrorInsufficientResources;
   1991   }
   1992 
   1993   return eRet;
   1994 }
   1995 
   1996 
   1997 
   1998 /* ======================================================================
   1999 FUNCTION
   2000   omx_video::UseOutputBuffer
   2001 
   2002 DESCRIPTION
   2003   Helper function for Use buffer in the input pin
   2004 
   2005 PARAMETERS
   2006   None.
   2007 
   2008 RETURN VALUE
   2009   true/false
   2010 
   2011 ========================================================================== */
   2012 OMX_ERRORTYPE  omx_video::use_output_buffer(
   2013                                            OMX_IN OMX_HANDLETYPE            hComp,
   2014                                            OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2015                                            OMX_IN OMX_U32                   port,
   2016                                            OMX_IN OMX_PTR                   appData,
   2017                                            OMX_IN OMX_U32                   bytes,
   2018                                            OMX_IN OMX_U8*                   buffer)
   2019 {
   2020   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2021   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   2022   unsigned                         i= 0; // Temporary counter
   2023   unsigned char *buf_addr = NULL;
   2024 
   2025   DEBUG_PRINT_HIGH("\n Inside use_output_buffer()");
   2026   if(bytes != m_sOutPortDef.nBufferSize)
   2027   {
   2028     DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! "
   2029                       "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize);
   2030     return OMX_ErrorBadParameter;
   2031   }
   2032 
   2033   if(!m_out_mem_ptr)
   2034   {
   2035     output_use_buffer = true;
   2036     int nBufHdrSize        = 0;
   2037 
   2038     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual);
   2039     nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
   2040     /*
   2041      * Memory for output side involves the following:
   2042      * 1. Array of Buffer Headers
   2043      * 2. Bitmask array to hold the buffer allocation details
   2044      * In order to minimize the memory management entire allocation
   2045      * is done in one step.
   2046      */
   2047     //OMX Buffer header
   2048     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   2049     if(m_out_mem_ptr == NULL)
   2050     {
   2051       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr");
   2052       return OMX_ErrorInsufficientResources;
   2053     }
   2054 
   2055     m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
   2056     if(m_pOutput_pmem == NULL)
   2057     {
   2058       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem");
   2059       return OMX_ErrorInsufficientResources;
   2060     }
   2061 
   2062     if(m_out_mem_ptr)
   2063     {
   2064       bufHdr          =  m_out_mem_ptr;
   2065       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
   2066 
   2067       // Settting the entire storage nicely
   2068       for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
   2069       {
   2070         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   2071         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   2072         bufHdr->nAllocLen          = bytes;
   2073         bufHdr->nFilledLen         = 0;
   2074         bufHdr->pAppPrivate        = appData;
   2075         bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
   2076         bufHdr->pBuffer            = NULL;
   2077         bufHdr++;
   2078         m_pOutput_pmem[i].fd = -1;
   2079       }
   2080     }
   2081     else
   2082     {
   2083       DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr);
   2084       eRet =  OMX_ErrorInsufficientResources;
   2085     }
   2086   }
   2087 
   2088   for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
   2089   {
   2090     if(BITMASK_ABSENT(&m_out_bm_count,i))
   2091     {
   2092       break;
   2093     }
   2094   }
   2095 
   2096   if(eRet == OMX_ErrorNone)
   2097   {
   2098     if(i < m_sOutPortDef.nBufferCountActual)
   2099     {
   2100       *bufferHdr = (m_out_mem_ptr + i );
   2101       (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
   2102       BITMASK_SET(&m_out_bm_count,i);
   2103 
   2104       if(!m_use_output_pmem)
   2105       {
   2106         m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   2107 
   2108         if(m_pOutput_pmem[i].fd == 0)
   2109         {
   2110           m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   2111         }
   2112 
   2113         if(m_pOutput_pmem[i].fd < 0)
   2114         {
   2115           DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
   2116           return OMX_ErrorInsufficientResources;
   2117         }
   2118         m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   2119         m_pOutput_pmem[i].offset = 0;
   2120         m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
   2121                                                          MAP_SHARED,m_pOutput_pmem[i].fd,0);
   2122         if(m_pOutput_pmem[i].buffer == MAP_FAILED)
   2123         {
   2124           DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
   2125           return OMX_ErrorInsufficientResources;
   2126         }
   2127       }
   2128       else
   2129       {
   2130         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
   2131         DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam);
   2132 
   2133         if(pParam)
   2134         {
   2135           DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
   2136           m_pOutput_pmem[i].fd = pParam->pmem_fd;
   2137           m_pOutput_pmem[i].offset = pParam->offset;
   2138           m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   2139           m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
   2140         }
   2141         else
   2142         {
   2143           DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
   2144           return OMX_ErrorBadParameter;
   2145         }
   2146         buf_addr = (unsigned char *)buffer;
   2147       }
   2148 
   2149       DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
   2150                 (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
   2151       if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT) != true)
   2152       {
   2153         DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
   2154         return OMX_ErrorInsufficientResources;
   2155       }
   2156     }
   2157     else
   2158     {
   2159       DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
   2160                       "index = %u", i);
   2161       eRet = OMX_ErrorInsufficientResources;
   2162     }
   2163   }
   2164   return eRet;
   2165 }
   2166 
   2167 
   2168 /* ======================================================================
   2169 FUNCTION
   2170   omx_video::UseBuffer
   2171 
   2172 DESCRIPTION
   2173   OMX Use Buffer method implementation.
   2174 
   2175 PARAMETERS
   2176   <TBD>.
   2177 
   2178 RETURN VALUE
   2179   OMX Error None , if everything successful.
   2180 
   2181 ========================================================================== */
   2182 OMX_ERRORTYPE  omx_video::use_buffer(
   2183                                     OMX_IN OMX_HANDLETYPE            hComp,
   2184                                     OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2185                                     OMX_IN OMX_U32                   port,
   2186                                     OMX_IN OMX_PTR                   appData,
   2187                                     OMX_IN OMX_U32                   bytes,
   2188                                     OMX_IN OMX_U8*                   buffer)
   2189 {
   2190   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2191   if(m_state == OMX_StateInvalid)
   2192   {
   2193     DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n");
   2194     return OMX_ErrorInvalidState;
   2195   }
   2196   if(port == PORT_INDEX_IN)
   2197   {
   2198     eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   2199   }
   2200   else if(port == PORT_INDEX_OUT)
   2201   {
   2202     eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   2203   }
   2204   else
   2205   {
   2206     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
   2207     eRet = OMX_ErrorBadPortIndex;
   2208   }
   2209 
   2210   if(eRet == OMX_ErrorNone)
   2211   {
   2212     if(allocate_done())
   2213     {
   2214       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2215       {
   2216         // Send the callback now
   2217         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   2218         post_event(OMX_CommandStateSet,OMX_StateIdle,
   2219                    OMX_COMPONENT_GENERATE_EVENT);
   2220       }
   2221     }
   2222     if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
   2223     {
   2224       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
   2225       {
   2226         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2227         post_event(OMX_CommandPortEnable,
   2228                    PORT_INDEX_IN,
   2229                    OMX_COMPONENT_GENERATE_EVENT);
   2230       }
   2231 
   2232     }
   2233     else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
   2234     {
   2235       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
   2236       {
   2237         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   2238         post_event(OMX_CommandPortEnable,
   2239                    PORT_INDEX_OUT,
   2240                    OMX_COMPONENT_GENERATE_EVENT);
   2241         m_event_port_settings_sent = false;
   2242       }
   2243     }
   2244   }
   2245   return eRet;
   2246 }
   2247 
   2248 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   2249 {
   2250   unsigned int index = 0;
   2251   OMX_U8 *temp_buff ;
   2252 
   2253   if(bufferHdr == NULL || m_inp_mem_ptr == NULL)
   2254   {
   2255     DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
   2256       bufferHdr, m_inp_mem_ptr);
   2257     return OMX_ErrorBadParameter;
   2258   }
   2259 
   2260   index = bufferHdr - m_inp_mem_ptr;
   2261 
   2262   if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem)
   2263   {
   2264     if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false)
   2265     {
   2266       DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case");
   2267       if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
   2268       {
   2269         DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf");
   2270       }
   2271       munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
   2272       close (m_pInput_pmem[index].fd);
   2273       m_pInput_pmem[index].fd = -1;
   2274     }
   2275     else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
   2276       m_use_input_pmem == OMX_FALSE))
   2277     {
   2278       DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case");
   2279       if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
   2280       {
   2281         DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf");
   2282       }
   2283       munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
   2284       close (m_pInput_pmem[index].fd);
   2285       m_pInput_pmem[index].fd = -1;
   2286     }
   2287     else
   2288     {
   2289       DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
   2290     }
   2291   }
   2292   return OMX_ErrorNone;
   2293 }
   2294 
   2295 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   2296 {
   2297   unsigned int index = 0;
   2298   OMX_U8 *temp_buff ;
   2299 
   2300   if(bufferHdr == NULL || m_out_mem_ptr == NULL)
   2301   {
   2302     DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
   2303       bufferHdr, m_out_mem_ptr);
   2304     return OMX_ErrorBadParameter;
   2305   }
   2306   index = bufferHdr - m_out_mem_ptr;
   2307 
   2308   if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem)
   2309   {
   2310     if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false )
   2311     {
   2312       DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case");
   2313       if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
   2314       {
   2315         DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
   2316       }
   2317       munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
   2318       close (m_pOutput_pmem[index].fd);
   2319       m_pOutput_pmem[index].fd = -1;
   2320     }
   2321     else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
   2322       && m_use_output_pmem == OMX_FALSE))
   2323     {
   2324       DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case");
   2325       if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
   2326       {
   2327         DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
   2328       }
   2329       munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
   2330       close (m_pOutput_pmem[index].fd);
   2331       m_pOutput_pmem[index].fd = -1;
   2332     }
   2333     else
   2334     {
   2335       DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
   2336     }
   2337   }
   2338   return OMX_ErrorNone;
   2339 }
   2340 
   2341 
   2342 /* ======================================================================
   2343 FUNCTION
   2344   omx_venc::AllocateInputBuffer
   2345 
   2346 DESCRIPTION
   2347   Helper function for allocate buffer in the input pin
   2348 
   2349 PARAMETERS
   2350   None.
   2351 
   2352 RETURN VALUE
   2353   true/false
   2354 
   2355 ========================================================================== */
   2356 OMX_ERRORTYPE  omx_video::allocate_input_buffer(
   2357                                                OMX_IN OMX_HANDLETYPE            hComp,
   2358                                                OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2359                                                OMX_IN OMX_U32                   port,
   2360                                                OMX_IN OMX_PTR                   appData,
   2361                                                OMX_IN OMX_U32                   bytes)
   2362 {
   2363 
   2364   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2365   unsigned   i = 0;
   2366 
   2367   DEBUG_PRINT_HIGH("\n allocate_input_buffer()::");
   2368   if(bytes != m_sInPortDef.nBufferSize)
   2369   {
   2370     DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n",
   2371       bytes, m_sInPortDef.nBufferSize);
   2372     return OMX_ErrorBadParameter;
   2373   }
   2374 
   2375   if(!m_inp_mem_ptr)
   2376   {
   2377     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   2378                     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
   2379     if(m_inp_mem_ptr == NULL)
   2380     {
   2381       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
   2382       return OMX_ErrorInsufficientResources;
   2383     }
   2384 
   2385     m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
   2386 
   2387     if(m_pInput_pmem == NULL)
   2388     {
   2389       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
   2390       return OMX_ErrorInsufficientResources;
   2391     }
   2392 
   2393     for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
   2394     {
   2395       m_pInput_pmem[i].fd = -1;
   2396     }
   2397   }
   2398 
   2399   for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
   2400   {
   2401     if(BITMASK_ABSENT(&m_inp_bm_count,i))
   2402     {
   2403       break;
   2404     }
   2405   }
   2406 
   2407   if(i < m_sInPortDef.nBufferCountActual)
   2408   {
   2409 
   2410     *bufferHdr = (m_inp_mem_ptr + i);
   2411     (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   2412     (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
   2413     (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
   2414     (*bufferHdr)->pAppPrivate       = appData;
   2415     (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
   2416 
   2417     m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   2418 
   2419     if(m_pInput_pmem[i].fd == 0)
   2420     {
   2421       m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   2422     }
   2423 
   2424     if(m_pInput_pmem[i].fd < 0)
   2425     {
   2426       DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n");
   2427       return OMX_ErrorInsufficientResources;
   2428     }
   2429     m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
   2430     m_pInput_pmem[i].offset = 0;
   2431 
   2432     m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
   2433                                                     MAP_SHARED,m_pInput_pmem[i].fd,0);
   2434     if(m_pInput_pmem[i].buffer == MAP_FAILED)
   2435     {
   2436       DEBUG_PRINT_ERROR("\nERROR: mmap FAILED\n");
   2437       return OMX_ErrorInsufficientResources;
   2438     }
   2439 
   2440     (*bufferHdr)->pBuffer           = (OMX_U8 *)m_pInput_pmem[i].buffer;
   2441 
   2442     BITMASK_SET(&m_inp_bm_count,i);
   2443     //here change the I/P param here from buf_adr to pmem
   2444     if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN) != true)
   2445     {
   2446       DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n");
   2447       return OMX_ErrorInsufficientResources;
   2448     }
   2449   }
   2450   else
   2451   {
   2452     DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call"
   2453                       "for index [%d]\n", i);
   2454     eRet = OMX_ErrorInsufficientResources;
   2455   }
   2456 
   2457   return eRet;
   2458 }
   2459 
   2460 
   2461 /* ======================================================================
   2462 FUNCTION
   2463   omx_venc::AllocateOutputBuffer
   2464 
   2465 DESCRIPTION
   2466   Helper fn for AllocateBuffer in the output pin
   2467 
   2468 PARAMETERS
   2469   <TBD>.
   2470 
   2471 RETURN VALUE
   2472   OMX Error None if everything went well.
   2473 
   2474 ========================================================================== */
   2475 OMX_ERRORTYPE  omx_video::allocate_output_buffer(
   2476                                                 OMX_IN OMX_HANDLETYPE            hComp,
   2477                                                 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2478                                                 OMX_IN OMX_U32                   port,
   2479                                                 OMX_IN OMX_PTR                   appData,
   2480                                                 OMX_IN OMX_U32                   bytes)
   2481 {
   2482   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2483   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   2484   unsigned                         i= 0; // Temporary counter
   2485   DEBUG_PRINT_HIGH("\n allocate_output_buffer()::");
   2486   if(!m_out_mem_ptr)
   2487   {
   2488     int nBufHdrSize        = 0;
   2489     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual);
   2490     nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
   2491 
   2492     /*
   2493      * Memory for output side involves the following:
   2494      * 1. Array of Buffer Headers
   2495      * 2. Bitmask array to hold the buffer allocation details
   2496      * In order to minimize the memory management entire allocation
   2497      * is done in one step.
   2498      */
   2499     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   2500 
   2501     m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
   2502 
   2503     if(m_out_mem_ptr && m_pOutput_pmem)
   2504     {
   2505       bufHdr          =  m_out_mem_ptr;
   2506 
   2507       for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
   2508       {
   2509         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   2510         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   2511         // Set the values when we determine the right HxW param
   2512         bufHdr->nAllocLen          = bytes;
   2513         bufHdr->nFilledLen         = 0;
   2514         bufHdr->pAppPrivate        = appData;
   2515         bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
   2516         bufHdr->pBuffer            = NULL;
   2517         bufHdr++;
   2518         m_pOutput_pmem[i].fd = -1;
   2519       }
   2520     }
   2521     else
   2522     {
   2523       DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
   2524       eRet = OMX_ErrorInsufficientResources;
   2525     }
   2526   }
   2527 
   2528   DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual);
   2529   for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
   2530   {
   2531     if(BITMASK_ABSENT(&m_out_bm_count,i))
   2532     {
   2533       DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
   2534       break;
   2535     }
   2536   }
   2537 
   2538   if(eRet == OMX_ErrorNone)
   2539   {
   2540     if(i < m_sOutPortDef.nBufferCountActual)
   2541     {
   2542       m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   2543       if(m_pOutput_pmem[i].fd == 0)
   2544       {
   2545         m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC);
   2546       }
   2547 
   2548       if(m_pOutput_pmem[i].fd < 0)
   2549       {
   2550         DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed");
   2551         return OMX_ErrorInsufficientResources;
   2552       }
   2553       m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
   2554       m_pOutput_pmem[i].offset = 0;
   2555       m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
   2556                                                        MAP_SHARED,m_pOutput_pmem[i].fd,0);
   2557       if(m_pOutput_pmem[i].buffer == MAP_FAILED)
   2558       {
   2559         DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer");
   2560         return OMX_ErrorInsufficientResources;
   2561       }
   2562 
   2563       *bufferHdr = (m_out_mem_ptr + i );
   2564       (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
   2565 
   2566       BITMASK_SET(&m_out_bm_count,i);
   2567 
   2568       if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT) != true)
   2569       {
   2570         DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf");
   2571         return OMX_ErrorInsufficientResources;
   2572       }
   2573     }
   2574     else
   2575     {
   2576       DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call"
   2577                         "for index [%d]\n", i);
   2578     }
   2579   }
   2580 
   2581   return eRet;
   2582 }
   2583 
   2584 
   2585 // AllocateBuffer  -- API Call
   2586 /* ======================================================================
   2587 FUNCTION
   2588   omx_video::AllocateBuffer
   2589 
   2590 DESCRIPTION
   2591   Returns zero if all the buffers released..
   2592 
   2593 PARAMETERS
   2594   None.
   2595 
   2596 RETURN VALUE
   2597   true/false
   2598 
   2599 ========================================================================== */
   2600 OMX_ERRORTYPE  omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   2601                                           OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   2602                                           OMX_IN OMX_U32                        port,
   2603                                           OMX_IN OMX_PTR                     appData,
   2604                                           OMX_IN OMX_U32                       bytes)
   2605 {
   2606 
   2607   OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   2608 
   2609   DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
   2610   if(m_state == OMX_StateInvalid)
   2611   {
   2612     DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n");
   2613     return OMX_ErrorInvalidState;
   2614   }
   2615 
   2616   // What if the client calls again.
   2617   if(port == PORT_INDEX_IN)
   2618   {
   2619     eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   2620   }
   2621   else if(port == PORT_INDEX_OUT)
   2622   {
   2623     eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   2624   }
   2625   else
   2626   {
   2627     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
   2628     eRet = OMX_ErrorBadPortIndex;
   2629   }
   2630   DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   2631   if(eRet == OMX_ErrorNone)
   2632   {
   2633     if(allocate_done())
   2634     {
   2635       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2636       {
   2637         // Send the callback now
   2638         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   2639         post_event(OMX_CommandStateSet,OMX_StateIdle,
   2640                    OMX_COMPONENT_GENERATE_EVENT);
   2641       }
   2642     }
   2643     if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
   2644     {
   2645       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
   2646       {
   2647         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2648         post_event(OMX_CommandPortEnable,
   2649                    PORT_INDEX_IN,
   2650                    OMX_COMPONENT_GENERATE_EVENT);
   2651       }
   2652     }
   2653     if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
   2654     {
   2655       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
   2656       {
   2657         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   2658         post_event(OMX_CommandPortEnable,
   2659                    PORT_INDEX_OUT,
   2660                    OMX_COMPONENT_GENERATE_EVENT);
   2661         m_event_port_settings_sent = false;
   2662       }
   2663     }
   2664   }
   2665   DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
   2666   return eRet;
   2667 }
   2668 
   2669 
   2670 // Free Buffer - API call
   2671 /* ======================================================================
   2672 FUNCTION
   2673   omx_video::FreeBuffer
   2674 
   2675 DESCRIPTION
   2676 
   2677 PARAMETERS
   2678   None.
   2679 
   2680 RETURN VALUE
   2681   true/false
   2682 
   2683 ========================================================================== */
   2684 OMX_ERRORTYPE  omx_video::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   2685                                       OMX_IN OMX_U32                 port,
   2686                                       OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   2687 {
   2688   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2689   unsigned int nPortIndex;
   2690 
   2691   DEBUG_PRINT_LOW("In for decoder free_buffer \n");
   2692 
   2693   if(m_state == OMX_StateIdle &&
   2694      (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
   2695   {
   2696     DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
   2697   }
   2698   else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
   2699           (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT))
   2700   {
   2701     DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
   2702   }
   2703   else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
   2704   {
   2705     DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n");
   2706     post_event(OMX_EventError,
   2707                OMX_ErrorPortUnpopulated,
   2708                OMX_COMPONENT_GENERATE_EVENT);
   2709 
   2710     return eRet;
   2711   }
   2712   else
   2713   {
   2714     DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n");
   2715     post_event(OMX_EventError,
   2716                OMX_ErrorPortUnpopulated,
   2717                OMX_COMPONENT_GENERATE_EVENT);
   2718   }
   2719 
   2720   if(port == PORT_INDEX_IN)
   2721   {
   2722     // check if the buffer is valid
   2723     nPortIndex = buffer - m_inp_mem_ptr;
   2724 
   2725     DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n",
   2726                     nPortIndex, m_sInPortDef.nBufferCountActual);
   2727     if(nPortIndex < m_sInPortDef.nBufferCountActual)
   2728     {
   2729       // Clear the bit associated with it.
   2730       BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   2731       free_input_buffer (buffer);
   2732       m_sInPortDef.bPopulated = OMX_FALSE;
   2733 
   2734       /*Free the Buffer Header*/
   2735       if(release_input_done())
   2736       {
   2737         input_use_buffer = false;
   2738         if(m_inp_mem_ptr)
   2739         {
   2740           DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n");
   2741           free (m_inp_mem_ptr);
   2742           m_inp_mem_ptr = NULL;
   2743         }
   2744         if(m_pInput_pmem)
   2745         {
   2746           DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n");
   2747           free(m_pInput_pmem);
   2748           m_pInput_pmem = NULL;
   2749         }
   2750 
   2751       }
   2752     }
   2753     else
   2754     {
   2755       DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n");
   2756       eRet = OMX_ErrorBadPortIndex;
   2757     }
   2758 
   2759     if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   2760        && release_input_done())
   2761     {
   2762       DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   2763       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   2764       post_event(OMX_CommandPortDisable,
   2765                  PORT_INDEX_IN,
   2766                  OMX_COMPONENT_GENERATE_EVENT);
   2767     }
   2768   }
   2769   else if(port == PORT_INDEX_OUT)
   2770   {
   2771     // check if the buffer is valid
   2772     nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
   2773 
   2774     DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n",
   2775                     nPortIndex, m_sOutPortDef.nBufferCountActual);
   2776     if(nPortIndex < m_sOutPortDef.nBufferCountActual)
   2777     {
   2778       // Clear the bit associated with it.
   2779       BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   2780       m_sOutPortDef.bPopulated = OMX_FALSE;
   2781       free_output_buffer (buffer);
   2782 
   2783       if(release_output_done())
   2784       {
   2785         output_use_buffer = false;
   2786         if(m_out_mem_ptr)
   2787         {
   2788           DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n");
   2789           free (m_out_mem_ptr);
   2790           m_out_mem_ptr = NULL;
   2791         }
   2792         if(m_pOutput_pmem)
   2793         {
   2794           DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n");
   2795           free(m_pOutput_pmem);
   2796           m_pOutput_pmem = NULL;
   2797         }
   2798       }
   2799     }
   2800     else
   2801     {
   2802       DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n");
   2803       eRet = OMX_ErrorBadPortIndex;
   2804     }
   2805     if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   2806        && release_output_done() )
   2807     {
   2808       DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
   2809 
   2810       DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   2811       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   2812       post_event(OMX_CommandPortDisable,
   2813                  PORT_INDEX_OUT,
   2814                  OMX_COMPONENT_GENERATE_EVENT);
   2815 
   2816     }
   2817   }
   2818   else
   2819   {
   2820     eRet = OMX_ErrorBadPortIndex;
   2821   }
   2822   if((eRet == OMX_ErrorNone) &&
   2823      (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
   2824   {
   2825     if(release_done())
   2826     {
   2827       if(dev_stop() != 0)
   2828       {
   2829         DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n");
   2830         eRet = OMX_ErrorHardware;
   2831       }
   2832       // Send the callback now
   2833       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   2834       post_event(OMX_CommandStateSet, OMX_StateLoaded,
   2835                  OMX_COMPONENT_GENERATE_EVENT);
   2836     }
   2837   }
   2838 
   2839   return eRet;
   2840 }
   2841 
   2842 
   2843 /* ======================================================================
   2844 FUNCTION
   2845   omx_video::EmptyThisBuffer
   2846 
   2847 DESCRIPTION
   2848   This routine is used to push the encoded video frames to
   2849   the video decoder.
   2850 
   2851 PARAMETERS
   2852   None.
   2853 
   2854 RETURN VALUE
   2855   OMX Error None if everything went successful.
   2856 
   2857 ========================================================================== */
   2858 OMX_ERRORTYPE  omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   2859                                             OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   2860 {
   2861   OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   2862   unsigned int nBufferIndex ;
   2863 
   2864   DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer);
   2865   if(m_state == OMX_StateInvalid)
   2866   {
   2867     DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n");
   2868     return OMX_ErrorInvalidState;
   2869   }
   2870 
   2871   if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
   2872   {
   2873     DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid");
   2874     return OMX_ErrorBadParameter;
   2875   }
   2876 
   2877   if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
   2878   {
   2879     DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid");
   2880     return OMX_ErrorVersionMismatch;
   2881   }
   2882 
   2883   if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN)
   2884   {
   2885     DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer");
   2886     return OMX_ErrorBadPortIndex;
   2887   }
   2888   if(!m_sInPortDef.bEnabled)
   2889   {
   2890     DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled");
   2891     return OMX_ErrorIncorrectStateOperation;
   2892   }
   2893 
   2894   nBufferIndex = buffer - m_inp_mem_ptr;
   2895 
   2896   if(nBufferIndex > m_sInPortDef.nBufferCountActual )
   2897   {
   2898     DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex);
   2899     return OMX_ErrorBadParameter;
   2900   }
   2901 
   2902   m_etb_count++;
   2903   DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
   2904   post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
   2905   return OMX_ErrorNone;
   2906 }
   2907 
   2908 
   2909 /* ======================================================================
   2910 FUNCTION
   2911   omx_video::empty_this_buffer_proxy
   2912 
   2913 DESCRIPTION
   2914   This routine is used to push the encoded video frames to
   2915   the video decoder.
   2916 
   2917 PARAMETERS
   2918   None.
   2919 
   2920 RETURN VALUE
   2921   OMX Error None if everything went successful.
   2922 
   2923 ========================================================================== */
   2924 OMX_ERRORTYPE  omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE         hComp,
   2925                                                   OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   2926 {
   2927   OMX_U8 *pmem_data_buf = NULL;
   2928   int push_cnt = 0;
   2929   unsigned nBufIndex = 0;
   2930   OMX_ERRORTYPE ret = OMX_ErrorNone;
   2931 
   2932   DEBUG_PRINT_LOW("\n ETBProxy: buffer->pBuffer[%p]\n", buffer->pBuffer);
   2933 
   2934   if(buffer == NULL)
   2935   {
   2936     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer);
   2937     return OMX_ErrorBadParameter;
   2938   }
   2939 
   2940   nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   2941 
   2942   if(nBufIndex >= m_sInPortDef.nBufferCountActual)
   2943   {
   2944     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex);
   2945     return OMX_ErrorBadParameter;
   2946   }
   2947 
   2948   pending_input_buffers++;
   2949   if(input_flush_progress == true)
   2950   {
   2951     post_event ((unsigned int)buffer,0,
   2952                 OMX_COMPONENT_GENERATE_EBD);
   2953     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress");
   2954     return OMX_ErrorNone;
   2955   }
   2956 
   2957   if(input_use_buffer && !m_use_input_pmem)
   2958   {
   2959     DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data");
   2960     pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
   2961 
   2962     memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
   2963             buffer->nFilledLen);
   2964     DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
   2965   }
   2966 
   2967   if(dev_empty_buf(buffer, pmem_data_buf) != true)
   2968   {
   2969     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed");
   2970     /*Generate an async error and move to invalid state*/
   2971     pending_input_buffers--;
   2972     return OMX_ErrorBadParameter;
   2973   }
   2974 
   2975   return ret;
   2976 }
   2977 
   2978 /* ======================================================================
   2979 FUNCTION
   2980   omx_video::FillThisBuffer
   2981 
   2982 DESCRIPTION
   2983   IL client uses this method to release the frame buffer
   2984   after displaying them.
   2985 
   2986 PARAMETERS
   2987   None.
   2988 
   2989 RETURN VALUE
   2990   true/false
   2991 
   2992 ========================================================================== */
   2993 OMX_ERRORTYPE  omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   2994                                            OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   2995 {
   2996   DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer);
   2997   if(m_state == OMX_StateInvalid)
   2998   {
   2999     DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n");
   3000     return OMX_ErrorInvalidState;
   3001   }
   3002 
   3003   if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
   3004   {
   3005     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n");
   3006     return OMX_ErrorBadParameter;
   3007   }
   3008 
   3009   if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
   3010   {
   3011     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n");
   3012     return OMX_ErrorVersionMismatch;
   3013   }
   3014 
   3015   if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT)
   3016   {
   3017     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n");
   3018     return OMX_ErrorBadPortIndex;
   3019   }
   3020 
   3021   if(!m_sOutPortDef.bEnabled)
   3022   {
   3023     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n");
   3024     return OMX_ErrorIncorrectStateOperation;
   3025   }
   3026 
   3027   post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
   3028   return OMX_ErrorNone;
   3029 }
   3030 
   3031 /* ======================================================================
   3032 FUNCTION
   3033   omx_video::fill_this_buffer_proxy
   3034 
   3035 DESCRIPTION
   3036   IL client uses this method to release the frame buffer
   3037   after displaying them.
   3038 
   3039 PARAMETERS
   3040   None.
   3041 
   3042 RETURN VALUE
   3043   true/false
   3044 
   3045 ========================================================================== */
   3046 OMX_ERRORTYPE  omx_video::fill_this_buffer_proxy(
   3047                                                 OMX_IN OMX_HANDLETYPE        hComp,
   3048                                                 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   3049 {
   3050   OMX_U8 *pmem_data_buf = NULL;
   3051   OMX_ERRORTYPE nRet = OMX_ErrorNone;
   3052 
   3053   DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer);
   3054 
   3055   if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) )
   3056   {
   3057     DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n");
   3058     return OMX_ErrorBadParameter;
   3059   }
   3060 
   3061   pending_output_buffers++;
   3062   /*Return back the output buffer to client*/
   3063   if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true)
   3064   {
   3065     DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress");
   3066     post_event ((unsigned int)bufferAdd,0,
   3067                 OMX_COMPONENT_GENERATE_FBD);
   3068     return OMX_ErrorNone;
   3069   }
   3070 
   3071   if(output_use_buffer && !m_use_output_pmem)
   3072   {
   3073     DEBUG_PRINT_LOW("\n Heap UseBuffer case");
   3074     pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
   3075   }
   3076 
   3077   if(dev_fill_buf(bufferAdd, pmem_data_buf) != true)
   3078   {
   3079     DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed");
   3080     pending_output_buffers--;
   3081     return OMX_ErrorBadParameter;
   3082   }
   3083 
   3084   return OMX_ErrorNone;
   3085 }
   3086 
   3087 /* ======================================================================
   3088 FUNCTION
   3089   omx_video::SetCallbacks
   3090 
   3091 DESCRIPTION
   3092   Set the callbacks.
   3093 
   3094 PARAMETERS
   3095   None.
   3096 
   3097 RETURN VALUE
   3098   OMX Error None if everything successful.
   3099 
   3100 ========================================================================== */
   3101 OMX_ERRORTYPE  omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   3102                                         OMX_IN OMX_CALLBACKTYPE* callbacks,
   3103                                         OMX_IN OMX_PTR             appData)
   3104 {
   3105 
   3106   m_pCallbacks       = *callbacks;
   3107   DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
   3108                m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
   3109   m_app_data =    appData;
   3110   return OMX_ErrorNotImplemented;
   3111 }
   3112 
   3113 
   3114 /* ======================================================================
   3115 FUNCTION
   3116   omx_venc::UseEGLImage
   3117 
   3118 DESCRIPTION
   3119   OMX Use EGL Image method implementation <TBD>.
   3120 
   3121 PARAMETERS
   3122   <TBD>.
   3123 
   3124 RETURN VALUE
   3125   Not Implemented error.
   3126 
   3127 ========================================================================== */
   3128 OMX_ERRORTYPE  omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE                hComp,
   3129                                         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3130                                         OMX_IN OMX_U32                        port,
   3131                                         OMX_IN OMX_PTR                     appData,
   3132                                         OMX_IN void*                      eglImage)
   3133 {
   3134   DEBUG_PRINT_ERROR("ERROR: use_EGL_image:  Not Implemented \n");
   3135   return OMX_ErrorNotImplemented;
   3136 }
   3137 
   3138 /* ======================================================================
   3139 FUNCTION
   3140   omx_venc::ComponentRoleEnum
   3141 
   3142 DESCRIPTION
   3143   OMX Component Role Enum method implementation.
   3144 
   3145 PARAMETERS
   3146   <TBD>.
   3147 
   3148 RETURN VALUE
   3149   OMX Error None if everything is successful.
   3150 ========================================================================== */
   3151 OMX_ERRORTYPE  omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   3152                                               OMX_OUT OMX_U8*        role,
   3153                                               OMX_IN OMX_U32        index)
   3154 {
   3155   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3156   if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
   3157   {
   3158     if((0 == index) && role)
   3159     {
   3160       strncpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   3161       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   3162     }
   3163     else
   3164     {
   3165       eRet = OMX_ErrorNoMore;
   3166     }
   3167   }
   3168   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
   3169   {
   3170     if((0 == index) && role)
   3171     {
   3172       strncpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   3173       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   3174     }
   3175     else
   3176     {
   3177       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
   3178       eRet = OMX_ErrorNoMore;
   3179     }
   3180   }
   3181   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
   3182   {
   3183     if((0 == index) && role)
   3184     {
   3185       strncpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   3186       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   3187     }
   3188     else
   3189     {
   3190       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
   3191       eRet = OMX_ErrorNoMore;
   3192     }
   3193   }
   3194   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
   3195   {
   3196     if((0 == index) && role)
   3197     {
   3198       strncpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   3199       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   3200     }
   3201     else
   3202     {
   3203       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
   3204       eRet = OMX_ErrorNoMore;
   3205     }
   3206   }
   3207   if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
   3208   {
   3209     if((0 == index) && role)
   3210     {
   3211       strncpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   3212       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   3213     }
   3214     else
   3215     {
   3216       eRet = OMX_ErrorNoMore;
   3217     }
   3218   }
   3219   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE))
   3220   {
   3221     if((0 == index) && role)
   3222     {
   3223       strncpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
   3224       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   3225     }
   3226     else
   3227     {
   3228       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
   3229       eRet = OMX_ErrorNoMore;
   3230     }
   3231   }
   3232   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE))
   3233   {
   3234     if((0 == index) && role)
   3235     {
   3236       strncpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
   3237       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   3238     }
   3239     else
   3240     {
   3241       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
   3242       eRet = OMX_ErrorNoMore;
   3243     }
   3244   }
   3245   else
   3246   {
   3247     DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n");
   3248     eRet = OMX_ErrorInvalidComponentName;
   3249   }
   3250   return eRet;
   3251 }
   3252 
   3253 
   3254 
   3255 
   3256 /* ======================================================================
   3257 FUNCTION
   3258   omx_venc::AllocateDone
   3259 
   3260 DESCRIPTION
   3261   Checks if entire buffer pool is allocated by IL Client or not.
   3262   Need this to move to IDLE state.
   3263 
   3264 PARAMETERS
   3265   None.
   3266 
   3267 RETURN VALUE
   3268   true/false.
   3269 
   3270 ========================================================================== */
   3271 bool omx_video::allocate_done(void)
   3272 {
   3273   bool bRet = false;
   3274   bool bRet_In = false;
   3275   bool bRet_Out = false;
   3276 
   3277   bRet_In = allocate_input_done();
   3278   bRet_Out = allocate_output_done();
   3279 
   3280   if(bRet_In && bRet_Out)
   3281   {
   3282     bRet = true;
   3283   }
   3284 
   3285   return bRet;
   3286 }
   3287 /* ======================================================================
   3288 FUNCTION
   3289   omx_venc::AllocateInputDone
   3290 
   3291 DESCRIPTION
   3292   Checks if I/P buffer pool is allocated by IL Client or not.
   3293 
   3294 PARAMETERS
   3295   None.
   3296 
   3297 RETURN VALUE
   3298   true/false.
   3299 
   3300 ========================================================================== */
   3301 bool omx_video::allocate_input_done(void)
   3302 {
   3303   bool bRet = false;
   3304   unsigned i=0;
   3305 
   3306   if(m_inp_mem_ptr == NULL)
   3307   {
   3308     return bRet;
   3309   }
   3310   if(m_inp_mem_ptr )
   3311   {
   3312     for(;i<m_sInPortDef.nBufferCountActual;i++)
   3313     {
   3314       if(BITMASK_ABSENT(&m_inp_bm_count,i))
   3315       {
   3316         break;
   3317       }
   3318     }
   3319   }
   3320   if(i==m_sInPortDef.nBufferCountActual)
   3321   {
   3322     bRet = true;
   3323   }
   3324   if(i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled)
   3325   {
   3326     m_sInPortDef.bPopulated = OMX_TRUE;
   3327   }
   3328   return bRet;
   3329 }
   3330 /* ======================================================================
   3331 FUNCTION
   3332   omx_venc::AllocateOutputDone
   3333 
   3334 DESCRIPTION
   3335   Checks if entire O/P buffer pool is allocated by IL Client or not.
   3336 
   3337 PARAMETERS
   3338   None.
   3339 
   3340 RETURN VALUE
   3341   true/false.
   3342 
   3343 ========================================================================== */
   3344 bool omx_video::allocate_output_done(void)
   3345 {
   3346   bool bRet = false;
   3347   unsigned j=0;
   3348 
   3349   if(m_out_mem_ptr == NULL)
   3350   {
   3351     return bRet;
   3352   }
   3353 
   3354   if(m_out_mem_ptr )
   3355   {
   3356     for(;j<m_sOutPortDef.nBufferCountActual;j++)
   3357     {
   3358       if(BITMASK_ABSENT(&m_out_bm_count,j))
   3359       {
   3360         break;
   3361       }
   3362     }
   3363   }
   3364 
   3365   if(j==m_sOutPortDef.nBufferCountActual)
   3366   {
   3367     bRet = true;
   3368   }
   3369 
   3370   if(j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled)
   3371   {
   3372     m_sOutPortDef.bPopulated = OMX_TRUE;
   3373   }
   3374   return bRet;
   3375 }
   3376 
   3377 /* ======================================================================
   3378 FUNCTION
   3379   omx_venc::ReleaseDone
   3380 
   3381 DESCRIPTION
   3382   Checks if IL client has released all the buffers.
   3383 
   3384 PARAMETERS
   3385   None.
   3386 
   3387 RETURN VALUE
   3388   true/false
   3389 
   3390 ========================================================================== */
   3391 bool omx_video::release_done(void)
   3392 {
   3393   bool bRet = false;
   3394   DEBUG_PRINT_LOW("Inside release_done()\n");
   3395   if(release_input_done())
   3396   {
   3397     if(release_output_done())
   3398     {
   3399       bRet = true;
   3400     }
   3401   }
   3402   return bRet;
   3403 }
   3404 
   3405 
   3406 /* ======================================================================
   3407 FUNCTION
   3408   omx_venc::ReleaseOutputDone
   3409 
   3410 DESCRIPTION
   3411   Checks if IL client has released all the buffers.
   3412 
   3413 PARAMETERS
   3414   None.
   3415 
   3416 RETURN VALUE
   3417   true/false
   3418 
   3419 ========================================================================== */
   3420 bool omx_video::release_output_done(void)
   3421 {
   3422   bool bRet = false;
   3423   unsigned i=0,j=0;
   3424 
   3425   DEBUG_PRINT_LOW("Inside release_output_done()\n");
   3426   if(m_out_mem_ptr)
   3427   {
   3428     for(;j<m_sOutPortDef.nBufferCountActual;j++)
   3429     {
   3430       if(BITMASK_PRESENT(&m_out_bm_count,j))
   3431       {
   3432         break;
   3433       }
   3434     }
   3435     if(j==m_sOutPortDef.nBufferCountActual)
   3436     {
   3437       bRet = true;
   3438     }
   3439   }
   3440   else
   3441   {
   3442     bRet = true;
   3443   }
   3444   return bRet;
   3445 }
   3446 /* ======================================================================
   3447 FUNCTION
   3448   omx_venc::ReleaseInputDone
   3449 
   3450 DESCRIPTION
   3451   Checks if IL client has released all the buffers.
   3452 
   3453 PARAMETERS
   3454   None.
   3455 
   3456 RETURN VALUE
   3457   true/false
   3458 
   3459 ========================================================================== */
   3460 bool omx_video::release_input_done(void)
   3461 {
   3462   bool bRet = false;
   3463   unsigned i=0,j=0;
   3464 
   3465   DEBUG_PRINT_LOW("Inside release_input_done()\n");
   3466   if(m_inp_mem_ptr)
   3467   {
   3468     for(;j<m_sInPortDef.nBufferCountActual;j++)
   3469     {
   3470       if( BITMASK_PRESENT(&m_inp_bm_count,j))
   3471       {
   3472         break;
   3473       }
   3474     }
   3475     if(j==m_sInPortDef.nBufferCountActual)
   3476     {
   3477       bRet = true;
   3478     }
   3479   }
   3480   else
   3481   {
   3482     bRet = true;
   3483   }
   3484   return bRet;
   3485 }
   3486 
   3487 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
   3488                                           OMX_BUFFERHEADERTYPE * buffer)
   3489 {
   3490   DEBUG_PRINT_LOW("\nfill_buffer_done: buffer->pBuffer[%p]\n", buffer->pBuffer);
   3491   if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual))
   3492   {
   3493     return OMX_ErrorBadParameter;
   3494   }
   3495 
   3496   pending_output_buffers--;
   3497 
   3498   /* For use buffer we need to copy the data */
   3499   if(m_pCallbacks.FillBufferDone)
   3500   {
   3501     if(buffer->nFilledLen > 0)
   3502     {
   3503       m_fbd_count++;
   3504     }
   3505     m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
   3506   }
   3507   else
   3508   {
   3509     return OMX_ErrorBadParameter;
   3510   }
   3511 
   3512   return OMX_ErrorNone;
   3513 }
   3514 
   3515 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE         hComp,
   3516                                            OMX_BUFFERHEADERTYPE* buffer)
   3517 {
   3518   DEBUG_PRINT_LOW("\nempty_buffer_done: buffer->pBuffer[%p]\n", buffer->pBuffer);
   3519   if(buffer == NULL || ((buffer - m_inp_mem_ptr) > m_sInPortDef.nBufferCountActual))
   3520   {
   3521     return OMX_ErrorBadParameter;
   3522   }
   3523 
   3524   pending_input_buffers--;
   3525   if(m_pCallbacks.EmptyBufferDone)
   3526   {
   3527     m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
   3528   }
   3529   return OMX_ErrorNone;
   3530 }
   3531