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