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