/*--------------------------------------------------------------------------
Copyright (c) 2010-2016, Linux Foundation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of The Linux Foundation nor
      the names of its contributors may be used to endorse or promote
      products derived from this software without specific prior written
      permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
/*============================================================================
                            O p e n M A X   w r a p p e r s
                             O p e n  M A X   C o r e

*//** @file omx_video_base.cpp
  This module contains the implementation of the OpenMAX core & component.

*//*========================================================================*/

//////////////////////////////////////////////////////////////////////////////
//                             Include Files
//////////////////////////////////////////////////////////////////////////////

#define __STDC_FORMAT_MACROS //enables the format specifiers in inttypes.h
#include <inttypes.h>
#include <string.h>
#include "omx_video_base.h"
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/prctl.h>
#ifdef _ANDROID_ICS_
#include <media/hardware/HardwareAPI.h>
#include <gralloc_priv.h>
#endif
#ifndef _ANDROID_
#include <glib.h>
#define strlcpy g_strlcpy
#endif
#define H264_SUPPORTED_WIDTH (480)
#define H264_SUPPORTED_HEIGHT (368)

#define MPEG4_SUPPORTED_WIDTH (480)
#define MPEG4_SUPPORTED_HEIGHT (368)

#define VC1_SP_MP_START_CODE        0xC5000000
#define VC1_SP_MP_START_CODE_MASK   0xFF000000
#define VC1_AP_START_CODE           0x00000100
#define VC1_AP_START_CODE_MASK      0xFFFFFF00
#define VC1_STRUCT_C_PROFILE_MASK   0xF0
#define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
#define VC1_SIMPLE_PROFILE          0
#define VC1_MAIN_PROFILE            1
#define VC1_ADVANCE_PROFILE         3
#define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
#define VC1_SIMPLE_PROFILE_MED_LEVEL  2
#define VC1_STRUCT_C_LEN            4
#define VC1_STRUCT_C_POS            8
#define VC1_STRUCT_A_POS            12
#define VC1_STRUCT_B_POS            24
#define VC1_SEQ_LAYER_SIZE          36

#define SZ_4K                       0x1000
#define SZ_1M                       0x100000

#ifndef ION_FLAG_CP_BITSTREAM
#define ION_FLAG_CP_BITSTREAM 0
#endif

#ifndef ION_FLAG_CP_PIXEL
#define ION_FLAG_CP_PIXEL 0
#endif

#undef MEM_HEAP_ID

#ifdef MASTER_SIDE_CP

#define MEM_HEAP_ID ION_SECURE_HEAP_ID
#define SECURE_ALIGN SZ_4K
#define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL)
#define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM)

#else //SLAVE_SIDE_CP

#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
#define SECURE_ALIGN SZ_1M
#define SECURE_FLAGS_INPUT_BUFFER ION_SECURE
#define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE

#endif

typedef struct OMXComponentCapabilityFlagsType {
    ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
    OMX_U32 nSize;
    OMX_VERSIONTYPE nVersion;
    OMX_BOOL iIsOMXComponentMultiThreaded;
    OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
    OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
    OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
    OMX_BOOL iOMXComponentSupportsPartialFrames;
    OMX_BOOL iOMXComponentUsesNALStartCodes;
    OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
    OMX_BOOL iOMXComponentUsesFullAVCFrames;

} OMXComponentCapabilityFlagsType;
#define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347

void* message_thread(void *input)
{
    omx_video* omx = reinterpret_cast<omx_video*>(input);
    unsigned char id;
    int n;

    fd_set readFds;
    int res = 0;
    struct timeval tv;

    DEBUG_PRINT_HIGH("omx_venc: message thread start");
    prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
    while (!omx->msg_thread_stop) {

        tv.tv_sec = 2;
        tv.tv_usec = 0;

        FD_ZERO(&readFds);
        FD_SET(omx->m_pipe_in, &readFds);

        res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv);
        if (res < 0) {
            DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno));
            continue;
        } else if (res == 0 /*timeout*/ || omx->msg_thread_stop) {
            continue;
        }

        n = read(omx->m_pipe_in, &id, 1);
        if (0 == n) {
            break;
        }

        if (1 == n) {
            omx->process_event_cb(omx, id);
        }
#ifdef QLE_BUILD
        if (n < 0) break;
#else
        if ((n < 0) && (errno != EINTR)) {
            DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
            break;
        }
#endif
    }
    DEBUG_PRINT_HIGH("omx_venc: message thread stop");
    return 0;
}

void post_message(omx_video *omx, unsigned char id)
{
    DEBUG_PRINT_LOW("omx_venc: post_message %d", id);
    int ret_value;
    ret_value = write(omx->m_pipe_out, &id, 1);
    if (ret_value <= 0) {
        DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno));
    } else {
        DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
    }
}

// omx_cmd_queue destructor
omx_video::omx_cmd_queue::~omx_cmd_queue()
{
    // Nothing to do
}

// omx cmd queue constructor
omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
{
    memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
}

// omx cmd queue insert
bool omx_video::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
{
    bool ret = true;
    if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
        m_q[m_write].id       = id;
        m_q[m_write].param1   = p1;
        m_q[m_write].param2   = p2;
        m_write++;
        m_size ++;
        if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
            m_write = 0;
        }
    } else {
        ret = false;
        DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full");
    }
    return ret;
}

// omx cmd queue pop
bool omx_video::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
{
    bool ret = true;
    if (m_size > 0) {
        *id = m_q[m_read].id;
        *p1 = m_q[m_read].param1;
        *p2 = m_q[m_read].param2;
        // Move the read pointer ahead
        ++m_read;
        --m_size;
        if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
            m_read = 0;
        }
    } else {
        ret = false;
    }
    return ret;
}

// Retrieve the first mesg type in the queue
unsigned omx_video::omx_cmd_queue::get_q_msg_type()
{
    return m_q[m_read].id;
}



#ifdef _ANDROID_
VideoHeap::VideoHeap(int fd, size_t size, void* base)
{
    // dup file descriptor, map once, use pmem
    init(dup(fd), base, size, 0 , MEM_DEVICE);
}
#endif // _ANDROID_

/* ======================================================================
   FUNCTION
   omx_venc::omx_venc

   DESCRIPTION
   Constructor

   PARAMETERS
   None

   RETURN VALUE
   None.
   ========================================================================== */
omx_video::omx_video():
    c2d_opened(false),
    psource_frame(NULL),
    pdest_frame(NULL),
    secure_session(false),
    mEmptyEosBuffer(NULL),
    m_pipe_in(-1),
    m_pipe_out(-1),
    m_pInput_pmem(NULL),
    m_pOutput_pmem(NULL),
#ifdef USE_ION
    m_pInput_ion(NULL),
    m_pOutput_ion(NULL),
#endif
    m_error_propogated(false),
    m_state(OMX_StateInvalid),
    m_app_data(NULL),
    m_use_input_pmem(OMX_FALSE),
    m_use_output_pmem(OMX_FALSE),
    m_sExtraData(0),
    m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
    m_inp_mem_ptr(NULL),
    m_out_mem_ptr(NULL),
    input_flush_progress (false),
    output_flush_progress (false),
    input_use_buffer (false),
    output_use_buffer (false),
    pending_input_buffers(0),
    pending_output_buffers(0),
    m_out_bm_count(0),
    m_inp_bm_count(0),
    m_flags(0),
    m_etb_count(0),
    m_fbd_count(0),
    m_event_port_settings_sent(false),
    hw_overload(false),
    m_graphicBufferSize(0)
{
    DEBUG_PRINT_HIGH("omx_video(): Inside Constructor()");
    memset(&m_cmp,0,sizeof(m_cmp));
    memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
    async_thread_created = false;
    msg_thread_created = false;
    msg_thread_stop = false;

    mUsesColorConversion = false;
    pthread_mutex_init(&m_lock, NULL);
    sem_init(&m_cmd_lock,0,0);
    DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr);
}


/* ======================================================================
   FUNCTION
   omx_venc::~omx_venc

   DESCRIPTION
   Destructor

   PARAMETERS
   None

   RETURN VALUE
   None.
   ========================================================================== */
omx_video::~omx_video()
{
    DEBUG_PRINT_HIGH("~omx_video(): Inside Destructor()");
    if (msg_thread_created) {
        msg_thread_stop = true;
        post_message(this, OMX_COMPONENT_CLOSE_MSG);
        DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit");
        pthread_join(msg_thread_id,NULL);
    }
    close(m_pipe_in);
    close(m_pipe_out);
    m_pipe_in = -1;
    m_pipe_out = -1;
    DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit");
    /*For V4L2 based drivers, pthread_join is done in device_close
     * so no need to do it here*/
#ifndef _MSM8974_
    if (async_thread_created)
        pthread_join(async_thread_id,NULL);
#endif
    pthread_mutex_destroy(&m_lock);
    sem_destroy(&m_cmd_lock);
    DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count,
            m_fbd_count);
    DEBUG_PRINT_HIGH("omx_video: Destructor exit");
    DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ...");
}

/* ======================================================================
   FUNCTION
   omx_venc::OMXCntrlProcessMsgCb

   DESCRIPTION
   IL Client callbacks are generated through this routine. The decoder
   provides the thread context for this routine.

   PARAMETERS
   ctxt -- Context information related to the self.
   id   -- Event identifier. This could be any of the following:
   1. Command completion event
   2. Buffer done callback event
   3. Frame done callback event

   RETURN VALUE
   None.

   ========================================================================== */
void omx_video::process_event_cb(void *ctxt, unsigned char id)
{
    unsigned long p1; // Parameter - 1
    unsigned long p2; // Parameter - 2
    unsigned long ident;
    unsigned qsize=0; // qsize
    omx_video *pThis = (omx_video *) ctxt;

    if (!pThis) {
        DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out");
        return;
    }

    // Protect the shared queue data structure
    do {
        /*Read the message id's from the queue*/

        pthread_mutex_lock(&pThis->m_lock);
        qsize = pThis->m_cmd_q.m_size;
        if (qsize) {
            pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
        }

        if (qsize == 0) {
            qsize = pThis->m_ftb_q.m_size;
            if (qsize) {
                pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
            }
        }

        if (qsize == 0) {
            qsize = pThis->m_etb_q.m_size;
            if (qsize) {
                pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
            }
        }

        pthread_mutex_unlock(&pThis->m_lock);

        /*process message if we have one*/
        if (qsize > 0) {
            id = ident;
            switch (id) {
                case OMX_COMPONENT_GENERATE_EVENT:
                    if (pThis->m_pCallbacks.EventHandler) {
                        switch (p1) {
                            case OMX_CommandStateSet:
                                pThis->m_state = (OMX_STATETYPE) p2;
                                DEBUG_PRINT_LOW("Process -> state set to %d", pThis->m_state);
                                pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                        OMX_EventCmdComplete, p1, p2, NULL);
                                break;

                            case OMX_EventError:
                                DEBUG_PRINT_ERROR("ERROR: OMX_EventError: p2 = %lu", p2);
                                if (p2 == (unsigned)OMX_ErrorHardware) {
                                    pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                            OMX_EventError,OMX_ErrorHardware,0,NULL);
                                } else {
                                    pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                            OMX_EventError, p2, 0, 0);

                                }
                                break;

                            case OMX_CommandPortDisable:
                                DEBUG_PRINT_LOW("Process -> Port %lu set to PORT_STATE_DISABLED" \
                                        "state", p2);
                                pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                        OMX_EventCmdComplete, p1, p2, NULL );
                                break;
                            case OMX_CommandPortEnable:
                                DEBUG_PRINT_LOW("Process ->Port %lu set PORT_STATE_ENABLED state" \
                                        , p2);
                                pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
                                        OMX_EventCmdComplete, p1, p2, NULL );
                                break;

                            default:
                                DEBUG_PRINT_LOW("process_event_cb forwarding EventCmdComplete %lu", p1);
                                pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                        OMX_EventCmdComplete, p1, p2, NULL );
                                break;

                        }
                    } else {
                        DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks");
                    }
                    break;
                case OMX_COMPONENT_GENERATE_ETB_OPQ:
                    DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ");
                    if (pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
                                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
                        DEBUG_PRINT_ERROR("ERROR: ETBProxy() failed!");
                        pThis->omx_report_error ();
                    }
                    break;
                case OMX_COMPONENT_GENERATE_ETB: {
                        OMX_ERRORTYPE iret;
                        DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB");
                        iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
                        if (iret == OMX_ErrorInsufficientResources) {
                            DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
                            pThis->omx_report_hw_overload ();
                        } else if (iret != OMX_ErrorNone) {
                            DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
                            pThis->omx_report_error ();
                        }
                    }
                    break;

                case OMX_COMPONENT_GENERATE_FTB:
                    if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
                                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
                        DEBUG_PRINT_ERROR("ERROR: FTBProxy() failed!");
                        pThis->omx_report_error ();
                    }
                    break;

                case OMX_COMPONENT_GENERATE_COMMAND:
                    pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
                            (OMX_U32)p2,(OMX_PTR)NULL);
                    break;

                case OMX_COMPONENT_GENERATE_EBD:
                    if ( pThis->empty_buffer_done(&pThis->m_cmp,
                                (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
                        DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
                        pThis->omx_report_error ();
                    }
                    break;

                case OMX_COMPONENT_GENERATE_FBD:
                    if ( pThis->fill_buffer_done(&pThis->m_cmp,
                                (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
                        DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
                        pThis->omx_report_error ();
                    }
                    break;

                case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:

                    pThis->input_flush_progress = false;
                    DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %" PRIu64, m_etb_count);
                    m_etb_count = 0;
                    if (pThis->m_pCallbacks.EventHandler) {
                        /*Check if we need generate event for Flush done*/
                        if (BITMASK_PRESENT(&pThis->m_flags,
                                    OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
                            BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
                            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                    OMX_EventCmdComplete,OMX_CommandFlush,
                                    PORT_INDEX_IN,NULL );
                        } else if (BITMASK_PRESENT(&pThis->m_flags,
                                    OMX_COMPONENT_IDLE_PENDING)) {
                            if (!pThis->output_flush_progress) {
                                DEBUG_PRINT_LOW("dev_stop called after input flush complete");
                                if (dev_stop() != 0) {
                                    DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in i/p flush!");
                                    pThis->omx_report_error ();
                                }
                            }
                        }
                    }

                    break;

                case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:

                    pThis->output_flush_progress = false;
                    DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %" PRIu64, m_fbd_count);
                    m_fbd_count = 0;
                    if (pThis->m_pCallbacks.EventHandler) {
                        /*Check if we need generate event for Flush done*/
                        if (BITMASK_PRESENT(&pThis->m_flags,
                                    OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
                            BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);

                            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                    OMX_EventCmdComplete,OMX_CommandFlush,
                                    PORT_INDEX_OUT,NULL );
                        } else if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
                            DEBUG_PRINT_LOW("dev_stop called after Output flush complete");
                            if (!pThis->input_flush_progress) {
                                if (dev_stop() != 0) {
                                    DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in o/p flush!");
                                    pThis->omx_report_error ();
                                }
                            }
                        }
                    }
                    break;

                case OMX_COMPONENT_GENERATE_START_DONE:
                    DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE msg");

                    if (pThis->m_pCallbacks.EventHandler) {
                        DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
                        if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
                            DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Move to \
                                    executing");
                            // Send the callback now
                            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
                            pThis->m_state = OMX_StateExecuting;
                            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                    OMX_EventCmdComplete,OMX_CommandStateSet,
                                    OMX_StateExecuting, NULL);
                        } else if (BITMASK_PRESENT(&pThis->m_flags,
                                    OMX_COMPONENT_PAUSE_PENDING)) {
                            if (dev_pause()) {
                                DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in Start Done!");
                                pThis->omx_report_error ();
                            }
                        } else if (BITMASK_PRESENT(&pThis->m_flags,
                                    OMX_COMPONENT_LOADED_START_PENDING)) {
                            if (dev_loaded_start_done()) {
                                DEBUG_PRINT_LOW("successful loaded Start Done!");
                            } else {
                                DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
                                pThis->omx_report_error ();
                            }
                            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
                        } else {
                            DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
                        }
                    } else {
                        DEBUG_PRINT_LOW("Event Handler callback is NULL");
                    }
                    break;

                case OMX_COMPONENT_GENERATE_PAUSE_DONE:
                    DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
                    if (pThis->m_pCallbacks.EventHandler) {
                        if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
                            //Send the callback now
                            pThis->complete_pending_buffer_done_cbs();
                            DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD");
                            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
                            pThis->m_state = OMX_StatePause;
                            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                    OMX_EventCmdComplete,OMX_CommandStateSet,
                                    OMX_StatePause, NULL);
                        }
                    }

                    break;

                case OMX_COMPONENT_GENERATE_RESUME_DONE:
                    DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_RESUME_DONE msg");
                    if (pThis->m_pCallbacks.EventHandler) {
                        if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
                            // Send the callback now
                            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
                            pThis->m_state = OMX_StateExecuting;
                            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
                                    OMX_EventCmdComplete,OMX_CommandStateSet,
                                    OMX_StateExecuting,NULL);
                        }
                    }

                    break;

                case OMX_COMPONENT_GENERATE_STOP_DONE:
                    DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE msg");
                    if (pThis->m_pCallbacks.EventHandler) {
                        pThis->complete_pending_buffer_done_cbs();
                        if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
                            // Send the callback now
                            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
                            pThis->m_state = OMX_StateIdle;
                            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
                                    OMX_EventCmdComplete,OMX_CommandStateSet,
                                    OMX_StateIdle,NULL);
                        } else if (BITMASK_PRESENT(&pThis->m_flags,
                                    OMX_COMPONENT_LOADED_STOP_PENDING)) {
                            if (dev_loaded_stop_done()) {
                                DEBUG_PRINT_LOW("successful loaded Stop Done!");
                            } else {
                                DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
                                pThis->omx_report_error ();
                            }
                            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
                        } else {
                            DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
                        }
                    }

                    break;

                case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
                    DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!");
                    pThis->omx_report_error ();
                    break;
#ifndef _MSM8974_
                case OMX_COMPONENT_GENERATE_LTRUSE_FAILED:
                    DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_LTRUSE_FAILED!");
                    if (pThis->m_pCallbacks.EventHandler) {
                        DEBUG_PRINT_ERROR("Sending QOMX_ErrorLTRUseFailed, p2 = 0x%x", p2);
                        pThis->m_pCallbacks.EventHandler(
                                &pThis->m_cmp, pThis->m_app_data,
                                OMX_EventError, QOMX_ErrorLTRUseFailed, NULL, NULL);
                    }
                    break;
#endif
                case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
                    DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
                    pThis->omx_report_unsupported_setting();
                    break;

                case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
                    DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
                    pThis->omx_report_hw_overload();
                    break;

                default:
                    DEBUG_PRINT_LOW("process_event_cb unknown msg id 0x%02x", id);
                    break;
            }
        }

        pthread_mutex_lock(&pThis->m_lock);
        qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
                pThis->m_etb_q.m_size;

        pthread_mutex_unlock(&pThis->m_lock);

    } while (qsize>0);
    DEBUG_PRINT_LOW("exited the while loop");

}




/* ======================================================================
   FUNCTION
   omx_venc::GetComponentVersion

   DESCRIPTION
   Returns the component version.

   PARAMETERS
   TBD.

   RETURN VALUE
   OMX_ErrorNone.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::get_component_version
(
 OMX_IN OMX_HANDLETYPE hComp,
 OMX_OUT OMX_STRING componentName,
 OMX_OUT OMX_VERSIONTYPE* componentVersion,
 OMX_OUT OMX_VERSIONTYPE* specVersion,
 OMX_OUT OMX_UUIDTYPE* componentUUID
 )
{
    (void)hComp;
    (void)componentName;
    (void)componentVersion;
    (void)componentUUID;
    if (m_state == OMX_StateInvalid) {
        DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State");
        return OMX_ErrorInvalidState;
    }
    /* TBD -- Return the proper version */
    if (specVersion) {
        specVersion->nVersion = OMX_SPEC_VERSION;
    }
    return OMX_ErrorNone;
}
/* ======================================================================
   FUNCTION
   omx_venc::SendCommand

   DESCRIPTION
   Returns zero if all the buffers released..

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
        OMX_IN OMX_COMMANDTYPE cmd,
        OMX_IN OMX_U32 param1,
        OMX_IN OMX_PTR cmdData
        )
{
    (void)hComp;
    if (m_state == OMX_StateInvalid) {
        DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
        return OMX_ErrorInvalidState;
    }

    if (cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) {
        if ((param1 != (OMX_U32)PORT_INDEX_IN) && (param1 != (OMX_U32)PORT_INDEX_OUT) && (param1 != (OMX_U32)PORT_INDEX_BOTH)) {
            DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
            return OMX_ErrorBadPortIndex;
        }
    }
    if (cmd == OMX_CommandMarkBuffer) {
        if (param1 != PORT_INDEX_IN) {
            DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
            return OMX_ErrorBadPortIndex;
        }
        if (!cmdData) {
            DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
            return OMX_ErrorBadParameter;
        }
    }

    post_event((unsigned long)cmd,(unsigned long)param1,OMX_COMPONENT_GENERATE_COMMAND);
    sem_wait(&m_cmd_lock);
    return OMX_ErrorNone;
}

/* ======================================================================
   FUNCTION
   omx_venc::SendCommand

   DESCRIPTION
   Returns zero if all the buffers released..

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
        OMX_IN OMX_COMMANDTYPE cmd,
        OMX_IN OMX_U32 param1,
        OMX_IN OMX_PTR cmdData
        )
{
    (void)hComp;
    (void)cmdData;

    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    OMX_STATETYPE eState = (OMX_STATETYPE) param1;
    int bFlag = 1;

    if (cmd == OMX_CommandStateSet) {
        /***************************/
        /* Current State is Loaded */
        /***************************/
        if (m_state == OMX_StateLoaded) {
            if (eState == OMX_StateIdle) {
                //if all buffers are allocated or all ports disabled
                if (allocate_done() ||
                        ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) {
                    DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle");
                } else {
                    DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending");
                    BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
                    // Skip the event notification
                    bFlag = 0;
                }
            }
            /* Requesting transition from Loaded to Loaded */
            else if (eState == OMX_StateLoaded) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded");
                post_event(OMX_EventError,OMX_ErrorSameState,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorSameState;
            }
            /* Requesting transition from Loaded to WaitForResources */
            else if (eState == OMX_StateWaitForResources) {
                /* Since error is None , we will post an event
                   at the end of this function definition */
                DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources");
            }
            /* Requesting transition from Loaded to Executing */
            else if (eState == OMX_StateExecuting) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from Loaded to Pause */
            else if (eState == OMX_StatePause) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from Loaded to Invalid */
            else if (eState == OMX_StateInvalid) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid");
                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorInvalidState;
            } else {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled",\
                        eState);
                eRet = OMX_ErrorBadParameter;
            }
        }

        /***************************/
        /* Current State is IDLE */
        /***************************/
        else if (m_state == OMX_StateIdle) {
            if (eState == OMX_StateLoaded) {
                if (release_done()) {
                    /*
                       Since error is None , we will post an event at the end
                       of this function definition
                     */
                    DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded");
                    if (dev_stop() != 0) {
                        DEBUG_PRINT_ERROR("ERROR: dev_stop() failed at Idle --> Loaded");
                        eRet = OMX_ErrorHardware;
                    }
                } else {
                    DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending");
                    BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
                    // Skip the event notification
                    bFlag = 0;
                }
            }
            /* Requesting transition from Idle to Executing */
            else if (eState == OMX_StateExecuting) {
                if ( dev_start() ) {
                    DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Exe");
                    omx_report_error ();
                    eRet = OMX_ErrorHardware;
                } else {
                    BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
                    DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing");
                    bFlag = 0;
                }

                dev_start_done();
            }
            /* Requesting transition from Idle to Idle */
            else if (eState == OMX_StateIdle) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle");
                post_event(OMX_EventError,OMX_ErrorSameState,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorSameState;
            }
            /* Requesting transition from Idle to WaitForResources */
            else if (eState == OMX_StateWaitForResources) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from Idle to Pause */
            else if (eState == OMX_StatePause) {
                /*To pause the Video core we need to start the driver*/
                if ( dev_start() ) {
                    DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Pause");
                    omx_report_error ();
                    eRet = OMX_ErrorHardware;
                } else {
                    BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
                    DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause");
                    bFlag = 0;
                }
            }
            /* Requesting transition from Idle to Invalid */
            else if (eState == OMX_StateInvalid) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid");
                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorInvalidState;
            } else {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled",eState);
                eRet = OMX_ErrorBadParameter;
            }
        }

        /******************************/
        /* Current State is Executing */
        /******************************/
        else if (m_state == OMX_StateExecuting) {
            /* Requesting transition from Executing to Idle */
            if (eState == OMX_StateIdle) {
                /* Since error is None , we will post an event
                   at the end of this function definition
                 */
                DEBUG_PRINT_LOW("OMXCORE-SM: Executing --> Idle");
                //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
                BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
                execute_omx_flush(OMX_ALL);
                bFlag = 0;
            }
            /* Requesting transition from Executing to Paused */
            else if (eState == OMX_StatePause) {

                if (dev_pause()) {
                    DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in SCP on Exe --> Pause");
                    post_event(OMX_EventError,OMX_ErrorHardware,\
                            OMX_COMPONENT_GENERATE_EVENT);
                    eRet = OMX_ErrorHardware;
                } else {
                    BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
                    DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause");
                    bFlag = 0;
                }
            }
            /* Requesting transition from Executing to Loaded */
            else if (eState == OMX_StateLoaded) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Loaded");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from Executing to WaitForResources */
            else if (eState == OMX_StateWaitForResources) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> WaitForResources");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from Executing to Executing */
            else if (eState == OMX_StateExecuting) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Executing");
                post_event(OMX_EventError,OMX_ErrorSameState,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorSameState;
            }
            /* Requesting transition from Executing to Invalid */
            else if (eState == OMX_StateInvalid) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Invalid");
                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorInvalidState;
            } else {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled",eState);
                eRet = OMX_ErrorBadParameter;
            }
        }
        /***************************/
        /* Current State is Pause  */
        /***************************/
        else if (m_state == OMX_StatePause) {
            /* Requesting transition from Pause to Executing */
            if (eState == OMX_StateExecuting) {
                DEBUG_PRINT_LOW("Pause --> Executing");
                if ( dev_resume() ) {
                    post_event(OMX_EventError,OMX_ErrorHardware,\
                            OMX_COMPONENT_GENERATE_EVENT);
                    eRet = OMX_ErrorHardware;
                } else {
                    BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
                    DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing");
                    post_event (0, 0, OMX_COMPONENT_GENERATE_RESUME_DONE);
                    bFlag = 0;
                }
            }
            /* Requesting transition from Pause to Idle */
            else if (eState == OMX_StateIdle) {
                /* Since error is None , we will post an event
                   at the end of this function definition */
                DEBUG_PRINT_LOW("Pause --> Idle");
                BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
                execute_omx_flush(OMX_ALL);
                bFlag = 0;
            }
            /* Requesting transition from Pause to loaded */
            else if (eState == OMX_StateLoaded) {
                DEBUG_PRINT_ERROR("ERROR: Pause --> loaded");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from Pause to WaitForResources */
            else if (eState == OMX_StateWaitForResources) {
                DEBUG_PRINT_ERROR("ERROR: Pause --> WaitForResources");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from Pause to Pause */
            else if (eState == OMX_StatePause) {
                DEBUG_PRINT_ERROR("ERROR: Pause --> Pause");
                post_event(OMX_EventError,OMX_ErrorSameState,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorSameState;
            }
            /* Requesting transition from Pause to Invalid */
            else if (eState == OMX_StateInvalid) {
                DEBUG_PRINT_ERROR("ERROR: Pause --> Invalid");
                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorInvalidState;
            } else {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled",eState);
                eRet = OMX_ErrorBadParameter;
            }
        }
        /***************************/
        /* Current State is WaitForResources  */
        /***************************/
        else if (m_state == OMX_StateWaitForResources) {
            /* Requesting transition from WaitForResources to Loaded */
            if (eState == OMX_StateLoaded) {
                /* Since error is None , we will post an event
                   at the end of this function definition */
                DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded");
            }
            /* Requesting transition from WaitForResources to WaitForResources */
            else if (eState == OMX_StateWaitForResources) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources");
                post_event(OMX_EventError,OMX_ErrorSameState,
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorSameState;
            }
            /* Requesting transition from WaitForResources to Executing */
            else if (eState == OMX_StateExecuting) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from WaitForResources to Pause */
            else if (eState == OMX_StatePause) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause");
                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
                        OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorIncorrectStateTransition;
            }
            /* Requesting transition from WaitForResources to Invalid */
            else if (eState == OMX_StateInvalid) {
                DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid");
                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
                eRet = OMX_ErrorInvalidState;
            }
            /* Requesting transition from WaitForResources to Loaded -
               is NOT tested by Khronos TS */

        } else {
            DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)",m_state,eState);
            eRet = OMX_ErrorBadParameter;
        }
    }
    /********************************/
    /* Current State is Invalid */
    /*******************************/
    else if (m_state == OMX_StateInvalid) {
        /* State Transition from Inavlid to any state */
        if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
                    || OMX_StateIdle || OMX_StateExecuting
                    || OMX_StatePause || OMX_StateInvalid)) {
            DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded");
            post_event(OMX_EventError,OMX_ErrorInvalidState,\
                    OMX_COMPONENT_GENERATE_EVENT);
            eRet = OMX_ErrorInvalidState;
        }
    } else if (cmd == OMX_CommandFlush) {
        if (0 == param1 || OMX_ALL == param1) {
            BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
        }
        if (1 == param1 || OMX_ALL == param1) {
            //generate output flush event only.
            BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
        }

        execute_omx_flush(param1);
        bFlag = 0;
    } else if ( cmd == OMX_CommandPortEnable) {
        if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) {
            m_sInPortDef.bEnabled = OMX_TRUE;

            if ( (m_state == OMX_StateLoaded &&
                        !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
                    || allocate_input_done()) {
                post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
                        OMX_COMPONENT_GENERATE_EVENT);
            } else {
                DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending");
                BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
                // Skip the event notification
                bFlag = 0;
            }
        }
        if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) {
            m_sOutPortDef.bEnabled = OMX_TRUE;

            if ( (m_state == OMX_StateLoaded &&
                        !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
                    || (allocate_output_done())) {
                post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
                        OMX_COMPONENT_GENERATE_EVENT);

            } else {
                DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending");
                BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
                // Skip the event notification
                bFlag = 0;
            }
        }
    } else if (cmd == OMX_CommandPortDisable) {
        if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) {
            m_sInPortDef.bEnabled = OMX_FALSE;
            if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
                    && release_input_done()) {
                post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
                        OMX_COMPONENT_GENERATE_EVENT);
            } else {
                BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
                if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
                    execute_omx_flush(PORT_INDEX_IN);
                }

                // Skip the event notification
                bFlag = 0;
            }
        }
        if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) {
            m_sOutPortDef.bEnabled = OMX_FALSE;

            if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
                    && release_output_done()) {
                post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
                        OMX_COMPONENT_GENERATE_EVENT);
            } else {
                BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
                if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
                    execute_omx_flush(PORT_INDEX_OUT);
                }
                // Skip the event notification
                bFlag = 0;

            }
        }
    } else {
        DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)",cmd);
        eRet = OMX_ErrorNotImplemented;
    }
    if (eRet == OMX_ErrorNone && bFlag) {
        post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
    }
    sem_post(&m_cmd_lock);
    return eRet;
}

/* ======================================================================
   FUNCTION
   omx_venc::ExecuteOmxFlush

   DESCRIPTION
   Executes the OMX flush.

   PARAMETERS
   flushtype - input flush(1)/output flush(0)/ both.

   RETURN VALUE
   true/false

   ========================================================================== */
bool omx_video::execute_omx_flush(OMX_U32 flushType)
{
    bool bRet = false;
    DEBUG_PRINT_LOW("execute_omx_flush -  %u", (unsigned int)flushType);
#ifdef _MSM8974_
    /* XXX: The driver/hardware does not support flushing of individual ports
     * in all states. So we pretty much need to flush both ports internally,
     * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
     * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
     * we automatically omit sending the FLUSH done for the "opposite" port. */

    input_flush_progress = true;
    output_flush_progress = true;
    bRet = execute_flush_all();
#else
    if (flushType == 0 || flushType == OMX_ALL) {
        input_flush_progress = true;
        //flush input only
        bRet = execute_input_flush();
    }
    if (flushType == 1 || flushType == OMX_ALL) {
        //flush output only
        output_flush_progress = true;
        bRet = execute_output_flush();
    }
#endif
    return bRet;
}
/*=========================================================================
FUNCTION : execute_output_flush

DESCRIPTION
Executes the OMX flush at OUTPUT PORT.

PARAMETERS
None.

RETURN VALUE
true/false
==========================================================================*/
bool omx_video::execute_output_flush(void)
{
    unsigned long p1 = 0; // Parameter - 1
    unsigned long p2 = 0; // Parameter - 2
    unsigned long ident = 0;
    bool bRet = true;

    /*Generate FBD for all Buffers in the FTBq*/
    DEBUG_PRINT_LOW("execute_output_flush");
    pthread_mutex_lock(&m_lock);
    while (m_ftb_q.m_size) {
        m_ftb_q.pop_entry(&p1,&p2,&ident);

        if (ident == OMX_COMPONENT_GENERATE_FTB ) {
            pending_output_buffers++;
            fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
        } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
            fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
        }
    }

    pthread_mutex_unlock(&m_lock);
    /*Check if there are buffers with the Driver*/
    if (dev_flush(PORT_INDEX_OUT)) {
        DEBUG_PRINT_ERROR("ERROR: o/p dev_flush() Failed");
        return false;
    }

    return bRet;
}
/*=========================================================================
FUNCTION : execute_input_flush

DESCRIPTION
Executes the OMX flush at INPUT PORT.

PARAMETERS
None.

RETURN VALUE
true/false
==========================================================================*/
bool omx_video::execute_input_flush(void)
{
    unsigned long p1 = 0; // Parameter - 1
    unsigned long p2 = 0; // Parameter - 2
    unsigned long ident = 0;
    bool bRet = true;

    /*Generate EBD for all Buffers in the ETBq*/
    DEBUG_PRINT_LOW("execute_input_flush");

    pthread_mutex_lock(&m_lock);
    while (m_etb_q.m_size) {
        m_etb_q.pop_entry(&p1,&p2,&ident);
        if (ident == OMX_COMPONENT_GENERATE_ETB) {
            pending_input_buffers++;
            empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
        } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
            empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
        } else if (ident == OMX_COMPONENT_GENERATE_ETB_OPQ) {
            m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
        }
    }
    if (mUseProxyColorFormat) {
        if (psource_frame) {
            m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
            psource_frame = NULL;
        }
        while (m_opq_meta_q.m_size) {
            unsigned long p1,p2,id;
            m_opq_meta_q.pop_entry(&p1,&p2,&id);
            m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
                    (OMX_BUFFERHEADERTYPE  *)p1);
        }
        if (pdest_frame) {
            m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0);
            pdest_frame = NULL;
        }
    }
    pthread_mutex_unlock(&m_lock);
    /*Check if there are buffers with the Driver*/
    if (dev_flush(PORT_INDEX_IN)) {
        DEBUG_PRINT_ERROR("ERROR: i/p dev_flush() Failed");
        return false;
    }

    return bRet;
}


/*=========================================================================
FUNCTION : execute_flush

DESCRIPTION
Executes the OMX flush at INPUT & OUTPUT PORT.

PARAMETERS
None.

RETURN VALUE
true/false
==========================================================================*/
#ifdef _MSM8974_
bool omx_video::execute_flush_all(void)
{
    unsigned long p1 = 0; // Parameter - 1
    unsigned long p2 = 0; // Parameter - 2
    unsigned long ident = 0;
    bool bRet = true;

    DEBUG_PRINT_LOW("execute_flush_all");

    /*Generate EBD for all Buffers in the ETBq*/
    pthread_mutex_lock(&m_lock);
    while (m_etb_q.m_size) {
        m_etb_q.pop_entry(&p1,&p2,&ident);
        if (ident == OMX_COMPONENT_GENERATE_ETB) {
            pending_input_buffers++;
            empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
        } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
            empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
        } else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) {
            m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
        }
    }
    if(mUseProxyColorFormat) {
        if(psource_frame) {
            m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
            psource_frame = NULL;
        }
        while(m_opq_meta_q.m_size) {
            unsigned long p1,p2,id;
            m_opq_meta_q.pop_entry(&p1,&p2,&id);
            m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
                (OMX_BUFFERHEADERTYPE  *)p1);
        }
        if(pdest_frame){
            m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0);
            pdest_frame = NULL;
        }
    }

    /*Generate FBD for all Buffers in the FTBq*/
    DEBUG_PRINT_LOW("execute_output_flush");
    while (m_ftb_q.m_size) {
        m_ftb_q.pop_entry(&p1,&p2,&ident);

        if (ident == OMX_COMPONENT_GENERATE_FTB ) {
            pending_output_buffers++;
            fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
        } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
            fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
        }
    }

    pthread_mutex_unlock(&m_lock);

    /*Check if there are buffers with the Driver*/
    if (dev_flush(PORT_INDEX_BOTH)) {
        DEBUG_PRINT_ERROR("ERROR: dev_flush() Failed");
        return false;
    }
    return bRet;
}

#endif

/* ======================================================================
   FUNCTION
   omx_venc::SendCommandEvent

   DESCRIPTION
   Send the event to decoder pipe.  This is needed to generate the callbacks
   in decoder thread context.

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
bool omx_video::post_event(unsigned long p1,
        unsigned long p2,
        unsigned long id)
{
    bool bRet =  false;

    pthread_mutex_lock(&m_lock);

    if ((id == OMX_COMPONENT_GENERATE_FTB) ||
            (id == OMX_COMPONENT_GENERATE_FBD) ||
            (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH)) {
        m_ftb_q.insert_entry(p1,p2,id);
    } else if ((id == OMX_COMPONENT_GENERATE_ETB) ||
            (id == OMX_COMPONENT_GENERATE_EBD) ||
            (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH)) {
        m_etb_q.insert_entry(p1,p2,id);
    } else {
        m_cmd_q.insert_entry(p1,p2,id);
    }

    bRet = true;
    DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
    post_message(this, id);
    pthread_mutex_unlock(&m_lock);

    return bRet;
}

/* ======================================================================
   FUNCTION
   omx_venc::GetParameter

   DESCRIPTION
   OMX Get Parameter method implementation

   PARAMETERS
   <TBD>.

   RETURN VALUE
   Error None if successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
        OMX_IN OMX_INDEXTYPE paramIndex,
        OMX_INOUT OMX_PTR     paramData)
{
    (void)hComp;
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    unsigned int height=0,width = 0;

    DEBUG_PRINT_LOW("get_parameter:");
    if (m_state == OMX_StateInvalid) {
        DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State");
        return OMX_ErrorInvalidState;
    }
    if (paramData == NULL) {
        DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
        return OMX_ErrorBadParameter;
    }
    switch ((int)paramIndex) {
        case OMX_IndexParamPortDefinition:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;

                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
                if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
                    dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
                        &m_sInPortDef.nBufferCountActual,
                        &m_sInPortDef.nBufferSize,
                        m_sInPortDef.nPortIndex);
                    DEBUG_PRINT_LOW("m_sInPortDef: size = %u, min cnt = %u, actual cnt = %u",
                            (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountMin,
                            (unsigned int)m_sInPortDef.nBufferCountActual);
                    memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
#ifdef _ANDROID_ICS_
                    if (meta_mode_enable) {
                        portDefn->nBufferSize = sizeof(encoder_media_buffer_type);
                    }
                    if (mUseProxyColorFormat) {
                        portDefn->format.video.eColorFormat =
                            (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
                    }
#endif
                } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
                    if (m_state != OMX_StateExecuting) {
                        dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
                            &m_sOutPortDef.nBufferCountActual,
                            &m_sOutPortDef.nBufferSize,
                            m_sOutPortDef.nPortIndex);
                    }
                    DEBUG_PRINT_LOW("m_sOutPortDef: size = %u, min cnt = %u, actual cnt = %u",
                            (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountMin,
                            (unsigned int)m_sOutPortDef.nBufferCountActual);
                    memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
                } else {
                    DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
                    eRet = OMX_ErrorBadPortIndex;
                }
                break;
            }
        case OMX_IndexParamVideoInit:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
                OMX_PORT_PARAM_TYPE *portParamType =
                    (OMX_PORT_PARAM_TYPE *) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");

                memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
                break;
            }
        case OMX_IndexParamVideoPortFormat:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
                OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
                    (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");

                if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
                    unsigned index = portFmt->nIndex;

#ifdef _UBWC_
                    //we support following formats
                    //index 0 - Compressed (UBWC) Venus flavour of YUV420SP
                    //index 1 - Venus flavour of YUV420SP
                    //index 2 - Compressed (UBWC) Venus flavour of RGBA8888
                    //index 3 - Venus flavour of RGBA8888
                    //index 4 - opaque which internally maps to YUV420SP.
                    //index 5 - vannilla YUV420SP
                    //this can be extended in the future
                    int supportedFormats[] = {
                        [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed,
                        [1] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
                        [2] = QOMX_COLOR_Format32bitRGBA8888Compressed,
                        [3] = QOMX_COLOR_Format32bitRGBA8888,
                        [4] = QOMX_COLOR_FormatAndroidOpaque,
                        [5] = OMX_COLOR_FormatYUV420SemiPlanar,
                    };
#else
                    //we support two formats
                    //index 0 - Venus flavour of YUV420SP
                    //index 1 - opaque which internally maps to YUV420SP.
                    //index 2 - vannilla YUV420SP
                    //this can be extended in the future
                    int supportedFormats[] = {
                        [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
                        [1] = QOMX_COLOR_FormatAndroidOpaque,
                        [2] = OMX_COLOR_FormatYUV420SemiPlanar,
                    };
#endif
                    if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1))
                        eRet = OMX_ErrorNoMore;
                    else {
                        memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
                        portFmt->nIndex = index; //restore index set from client
                        portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)supportedFormats[index];
                    }
                } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
                    memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
                } else {
                    DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
                    eRet = OMX_ErrorBadPortIndex;
                }
                break;
            }
        case OMX_IndexParamVideoBitrate:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_BITRATETYPE);
                OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate");

                if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
                    memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
                } else {
                    DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
                    eRet = OMX_ErrorBadPortIndex;
                }

                break;
            }
        case OMX_IndexParamVideoMpeg4:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_MPEG4TYPE);
                OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4");
                memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
                break;
            }
        case OMX_IndexParamVideoH263:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_H263TYPE);
                OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263");
                memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
                break;
            }
        case OMX_IndexParamVideoAvc:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_AVCTYPE);
                OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc");
                memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
                break;
            }
        case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_VP8TYPE);
                OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoVp8");
                memcpy(pParam, &m_sParamVP8, sizeof(m_sParamVP8));
                break;
            }
        case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_HEVCTYPE);
                OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoHevc");
                memcpy(pParam, &m_sParamHEVC, sizeof(m_sParamHEVC));
                break;
            }
        case OMX_IndexParamVideoProfileLevelQuerySupported:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
                OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported");
                eRet = get_supported_profile_level(pParam);
                if (eRet && eRet != OMX_ErrorNoMore)
                    DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %u, %u",
                            (unsigned int)pParam->eProfile, (unsigned int)pParam->eLevel);
                break;
            }
        case OMX_IndexParamVideoProfileLevelCurrent:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
                OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent");
                memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
                break;
            }
            /*Component should support this port definition*/
        case OMX_IndexParamAudioInit:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
                OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
                memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
                break;
            }
            /*Component should support this port definition*/
        case OMX_IndexParamImageInit:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
                OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
                memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
                break;

            }
            /*Component should support this port definition*/
        case OMX_IndexParamOtherInit:
            {
                DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x", paramIndex);
                eRet =OMX_ErrorUnsupportedIndex;
                break;
            }
        case OMX_IndexParamStandardComponentRole:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
                OMX_PARAM_COMPONENTROLETYPE *comp_role;
                comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
                comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
                comp_role->nSize = sizeof(*comp_role);

                DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",paramIndex);
                strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
                break;
            }
            /* Added for parameter test */
        case OMX_IndexParamPriorityMgmt:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
                OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
                memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
                break;
            }
            /* Added for parameter test */
        case OMX_IndexParamCompBufferSupplier:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
                OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
                if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) {
                    memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier));
                } else if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) {
                    memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier));
                } else {
                    DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
                    eRet = OMX_ErrorBadPortIndex;
                }
                break;
            }

        case OMX_IndexParamVideoQuantization:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
                OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization");
                memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
                break;
            }

        case OMX_QcomIndexParamVideoQPRange:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE);
                OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange");
                memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange));
                break;
            }

        case OMX_IndexParamVideoErrorCorrection:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
                OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
                DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
                errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
                errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
                errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
                break;
            }
        case OMX_IndexParamVideoIntraRefresh:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
                OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
                DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh");
                DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET");
                intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
                intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
                break;
            }
        case OMX_QcomIndexPortDefn:
            //TODO
            break;
        case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMXComponentCapabilityFlagsType);
                OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
                DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX");
                pParam->iIsOMXComponentMultiThreaded = OMX_TRUE;
                pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE;
                pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
                pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
                pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE;
                pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE;
                pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE;
                pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
                m_use_input_pmem = OMX_TRUE;
                DEBUG_PRINT_LOW("Supporting capability index in encoder node");
                break;
            }
#if !defined(MAX_RES_720P) || defined(_MSM8974_)
        case OMX_QcomIndexParamIndexExtraDataType:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType");
                QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
                if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) {
                    if (pParam->nPortIndex == PORT_INDEX_OUT) {
                        pParam->bEnabled =
                            (OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_SLICEINFO);
                        DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled);
                    } else {
                        DEBUG_PRINT_ERROR("get_parameter: slice information is "
                                "valid for output port only");
                        eRet = OMX_ErrorUnsupportedIndex;
                    }
                } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo) {
                    if (pParam->nPortIndex == PORT_INDEX_OUT) {
                        pParam->bEnabled =
                            (OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_MBINFO);
                        DEBUG_PRINT_HIGH("MB Info extradata %d", pParam->bEnabled);
                    } else {
                        DEBUG_PRINT_ERROR("get_parameter: MB information is "
                                "valid for output port only");
                        eRet = OMX_ErrorUnsupportedIndex;
                    }
                } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataFrameDimension) {
                    if (pParam->nPortIndex == PORT_INDEX_IN) {
                        pParam->bEnabled =
                            (OMX_BOOL)((m_sExtraData & VENC_EXTRADATA_FRAMEDIMENSION) ? 1 : 0);
                        DEBUG_PRINT_HIGH("Frame dimension extradata %d", pParam->bEnabled);
                    } else {
                        DEBUG_PRINT_ERROR("get_parameter: frame dimension is "
                                "valid for input port only");
                        eRet = OMX_ErrorUnsupportedIndex;
                    }
                }
#ifndef _MSM8974_
                else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) {
                    if (pParam->nPortIndex == PORT_INDEX_OUT) {
                        pParam->bEnabled =
                            (OMX_BOOL)(m_sExtraData & VEN_EXTRADATA_LTRINFO);
                        DEBUG_PRINT_HIGH("LTR Info extradata %d", pParam->bEnabled);
                    } else {
                        DEBUG_PRINT_ERROR("get_parameter: LTR information is "
                                "valid for output port only");
                        eRet = OMX_ErrorUnsupportedIndex;
                    }
                }
#endif
                else {
                    DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)",
                            pParam->nIndex);
                    eRet = OMX_ErrorUnsupportedIndex;
                }
                break;
            }
        case QOMX_IndexParamVideoLTRCountRangeSupported:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_RANGETYPE);
                DEBUG_PRINT_HIGH("get_parameter: QOMX_IndexParamVideoLTRCountRangeSupported");
                QOMX_EXTNINDEX_RANGETYPE *pParam = (QOMX_EXTNINDEX_RANGETYPE *)paramData;
                if (pParam->nPortIndex == PORT_INDEX_OUT) {
                    OMX_U32 min = 0, max = 0, step_size = 0;
                    if (dev_get_capability_ltrcount(&min, &max, &step_size)) {
                        pParam->nMin = min;
                        pParam->nMax = max;
                        pParam->nStepSize = step_size;
                    } else {
                        DEBUG_PRINT_ERROR("get_parameter: get_capability_ltrcount failed");
                        eRet = OMX_ErrorUndefined;
                    }
                } else {
                    DEBUG_PRINT_ERROR("LTR count range is valid for output port only");
                    eRet = OMX_ErrorUnsupportedIndex;
                }
            }
            break;
        case OMX_QcomIndexParamVideoLTRCount:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE);
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoLTRCount");
                OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE *pParam =
                        reinterpret_cast<OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*>(paramData);
                memcpy(pParam, &m_sParamLTRCount, sizeof(m_sParamLTRCount));
                break;
            }
#endif
        case QOMX_IndexParamVideoSyntaxHdr:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE);
                DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
                QOMX_EXTNINDEX_PARAMTYPE* pParam =
                    reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData);
                if (pParam->pData == NULL) {
                    DEBUG_PRINT_ERROR("Error: Data buffer is NULL");
                    eRet = OMX_ErrorBadParameter;
                    break;
                }
                if (get_syntaxhdr_enable == false) {
                    DEBUG_PRINT_ERROR("ERROR: get_parameter: Get syntax header disabled");
                    eRet = OMX_ErrorUnsupportedIndex;
                    break;
                }
                BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
                if (dev_loaded_start()) {
                    DEBUG_PRINT_LOW("device start successful");
                } else {
                    DEBUG_PRINT_ERROR("device start failed");
                    BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
                    return OMX_ErrorHardware;
                }
                if (dev_get_seq_hdr(pParam->pData,
                            (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)),
                            (unsigned *)(void *)&pParam->nDataSize)) {
                    DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %u)",
                            (unsigned int)pParam->nDataSize);
                    for (unsigned i = 0; i < pParam->nDataSize; i++) {
                        DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i));
                    }
                } else {
                    DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()");
                    eRet = OMX_ErrorHardware;
                }
                BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
                if (dev_loaded_stop()) {
                    DEBUG_PRINT_LOW("device stop successful");
                } else {
                    DEBUG_PRINT_ERROR("device stop failed");
                    BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
                    eRet = OMX_ErrorHardware;
                }
                break;
            }
        case OMX_QcomIndexHierarchicalStructure:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_HIERARCHICALLAYERS);
                QOMX_VIDEO_HIERARCHICALLAYERS* hierp = (QOMX_VIDEO_HIERARCHICALLAYERS*) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexHierarchicalStructure");
                memcpy(hierp, &m_sHierLayers, sizeof(m_sHierLayers));
                break;
            }
         case OMX_QcomIndexParamMBIStatisticsMode:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QOMX_VIDEO_MBI_STATISTICS);
                OMX_QOMX_VIDEO_MBI_STATISTICS* mbi_mode = (OMX_QOMX_VIDEO_MBI_STATISTICS*) paramData;
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamMBIStatisticsMode");
                memcpy(mbi_mode, &m_sMBIStatistics, sizeof(m_sMBIStatistics));
                break;
            }
        case OMX_QcomIndexParamPerfLevel:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PERF_LEVEL);
                OMX_U32 perflevel;
                OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
                    reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PERF_LEVEL*>(paramData);
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPerfLevel");
                if (!dev_get_performance_level(&perflevel)) {
                    DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
                        pParam->ePerfLevel);
                } else {
                    pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
                }
                break;
            }
        case OMX_QcomIndexParamH264VUITimingInfo:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO);
                OMX_U32 enabled;
                OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
                    reinterpret_cast<OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO*>(paramData);
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamH264VUITimingInfo");
                if (!dev_get_vui_timing_info(&enabled)) {
                    DEBUG_PRINT_ERROR("Invalid entry returned from get_vui_Timing_info %d",
                        pParam->bEnable);
                } else {
                    pParam->bEnable = (OMX_BOOL)enabled;
                }
                break;
            }
        case OMX_QTIIndexParamVQZIPSEIType:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
                OMX_U32 enabled;
                OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
                    reinterpret_cast<OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*>(paramData);
                DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVQZIPSEIType");
                if (!dev_get_vqzip_sei_info(&enabled)) {
                    DEBUG_PRINT_ERROR("Invalid entry returned from get_vqzip_sei_type %d",
                        pParam->bEnable);
                } else {
                    pParam->bEnable = (OMX_BOOL)enabled;
                }
                break;
            }
        case OMX_QcomIndexParamPeakBitrate:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE);
                OMX_U32 peakbitrate;
                OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
                    reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE*>(paramData);
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPeakBitrate");
                if (!dev_get_peak_bitrate(&peakbitrate)) {
                    DEBUG_PRINT_ERROR("Invalid entry returned from get_peak_bitrate %u",
                        (unsigned int)pParam->nPeakBitrate);
                } else {
                    pParam->nPeakBitrate = peakbitrate;
                }
                break;
            }
         case QOMX_IndexParamVideoInitialQp:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP);
                 QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp =
                     reinterpret_cast<QOMX_EXTNINDEX_VIDEO_INITIALQP *>(paramData);
                     memcpy(initqp, &m_sParamInitqp, sizeof(m_sParamInitqp));
                break;
            }
         case OMX_QcomIndexParamBatchSize:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_U32TYPE);
                OMX_PARAM_U32TYPE* batch =
                    reinterpret_cast<OMX_PARAM_U32TYPE *>(paramData);

                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamBatchSize");
                if (!dev_get_batch_size(&batch->nU32)) {
                    DEBUG_PRINT_ERROR("Invalid entry returned from dev_get_batch_size %u",
                        (unsigned int)batch->nSize);
                    eRet = OMX_ErrorUnsupportedIndex;
                    break;
                }

                batch->nPortIndex = PORT_INDEX_IN;
                break;
            }
        case OMX_QcomIndexParamSequenceHeaderWithIDR:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, PrependSPSPPSToIDRFramesParams);
                PrependSPSPPSToIDRFramesParams * pParam =
                    reinterpret_cast<PrependSPSPPSToIDRFramesParams *>(paramData);
                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamSequenceHeaderWithIDR");
                memcpy(pParam, &m_sPrependSPSPPS, sizeof(m_sPrependSPSPPS));
                break;
            }
        case OMX_QcomIndexParamVencAspectRatio:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_SAR);
               QOMX_EXTNINDEX_VIDEO_VENC_SAR * pParam =
                   reinterpret_cast<QOMX_EXTNINDEX_VIDEO_VENC_SAR *>(paramData);
                memcpy(pParam, &m_sSar, sizeof(m_sSar));
                break;
            }
        case OMX_IndexParamAndroidVideoTemporalLayering:
            {
                VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
                OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pLayerInfo =
                        reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*>(paramData);
                if (!dev_get_temporal_layer_caps(&m_sParamTemporalLayers.nLayerCountMax,
                        &m_sParamTemporalLayers.nBLayerCountMax)) {
                    DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities");
                    eRet = OMX_ErrorHardware;
                }
                memcpy(pLayerInfo, &m_sParamTemporalLayers, sizeof(m_sParamTemporalLayers));
                break;
            }
        case OMX_IndexParamVideoSliceFMO:
        default:
            {
                DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x", paramIndex);
                eRet =OMX_ErrorUnsupportedIndex;
                break;
            }

    }

    return eRet;

}
/* ======================================================================
   FUNCTION
   omx_video::GetConfig

   DESCRIPTION
   OMX Get Config Method implementation.

   PARAMETERS
   <TBD>.

   RETURN VALUE
   OMX Error None if successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::get_config(OMX_IN OMX_HANDLETYPE      hComp,
        OMX_IN OMX_INDEXTYPE configIndex,
        OMX_INOUT OMX_PTR     configData)
{
    (void)hComp;
    ////////////////////////////////////////////////////////////////
    // Supported Config Index           Type
    // =============================================================
    // OMX_IndexConfigVideoBitrate      OMX_VIDEO_CONFIG_BITRATETYPE
    // OMX_IndexConfigVideoFramerate    OMX_CONFIG_FRAMERATETYPE
    // OMX_IndexConfigCommonRotate      OMX_CONFIG_ROTATIONTYPE
    ////////////////////////////////////////////////////////////////

    if (configData == NULL) {
        DEBUG_PRINT_ERROR("ERROR: param is null");
        return OMX_ErrorBadParameter;
    }

    if (m_state == OMX_StateInvalid) {
        DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
        return OMX_ErrorIncorrectStateOperation;
    }

    //@todo need to validate params
    switch ((int)configIndex) {
        case OMX_IndexConfigVideoBitrate:
            {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE);
                OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
                memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
                break;
            }
        case OMX_IndexConfigVideoFramerate:
            {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE);
                OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
                memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
                break;
            }
        case OMX_IndexConfigCommonRotate:
            {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE);
                OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
                memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
                break;
            }
        case QOMX_IndexConfigVideoIntraperiod:
            {
                DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod");
                VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE);
                QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
                memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
                break;
            }
        case OMX_IndexConfigVideoAVCIntraPeriod:
            {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD);
                OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam =
                    reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData);
                DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod");
                memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod));
                break;
            }
        case OMX_IndexConfigCommonDeinterlace:
            {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE);
                OMX_VIDEO_CONFIG_DEINTERLACE *pParam =
                    reinterpret_cast<OMX_VIDEO_CONFIG_DEINTERLACE*>(configData);
                DEBUG_PRINT_LOW("get_config: OMX_IndexConfigCommonDeinterlace");
                memcpy(pParam, &m_sConfigDeinterlace, sizeof(m_sConfigDeinterlace));
                break;
            }
       case OMX_IndexConfigVideoVp8ReferenceFrame:
           {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE);
               OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam =
                   reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData);
               DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame");
               memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame));
               break;
           }
        case OMX_QcomIndexConfigPerfLevel:
            {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
                OMX_U32 perflevel;
                OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam =
                    reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData);
                DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel");
                if (!dev_get_performance_level(&perflevel)) {
                    DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
                        pParam->ePerfLevel);
                } else {
                    pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
                }
                break;
            }
       case OMX_QcomIndexConfigNumHierPLayers:
           {
                VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS);
               QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS* pParam =
                   reinterpret_cast<QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS*>(configData);
               DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigNumHierPLayers");
               memcpy(pParam, &m_sHPlayers, sizeof(m_sHPlayers));
               break;
           }
       case OMX_QcomIndexConfigQp:
           {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_QP);
               OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
                   reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_QP*>(configData);
               DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigQp");
               memcpy(pParam, &m_sConfigQP, sizeof(m_sConfigQP));
               break;
           }
       case OMX_QcomIndexConfigBaseLayerId:
           {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID);
               OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
                   reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*>(configData);
               DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigBaseLayerId");
               memcpy(pParam, &m_sBaseLayerID, sizeof(m_sBaseLayerID));
               break;
           }
       case OMX_IndexConfigAndroidIntraRefresh:
           {
               VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE);
               OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam =
                   reinterpret_cast<OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*>(configData);
               DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidIntraRefresh");
               memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh));
               break;
           }
        case OMX_IndexParamAndroidVideoTemporalLayering:
            {
                VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
                OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *layerConfig =
                        (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)configData;
                DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidVideoTemporalLayering");
                memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers));
                break;
            }
       case OMX_QTIIndexConfigDescribeColorAspects:
            {
                VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
                DescribeColorAspectsParams* pParam =
                    reinterpret_cast<DescribeColorAspectsParams*>(configData);
                DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigDescribeColorAspects");
                memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects));
                break;
            }
        default:
            DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
            return OMX_ErrorUnsupportedIndex;
    }
    return OMX_ErrorNone;

}

#define extn_equals(param, extn) (!strcmp(param, extn))

/* ======================================================================
   FUNCTION
   omx_video::GetExtensionIndex

   DESCRIPTION
   OMX GetExtensionIndex method implementaion.  <TBD>

   PARAMETERS
   <TBD>.

   RETURN VALUE
   OMX Error None if everything successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
        OMX_IN OMX_STRING      paramName,
        OMX_OUT OMX_INDEXTYPE* indexType)
{
    (void)hComp;
    if (m_state == OMX_StateInvalid) {
        DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State");
        return OMX_ErrorInvalidState;
    }
#ifdef MAX_RES_1080P
    if (extn_equals(paramName, "OMX.QCOM.index.param.SliceDeliveryMode")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
        return OMX_ErrorNone;
    }
#endif
#ifdef _ANDROID_ICS_
    if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
        return OMX_ErrorNone;
    }
#endif
    if (extn_equals(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.param.video.HierStructure")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexHierarchicalStructure;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRCount")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoLTRCount;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRPeriod")) {
        *indexType = (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRPeriod;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRUse")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRUse;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRMark")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRMark;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.config.video.hierplayers")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigNumHierPLayers;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.param.video.baselayerid")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.config.video.qp")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigQp;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.param.video.sar")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVencAspectRatio;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.QCOM.index.param.video.InputBatch")) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamBatchSize;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO)) {
        *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableRoiInfo;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO)) {
        *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiInfo;
        return OMX_ErrorNone;
    }

    if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
        *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
        return OMX_ErrorNone;
    }
    return OMX_ErrorNotImplemented;
}

/* ======================================================================
   FUNCTION
   omx_video::GetState

   DESCRIPTION
   Returns the state information back to the caller.<TBD>

   PARAMETERS
   <TBD>.

   RETURN VALUE
   Error None if everything is successful.
   ========================================================================== */
OMX_ERRORTYPE  omx_video::get_state(OMX_IN OMX_HANDLETYPE  hComp,
        OMX_OUT OMX_STATETYPE* state)
{
    (void)hComp;
    *state = m_state;
    DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
    return OMX_ErrorNone;
}

/* ======================================================================
   FUNCTION
   omx_video::ComponentTunnelRequest

   DESCRIPTION
   OMX Component Tunnel Request method implementation. <TBD>

   PARAMETERS
   None.

   RETURN VALUE
   OMX Error None if everything successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
        OMX_IN OMX_U32                        port,
        OMX_IN OMX_HANDLETYPE        peerComponent,
        OMX_IN OMX_U32                    peerPort,
        OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
{
    (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup;
    DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented");
    return OMX_ErrorNotImplemented;
}

/* ======================================================================
   FUNCTION
   omx_video::UseInputBuffer

   DESCRIPTION
   Helper function for Use buffer in the input pin

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::use_input_buffer(
        OMX_IN OMX_HANDLETYPE            hComp,
        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
        OMX_IN OMX_U32                   port,
        OMX_IN OMX_PTR                   appData,
        OMX_IN OMX_U32                   bytes,
        OMX_IN OMX_U8*                   buffer)
{
    (void) hComp;
    OMX_ERRORTYPE eRet = OMX_ErrorNone;

    unsigned   i = 0;
    unsigned char *buf_addr = NULL;

    DEBUG_PRINT_HIGH("use_input_buffer: port = %u appData = %p bytes = %u buffer = %p",(unsigned int)port,appData,(unsigned int)bytes,buffer);
    if (bytes < m_sInPortDef.nBufferSize) {
        DEBUG_PRINT_ERROR("ERROR: use_input_buffer: Size Mismatch!! "
                "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
        return OMX_ErrorBadParameter;
    }

    if (!m_inp_mem_ptr) {
        input_use_buffer = true;
        m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
                        calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
        if (m_inp_mem_ptr == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
            return OMX_ErrorInsufficientResources;
        }
        DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);


        m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
        if (m_pInput_pmem == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
            return OMX_ErrorInsufficientResources;
        }
#ifdef USE_ION
        m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
        if (m_pInput_ion == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
            return OMX_ErrorInsufficientResources;
        }
#endif

        for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
            m_pInput_pmem[i].fd = -1;
#ifdef USE_ION
            m_pInput_ion[i].ion_device_fd =-1;
            m_pInput_ion[i].fd_ion_data.fd =-1;
            m_pInput_ion[i].ion_alloc_data.handle = 0;
#endif
        }

    }

    for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
        if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
            break;
        }
    }

    if (i < m_sInPortDef.nBufferCountActual) {

        *bufferHdr = (m_inp_mem_ptr + i);
        BITMASK_SET(&m_inp_bm_count,i);

        (*bufferHdr)->pBuffer           = (OMX_U8 *)buffer;
        (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
        (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
        (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
        (*bufferHdr)->pAppPrivate       = appData;
        (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;

        if (!m_use_input_pmem) {
#ifdef USE_ION
#ifdef _MSM8974_
            m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
                    &m_pInput_ion[i].ion_alloc_data,
                    &m_pInput_ion[i].fd_ion_data,
                    secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0);
#else
            m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
                    &m_pInput_ion[i].ion_alloc_data,
                    &m_pInput_ion[i].fd_ion_data, ION_FLAG_CACHED);
#endif
            if (m_pInput_ion[i].ion_device_fd < 0) {
                DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
                return OMX_ErrorInsufficientResources;
            }
            m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
#else
            m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
            if (m_pInput_pmem[i].fd == 0) {
                m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
            }

            if (m_pInput_pmem[i] .fd < 0) {
                DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
                return OMX_ErrorInsufficientResources;
            }
#endif
            m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
            m_pInput_pmem[i].offset = 0;

            m_pInput_pmem[i].buffer = NULL;
            if(!secure_session) {
                m_pInput_pmem[i].buffer = (unsigned char *)mmap(
                    NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
                    MAP_SHARED,m_pInput_pmem[i].fd,0);

                if (m_pInput_pmem[i].buffer == MAP_FAILED) {
                    DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
                    m_pInput_pmem[i].buffer = NULL;
                    close(m_pInput_pmem[i].fd);
#ifdef USE_ION
                    free_ion_memory(&m_pInput_ion[i]);
#endif
                    return OMX_ErrorInsufficientResources;
                }
            }

        } else {
            OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
            DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (unsigned)pParam->offset);

            if (pParam) {
                m_pInput_pmem[i].fd = pParam->pmem_fd;
                m_pInput_pmem[i].offset = pParam->offset;
                m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
                m_pInput_pmem[i].buffer = (unsigned char *)buffer;
                DEBUG_PRINT_LOW("DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
                        (unsigned int)pParam->pmem_fd, (unsigned int)pParam->offset);
            } else {
                DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
                return OMX_ErrorBadParameter;
            }
        }

        DEBUG_PRINT_LOW("use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
                (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
        if ( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) {
            DEBUG_PRINT_ERROR("ERROR: dev_use_buf() Failed for i/p buf");
            return OMX_ErrorInsufficientResources;
        }
    } else {
        DEBUG_PRINT_ERROR("ERROR: All buffers are already used, invalid use_buf call for "
                "index = %u", i);
        eRet = OMX_ErrorInsufficientResources;
    }

    return eRet;
}



/* ======================================================================
   FUNCTION
   omx_video::UseOutputBuffer

   DESCRIPTION
   Helper function for Use buffer in the input pin

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::use_output_buffer(
        OMX_IN OMX_HANDLETYPE            hComp,
        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
        OMX_IN OMX_U32                   port,
        OMX_IN OMX_PTR                   appData,
        OMX_IN OMX_U32                   bytes,
        OMX_IN OMX_U8*                   buffer)
{
    (void)hComp, (void)port;
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
    unsigned                         i= 0; // Temporary counter
    unsigned char *buf_addr = NULL;
#ifdef _MSM8974_
    int align_size;
#endif

    DEBUG_PRINT_HIGH("Inside use_output_buffer()");
    if (bytes < m_sOutPortDef.nBufferSize) {
        DEBUG_PRINT_ERROR("ERROR: use_output_buffer: Size Mismatch!! "
                "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sOutPortDef.nBufferSize);
        return OMX_ErrorBadParameter;
    }

    if (!m_out_mem_ptr) {
        output_use_buffer = true;
        int nBufHdrSize        = 0;

        DEBUG_PRINT_LOW("Allocating First Output Buffer(%u)",(unsigned int)m_sOutPortDef.nBufferCountActual);
        nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
        /*
         * Memory for output side involves the following:
         * 1. Array of Buffer Headers
         * 2. Bitmask array to hold the buffer allocation details
         * In order to minimize the memory management entire allocation
         * is done in one step.
         */
        //OMX Buffer header
        m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
        if (m_out_mem_ptr == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_out_mem_ptr");
            return OMX_ErrorInsufficientResources;
        }

        m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
        if (m_pOutput_pmem == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
            return OMX_ErrorInsufficientResources;
        }
#ifdef USE_ION
        m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
        if (m_pOutput_ion == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
            return OMX_ErrorInsufficientResources;
        }
#endif
        if (m_out_mem_ptr) {
            bufHdr          =  m_out_mem_ptr;
            DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
            // Settting the entire storage nicely
            for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
                bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
                bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
                bufHdr->nAllocLen          = bytes;
                bufHdr->nFilledLen         = 0;
                bufHdr->pAppPrivate        = appData;
                bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
                bufHdr->pBuffer            = NULL;
                bufHdr++;
                m_pOutput_pmem[i].fd = -1;
#ifdef USE_ION
                m_pOutput_ion[i].ion_device_fd =-1;
                m_pOutput_ion[i].fd_ion_data.fd=-1;
                m_pOutput_ion[i].ion_alloc_data.handle = 0;
#endif
            }
        } else {
            DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]",m_out_mem_ptr);
            eRet =  OMX_ErrorInsufficientResources;
        }
    }

    for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
        if (BITMASK_ABSENT(&m_out_bm_count,i)) {
            break;
        }
    }

    if (eRet == OMX_ErrorNone) {
        if (i < m_sOutPortDef.nBufferCountActual) {
            *bufferHdr = (m_out_mem_ptr + i );
            (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
            (*bufferHdr)->pAppPrivate = appData;

            if (!m_use_output_pmem) {
#ifdef USE_ION
#ifdef _MSM8974_
                align_size = (m_sOutPortDef.nBufferSize + (SZ_4K - 1)) & ~(SZ_4K - 1);
                m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size,
                        &m_pOutput_ion[i].ion_alloc_data,
                        &m_pOutput_ion[i].fd_ion_data,
                        secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
#else
                m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(
                        m_sOutPortDef.nBufferSize,
                        &m_pOutput_ion[i].ion_alloc_data,
                        &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED);
#endif
                if (m_pOutput_ion[i].ion_device_fd < 0) {
                    DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
                    return OMX_ErrorInsufficientResources;
                }
                m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
#else
                m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);

                if (m_pOutput_pmem[i].fd == 0) {
                    m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
                }

                if (m_pOutput_pmem[i].fd < 0) {
                    DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
                    return OMX_ErrorInsufficientResources;
                }
#endif
                m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
                m_pOutput_pmem[i].offset = 0;

                m_pOutput_pmem[i].buffer = NULL;
                if(!secure_session) {
#ifdef _MSM8974_
                    m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
                        align_size,PROT_READ|PROT_WRITE,
                        MAP_SHARED,m_pOutput_pmem[i].fd,0);
#else
                    m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
                        m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
                        MAP_SHARED,m_pOutput_pmem[i].fd,0);
#endif
                    if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
                        DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
                        m_pOutput_pmem[i].buffer = NULL;
                        close(m_pOutput_pmem[i].fd);
#ifdef USE_ION
                        free_ion_memory(&m_pOutput_ion[i]);
#endif
                        return OMX_ErrorInsufficientResources;
                    }
                }
            } else {
                OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
                DEBUG_PRINT_LOW("Inside qcom_ext pParam: %p", pParam);

                if (pParam) {
                    DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (int)pParam->offset);
                    m_pOutput_pmem[i].fd = pParam->pmem_fd;
                    m_pOutput_pmem[i].offset = pParam->offset;
                    m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
                    m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
                } else {
                    DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
                    return OMX_ErrorBadParameter;
                }
                buf_addr = (unsigned char *)buffer;
            }

            DEBUG_PRINT_LOW("use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
                    (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
            if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) {
                DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
                return OMX_ErrorInsufficientResources;
            }

            BITMASK_SET(&m_out_bm_count,i);
        } else {
            DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
                    "index = %u", i);
            eRet = OMX_ErrorInsufficientResources;
        }
    }
    return eRet;
}


/* ======================================================================
   FUNCTION
   omx_video::UseBuffer

   DESCRIPTION
   OMX Use Buffer method implementation.

   PARAMETERS
   <TBD>.

   RETURN VALUE
   OMX Error None , if everything successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::use_buffer(
        OMX_IN OMX_HANDLETYPE            hComp,
        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
        OMX_IN OMX_U32                   port,
        OMX_IN OMX_PTR                   appData,
        OMX_IN OMX_U32                   bytes,
        OMX_IN OMX_U8*                   buffer)
{
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    if (m_state == OMX_StateInvalid) {
        DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State");
        return OMX_ErrorInvalidState;
    }
    if (port == PORT_INDEX_IN) {
        eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
    } else if (port == PORT_INDEX_OUT) {
        eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
    } else {
        DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
        eRet = OMX_ErrorBadPortIndex;
    }

    if (eRet == OMX_ErrorNone) {
        if (allocate_done()) {
            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
                // Send the callback now
                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
                post_event(OMX_CommandStateSet,OMX_StateIdle,
                        OMX_COMPONENT_GENERATE_EVENT);
            }
        }
        if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
                post_event(OMX_CommandPortEnable,
                        PORT_INDEX_IN,
                        OMX_COMPONENT_GENERATE_EVENT);
            }

        } else if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
                post_event(OMX_CommandPortEnable,
                        PORT_INDEX_OUT,
                        OMX_COMPONENT_GENERATE_EVENT);
                m_event_port_settings_sent = false;
            }
        }
    }
    return eRet;
}

OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
{
    unsigned int index = 0;
    OMX_U8 *temp_buff ;

    if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
        DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
                bufferHdr, m_inp_mem_ptr);
        return OMX_ErrorBadParameter;
    }

    index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
#ifdef _ANDROID_ICS_
    if (meta_mode_enable) {
        if (index < m_sInPortDef.nBufferCountActual) {
            memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
            memset(&meta_buffers[index], 0, sizeof(meta_buffers[index]));
        }
        if (!mUseProxyColorFormat)
            return OMX_ErrorNone;
        else {
            c2d_conv.close();
            opaque_buffer_hdr[index] = NULL;
        }
    }
#endif
    if (index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat &&
            dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
        DEBUG_PRINT_LOW("ERROR: dev_free_buf() Failed for i/p buf");
    }

    if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) {
        auto_lock l(m_lock);

        if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) {
            DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case");
            if(!secure_session) {
                munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
            } else {
                free(m_pInput_pmem[index].buffer);
            }
            m_pInput_pmem[index].buffer = NULL;
            close (m_pInput_pmem[index].fd);
#ifdef USE_ION
            free_ion_memory(&m_pInput_ion[index]);
#endif
            m_pInput_pmem[index].fd = -1;
        } else if (m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
                    m_use_input_pmem == OMX_FALSE)) {
            DEBUG_PRINT_LOW("FreeBuffer:: i/p Heap UseBuffer case");
            if (dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
                DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf");
            }
            if(!secure_session) {
                munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
                m_pInput_pmem[index].buffer = NULL;
            }
            close (m_pInput_pmem[index].fd);
#ifdef USE_ION
            free_ion_memory(&m_pInput_ion[index]);
#endif
            m_pInput_pmem[index].fd = -1;
        } else {
            DEBUG_PRINT_ERROR("FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
        }
    }
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
{
    unsigned int index = 0;
    OMX_U8 *temp_buff ;

    if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
        DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
                bufferHdr, m_out_mem_ptr);
        return OMX_ErrorBadParameter;
    }
    index = bufferHdr - m_out_mem_ptr;

    if (index < m_sOutPortDef.nBufferCountActual &&
            dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
        DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
    }

    if (index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) {
        if (m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) {
            DEBUG_PRINT_LOW("FreeBuffer:: o/p AllocateBuffer case");
            if(!secure_session) {
                munmap (m_pOutput_pmem[index].buffer,
                        m_pOutput_pmem[index].size);
            } else {
                char *data = (char*) m_pOutput_pmem[index].buffer;
                native_handle_t *handle = NULL;
                memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*));
                native_handle_delete(handle);
                free(m_pOutput_pmem[index].buffer);
            }
            close (m_pOutput_pmem[index].fd);
#ifdef USE_ION
            free_ion_memory(&m_pOutput_ion[index]);
#endif
            m_pOutput_pmem[index].fd = -1;
        } else if ( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
                    && m_use_output_pmem == OMX_FALSE)) {
            DEBUG_PRINT_LOW("FreeBuffer:: o/p Heap UseBuffer case");
            if (dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
                DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
            }
            if(!secure_session) {
                munmap (m_pOutput_pmem[index].buffer,
                        m_pOutput_pmem[index].size);
            }
            close (m_pOutput_pmem[index].fd);
#ifdef USE_ION
            free_ion_memory(&m_pOutput_ion[index]);
#endif
            m_pOutput_pmem[index].fd = -1;
        } else {
            DEBUG_PRINT_LOW("FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
        }
    }
    return OMX_ErrorNone;
}
#ifdef _ANDROID_ICS_
OMX_ERRORTYPE omx_video::allocate_input_meta_buffer(
        OMX_HANDLETYPE       hComp,
        OMX_BUFFERHEADERTYPE **bufferHdr,
        OMX_PTR              appData,
        OMX_U32              bytes)
{
    unsigned index = 0;
    if (!bufferHdr || bytes < sizeof(encoder_media_buffer_type)) {
        DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %u",
                bufferHdr, (unsigned int)bytes);
        return OMX_ErrorBadParameter;
    }

    if (!m_inp_mem_ptr && !mUseProxyColorFormat) {
        m_inp_mem_ptr = meta_buffer_hdr;
        DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p",
                meta_buffer_hdr, m_inp_mem_ptr);
    }
    for (index = 0; ((index < m_sInPortDef.nBufferCountActual) &&
                meta_buffer_hdr[index].pBuffer); index++);
    if (index == m_sInPortDef.nBufferCountActual) {
        DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer");
        return OMX_ErrorBadParameter;
    }
    if (mUseProxyColorFormat) {
        if (opaque_buffer_hdr[index]) {
            DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
            return OMX_ErrorBadParameter;
        }
        if (allocate_input_buffer(hComp,&opaque_buffer_hdr[index],
                    PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) {
            DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
            return OMX_ErrorBadParameter;
        }
    }
    BITMASK_SET(&m_inp_bm_count,index);
    *bufferHdr = &meta_buffer_hdr[index];
    memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
    meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]);
    meta_buffer_hdr[index].nAllocLen = sizeof(meta_buffers[index]);
    meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION;
    meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN;
    meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index];
    meta_buffer_hdr[index].pAppPrivate = appData;
    if (mUseProxyColorFormat) {
        m_opq_pmem_q.insert_entry((unsigned long)opaque_buffer_hdr[index],0,0);
        DEBUG_PRINT_HIGH("opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]);
    }
    return OMX_ErrorNone;
}
#endif
/* ======================================================================
   FUNCTION
   omx_venc::AllocateInputBuffer

   DESCRIPTION
   Helper function for allocate buffer in the input pin

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::allocate_input_buffer(
        OMX_IN OMX_HANDLETYPE            hComp,
        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
        OMX_IN OMX_U32                   port,
        OMX_IN OMX_PTR                   appData,
        OMX_IN OMX_U32                   bytes)
{
    (void)hComp, (void)port;
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    unsigned   i = 0;

    DEBUG_PRINT_HIGH("allocate_input_buffer()::");
    if (bytes < m_sInPortDef.nBufferSize) {
        DEBUG_PRINT_ERROR("ERROR: Buffer size mismatch error: bytes[%u] < nBufferSize[%u]",
                (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
        return OMX_ErrorBadParameter;
    }

    if (!m_inp_mem_ptr) {
        DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
                (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountActual);
        m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
                        calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
        if (m_inp_mem_ptr == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
            return OMX_ErrorInsufficientResources;
        }

        DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
        m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);

        if (m_pInput_pmem == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
            return OMX_ErrorInsufficientResources;
        }
#ifdef USE_ION
        m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
        if (m_pInput_ion == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
            return OMX_ErrorInsufficientResources;
        }
#endif
        for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
            m_pInput_pmem[i].fd = -1;
#ifdef USE_ION
            m_pInput_ion[i].ion_device_fd =-1;
            m_pInput_ion[i].fd_ion_data.fd =-1;
            m_pInput_ion[i].ion_alloc_data.handle = 0;
#endif
        }
    }

    for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
        if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
            break;
        }
    }
    if (i < m_sInPortDef.nBufferCountActual) {

        *bufferHdr = (m_inp_mem_ptr + i);
        (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
        (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
        (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
        (*bufferHdr)->pAppPrivate       = appData;
        (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
        // make fd available to app layer, help with testing
        (*bufferHdr)->pInputPortPrivate = (OMX_PTR)&m_pInput_pmem[i];

#ifdef USE_ION
#ifdef _MSM8974_
        m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
                &m_pInput_ion[i].ion_alloc_data,
                &m_pInput_ion[i].fd_ion_data,
                secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0);
#else
        m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
                &m_pInput_ion[i].ion_alloc_data,
                &m_pInput_ion[i].fd_ion_data, ION_FLAG_CACHED);
#endif
        if (m_pInput_ion[i].ion_device_fd < 0) {
            DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
            return OMX_ErrorInsufficientResources;
        }

        m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
#else
        m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);

        if (m_pInput_pmem[i].fd == 0) {
            m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
        }

        if (m_pInput_pmem[i].fd < 0) {
            DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed");
            return OMX_ErrorInsufficientResources;
        }
#endif
        m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
        m_pInput_pmem[i].offset = 0;

        m_pInput_pmem[i].buffer = NULL;
        if(!secure_session) {
            m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,
                m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
                MAP_SHARED,m_pInput_pmem[i].fd,0);
            if (m_pInput_pmem[i].buffer == MAP_FAILED) {
                DEBUG_PRINT_ERROR("ERROR: mmap FAILED= %d", errno);
                m_pInput_pmem[i].buffer = NULL;
                close(m_pInput_pmem[i].fd);
#ifdef USE_ION
                free_ion_memory(&m_pInput_ion[i]);
#endif
                return OMX_ErrorInsufficientResources;
            }
        } else {
            //This should only be used for passing reference to source type and
            //secure handle fd struct native_handle_t*
            m_pInput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*));
            if (m_pInput_pmem[i].buffer == NULL) {
                DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__);
                return OMX_ErrorInsufficientResources;
            }
        }

        (*bufferHdr)->pBuffer           = (OMX_U8 *)m_pInput_pmem[i].buffer;
        DEBUG_PRINT_LOW("Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer);
        BITMASK_SET(&m_inp_bm_count,i);
        //here change the I/P param here from buf_adr to pmem
        if (!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) {
            DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for i/p buf");
            return OMX_ErrorInsufficientResources;
        }
    } else {
        DEBUG_PRINT_ERROR("ERROR: All i/p buffers are allocated, invalid allocate buf call"
                "for index [%d]", i);
        eRet = OMX_ErrorInsufficientResources;
    }

    return eRet;
}


/* ======================================================================
   FUNCTION
   omx_venc::AllocateOutputBuffer

   DESCRIPTION
   Helper fn for AllocateBuffer in the output pin

   PARAMETERS
   <TBD>.

   RETURN VALUE
   OMX Error None if everything went well.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::allocate_output_buffer(
        OMX_IN OMX_HANDLETYPE            hComp,
        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
        OMX_IN OMX_U32                   port,
        OMX_IN OMX_PTR                   appData,
        OMX_IN OMX_U32                   bytes)
{
    (void)hComp, (void)port;
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
    unsigned                         i= 0; // Temporary counter
#ifdef _MSM8974_
    int align_size;
#endif
    DEBUG_PRINT_HIGH("allocate_output_buffer()for %u bytes", (unsigned int)bytes);
    if (!m_out_mem_ptr) {
        int nBufHdrSize        = 0;
        DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
                (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountActual);
        nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);

        /*
         * Memory for output side involves the following:
         * 1. Array of Buffer Headers
         * 2. Bitmask array to hold the buffer allocation details
         * In order to minimize the memory management entire allocation
         * is done in one step.
         */
        m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);

#ifdef USE_ION
        m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
        if (m_pOutput_ion == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
            return OMX_ErrorInsufficientResources;
        }
#endif
        m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
        if (m_pOutput_pmem == NULL) {
            DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
            return OMX_ErrorInsufficientResources;
        }
        if (m_out_mem_ptr && m_pOutput_pmem) {
            bufHdr          =  m_out_mem_ptr;

            for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
                bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
                bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
                // Set the values when we determine the right HxW param
                bufHdr->nAllocLen          = m_sOutPortDef.nBufferSize;
                bufHdr->nFilledLen         = 0;
                bufHdr->pAppPrivate        = appData;
                bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
                // make fd available to app layer, help with testing
                bufHdr->pOutputPortPrivate = (OMX_PTR)&m_pOutput_pmem[i];
                bufHdr->pBuffer            = NULL;
                bufHdr++;
                m_pOutput_pmem[i].fd = -1;
#ifdef USE_ION
                m_pOutput_ion[i].ion_device_fd =-1;
                m_pOutput_ion[i].fd_ion_data.fd=-1;
                m_pOutput_ion[i].ion_alloc_data.handle = 0;
#endif
            }
        } else {
            DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
            eRet = OMX_ErrorInsufficientResources;
        }
    }

    DEBUG_PRINT_HIGH("actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferCountActual);
    for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
        if (BITMASK_ABSENT(&m_out_bm_count,i)) {
            DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
            break;
        }
    }
    if (eRet == OMX_ErrorNone) {
        if (i < m_sOutPortDef.nBufferCountActual) {
#ifdef USE_ION
#ifdef _MSM8974_
            align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096;
            m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size,
                    &m_pOutput_ion[i].ion_alloc_data,
                    &m_pOutput_ion[i].fd_ion_data,
                    secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : ION_FLAG_CACHED);
#else
            m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize,
                    &m_pOutput_ion[i].ion_alloc_data,
                    &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED);
#endif
            if (m_pOutput_ion[i].ion_device_fd < 0) {
                DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
                return OMX_ErrorInsufficientResources;
            }

            m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
#else
            m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
            if (m_pOutput_pmem[i].fd == 0) {
                m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
            }

            if (m_pOutput_pmem[i].fd < 0) {
                DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() failed");
                return OMX_ErrorInsufficientResources;
            }
#endif
            m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
            m_pOutput_pmem[i].offset = 0;

            m_pOutput_pmem[i].buffer = NULL;
            if(!secure_session) {
#ifdef _MSM8974_
                m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
                    align_size,PROT_READ|PROT_WRITE,
                    MAP_SHARED,m_pOutput_pmem[i].fd,0);
#else
                m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,
                    m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
                    MAP_SHARED,m_pOutput_pmem[i].fd,0);
#endif
                if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
                    DEBUG_PRINT_ERROR("ERROR: MMAP_FAILED in o/p alloc buffer");
                    m_pOutput_pmem[i].buffer = NULL;
                    close (m_pOutput_pmem[i].fd);
#ifdef USE_ION
                    free_ion_memory(&m_pOutput_ion[i]);
#endif
                    return OMX_ErrorInsufficientResources;
                }
            }
            else {
                //This should only be used for passing reference to source type and
                //secure handle fd struct native_handle_t*
                m_pOutput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*));
                if (m_pOutput_pmem[i].buffer == NULL) {
                    DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__);
                    return OMX_ErrorInsufficientResources;
                }
                native_handle_t *handle = native_handle_create(1, 0);
                handle->data[0] = m_pOutput_pmem[i].fd;
                char *data = (char*) m_pOutput_pmem[i].buffer;
                OMX_U32 type = 1;
                memcpy(data, &type, sizeof(OMX_U32));
                memcpy(data + sizeof(OMX_U32), &handle, sizeof(native_handle_t*));
            }

            *bufferHdr = (m_out_mem_ptr + i );
            (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
            (*bufferHdr)->pAppPrivate = appData;

            BITMASK_SET(&m_out_bm_count,i);

            if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) {
                DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for o/p buf");
                return OMX_ErrorInsufficientResources;
            }
        } else {
            DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call"
                    "for index [%d] actual: %u", i, (unsigned int)m_sOutPortDef.nBufferCountActual);
        }
    }

    return eRet;
}


// AllocateBuffer  -- API Call
/* ======================================================================
   FUNCTION
   omx_video::AllocateBuffer

   DESCRIPTION
   Returns zero if all the buffers released..

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
        OMX_IN OMX_U32                        port,
        OMX_IN OMX_PTR                     appData,
        OMX_IN OMX_U32                       bytes)
{

    OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type

    DEBUG_PRINT_LOW("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port);
    if (m_state == OMX_StateInvalid) {
        DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
        return OMX_ErrorInvalidState;
    }

    // What if the client calls again.
    if (port == PORT_INDEX_IN) {
#ifdef _ANDROID_ICS_
        if (meta_mode_enable)
            eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
        else
#endif
            eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
    } else if (port == PORT_INDEX_OUT) {
        eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
    } else {
        DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
        eRet = OMX_ErrorBadPortIndex;
    }
    DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
    if (eRet == OMX_ErrorNone) {
        if (allocate_done()) {
            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
                // Send the callback now
                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
                post_event(OMX_CommandStateSet,OMX_StateIdle,
                        OMX_COMPONENT_GENERATE_EVENT);
            }
        }
        if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
                post_event(OMX_CommandPortEnable,
                        PORT_INDEX_IN,
                        OMX_COMPONENT_GENERATE_EVENT);
            }
        }
        if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
                post_event(OMX_CommandPortEnable,
                        PORT_INDEX_OUT,
                        OMX_COMPONENT_GENERATE_EVENT);
                m_event_port_settings_sent = false;
            }
        }
    }
    DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
    return eRet;
}


// Free Buffer - API call
/* ======================================================================
   FUNCTION
   omx_video::FreeBuffer

   DESCRIPTION

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
        OMX_IN OMX_U32                 port,
        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
{
    (void)hComp;
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    unsigned int nPortIndex;

    DEBUG_PRINT_LOW("In for encoder free_buffer");

    if (m_state == OMX_StateIdle &&
            (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
        DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
    } else if ((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
            (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) {
        DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
    } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
        DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled");
        post_event(OMX_EventError,
                OMX_ErrorPortUnpopulated,
                OMX_COMPONENT_GENERATE_EVENT);
        return eRet;
    } else {
        DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers");
        post_event(OMX_EventError,
                OMX_ErrorPortUnpopulated,
                OMX_COMPONENT_GENERATE_EVENT);
    }

    if (port == PORT_INDEX_IN) {
        // check if the buffer is valid
        nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);

        DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
                nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
        if (nPortIndex < m_sInPortDef.nBufferCountActual &&
                BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
            // Clear the bit associated with it.
            BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
            free_input_buffer (buffer);
            m_sInPortDef.bPopulated = OMX_FALSE;

            /*Free the Buffer Header*/
            if (release_input_done()
#ifdef _ANDROID_ICS_
                    && !meta_mode_enable
#endif
               ) {
                input_use_buffer = false;
                if (m_inp_mem_ptr) {
                    DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr");
                    free (m_inp_mem_ptr);
                    m_inp_mem_ptr = NULL;
                }
                if (m_pInput_pmem) {
                    DEBUG_PRINT_LOW("Freeing m_pInput_pmem");
                    free(m_pInput_pmem);
                    m_pInput_pmem = NULL;
                }
#ifdef USE_ION
                if (m_pInput_ion) {
                    DEBUG_PRINT_LOW("Freeing m_pInput_ion");
                    free(m_pInput_ion);
                    m_pInput_ion = NULL;
                }
#endif
            }
        } else {
            DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid");
            eRet = OMX_ErrorBadPortIndex;
        }

        if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
                && release_input_done()) {
            DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
            post_event(OMX_CommandPortDisable,
                    PORT_INDEX_IN,
                    OMX_COMPONENT_GENERATE_EVENT);
        }
    } else if (port == PORT_INDEX_OUT) {
        // check if the buffer is valid
        nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;

        DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u",
                nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
        if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
                BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
            // Clear the bit associated with it.
            BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
            m_sOutPortDef.bPopulated = OMX_FALSE;
            free_output_buffer (buffer);

            if (release_output_done()) {
                output_use_buffer = false;
                if (m_out_mem_ptr) {
                    DEBUG_PRINT_LOW("Freeing m_out_mem_ptr");
                    free (m_out_mem_ptr);
                    m_out_mem_ptr = NULL;
                }
                if (m_pOutput_pmem) {
                    DEBUG_PRINT_LOW("Freeing m_pOutput_pmem");
                    free(m_pOutput_pmem);
                    m_pOutput_pmem = NULL;
                }
#ifdef USE_ION
                if (m_pOutput_ion) {
                    DEBUG_PRINT_LOW("Freeing m_pOutput_ion");
                    free(m_pOutput_ion);
                    m_pOutput_ion = NULL;
                }
#endif
            }
        } else {
            DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid");
            eRet = OMX_ErrorBadPortIndex;
        }
        if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
                && release_output_done() ) {
            DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");

            DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
            post_event(OMX_CommandPortDisable,
                    PORT_INDEX_OUT,
                    OMX_COMPONENT_GENERATE_EVENT);

        }
    } else {
        eRet = OMX_ErrorBadPortIndex;
    }
    if ((eRet == OMX_ErrorNone) &&
            (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
        if (release_done()) {
            if (dev_stop() != 0) {
                DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED");
                eRet = OMX_ErrorHardware;
            }
            // Send the callback now
            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
            post_event(OMX_CommandStateSet, OMX_StateLoaded,
                    OMX_COMPONENT_GENERATE_EVENT);
        } else {
            DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers input %" PRIx64" output %" PRIx64,
                    m_out_bm_count, m_inp_bm_count);
        }
    }

    return eRet;
}


/* ======================================================================
   FUNCTION
   omx_video::EmptyThisBuffer

   DESCRIPTION
   This routine is used to push the encoded video frames to
   the video decoder.

   PARAMETERS
   None.

   RETURN VALUE
   OMX Error None if everything went successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
{
    OMX_ERRORTYPE ret1 = OMX_ErrorNone;
    unsigned int nBufferIndex ;

    dev_set_extradata_cookie((void *)buffer);
    DEBUG_PRINT_LOW("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer);
    if (m_state != OMX_StateExecuting &&
            m_state != OMX_StatePause &&
            m_state != OMX_StateIdle) {
        DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State");
        return OMX_ErrorInvalidState;
    }

    if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
        DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid");
        return OMX_ErrorBadParameter;
    }

    if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
        DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid");
        return OMX_ErrorVersionMismatch;
    }

    if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) {
        DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer");
        return OMX_ErrorBadPortIndex;
    }
    if (!m_sInPortDef.bEnabled) {
        DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled");
        return OMX_ErrorIncorrectStateOperation;
    }

    nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);

    if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
        DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
        return OMX_ErrorBadParameter;
    }

    m_etb_count++;
    DEBUG_PRINT_LOW("DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
    post_event ((unsigned long)hComp,(unsigned long)buffer,m_input_msg_id);
    return OMX_ErrorNone;
}
/* ======================================================================
   FUNCTION
   omx_video::empty_this_buffer_proxy

   DESCRIPTION
   This routine is used to push the encoded video frames to
   the video decoder.

   PARAMETERS
   None.

   RETURN VALUE
   OMX Error None if everything went successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
{
    (void)hComp;
    OMX_U8 *pmem_data_buf = NULL;
    int push_cnt = 0;
    unsigned nBufIndex = 0;
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    encoder_media_buffer_type *media_buffer = NULL;

#ifdef _MSM8974_
    int fd = 0;
#endif
    DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer);
    if (buffer == NULL) {
        DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer);
        return OMX_ErrorBadParameter;
    }

    // Buffer sanity checks
    if (meta_mode_enable && !mUsesColorConversion) {
        //For color-conversion case, we have an internal buffer and not a meta buffer
        bool met_error = false;
        nBufIndex = buffer - meta_buffer_hdr;
        if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
            DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex);
            return OMX_ErrorBadParameter;
        }
        media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer;
        if (media_buffer) {
            if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource &&
                    media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
                met_error = true;
            } else {
                if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
                    if (media_buffer->meta_handle == NULL)
                        met_error = true;
                    else {
                        int nFds = media_buffer->meta_handle->numFds,
                            nInt = media_buffer->meta_handle->numInts;
                        met_error = ((nFds == 1 && nInt >= 2) /*normal*/ ||
                                (nFds < 16 && nInt >= nFds*3) /*batch*/) ? false : true;
                        if (met_error) {
                            DEBUG_PRINT_ERROR("Unbalanced fds in handle: fds=%d ints=%d",
                                    nFds, nInt);
                        }
                    }
                }
            }
        } else
            met_error = true;
        if (met_error) {
            DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call");
            post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
            return OMX_ErrorBadParameter;
        }
    } else {
        nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
        if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
            DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex);
            return OMX_ErrorBadParameter;
        }
    }

    pending_input_buffers++;
    if (input_flush_progress == true) {
        post_event ((unsigned long)buffer,0,
                OMX_COMPONENT_GENERATE_EBD);
        DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress");
        return OMX_ErrorNone;
    }
#ifdef _MSM8974_
    if (!meta_mode_enable) {
        fd = m_pInput_pmem[nBufIndex].fd;
    }
#endif
#ifdef _ANDROID_ICS_
    if (meta_mode_enable && !mUsesColorConversion) {
        // Camera or Gralloc-source meta-buffers queued with encodeable color-format
        struct pmem Input_pmem_info;
        if (!media_buffer) {
            DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
            return OMX_ErrorBadParameter;
        }
        if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
            Input_pmem_info.buffer = media_buffer;
            Input_pmem_info.fd = media_buffer->meta_handle->data[0];
#ifdef _MSM8974_
            fd = Input_pmem_info.fd;
#endif
            Input_pmem_info.offset = media_buffer->meta_handle->data[1];
            Input_pmem_info.size = media_buffer->meta_handle->data[2];
            DEBUG_PRINT_LOW("ETB (meta-Camera) fd = %d, offset = %d, size = %d",
                    Input_pmem_info.fd, Input_pmem_info.offset,
                    Input_pmem_info.size);
        } else {
            private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
            Input_pmem_info.buffer = media_buffer;
            Input_pmem_info.fd = handle->fd;
#ifdef _MSM8974_
            fd = Input_pmem_info.fd;
#endif
            Input_pmem_info.offset = 0;
            Input_pmem_info.size = handle->size;
            DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
                    Input_pmem_info.fd, Input_pmem_info.offset,
                    Input_pmem_info.size);
        }
        if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,nBufIndex) != true) {
            DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
            post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
            return OMX_ErrorBadParameter;
        }
    } else if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
#else
    if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
#endif
    {
        DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");

        auto_lock l(m_lock);
        pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
        if (pmem_data_buf) {
            memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
                    buffer->nFilledLen);
        }
        DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
    } else if (mUseProxyColorFormat) {
        // Gralloc-source buffers with color-conversion
        fd = m_pInput_pmem[nBufIndex].fd;
        DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u",
                fd, (unsigned int)buffer->nFilledLen);
    } else if (m_sInPortDef.format.video.eColorFormat ==
                    OMX_COLOR_FormatYUV420SemiPlanar) {
            //For the case where YUV420SP buffers are qeueued to component
            //by sources other than camera (Apps via MediaCodec), conversion
            //to vendor flavoured NV12 color format is required.
            if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth,
                                    m_sInPortDef.format.video.nFrameHeight)) {
                    DEBUG_PRINT_ERROR("Failed to adjust buffer color");
                    post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
                    return OMX_ErrorUndefined;
            }
    }
    if (m_sExtraData && !dev_handle_input_extradata((void *)buffer, fd)) {
            DEBUG_PRINT_ERROR("Failed to parse input extradata\n");
#ifdef _ANDROID_ICS_
        omx_release_meta_buffer(buffer);
#endif
        post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
        /*Generate an async error and move to invalid state*/
        pending_input_buffers--;
        return OMX_ErrorBadParameter;
    }
#ifdef _MSM8974_
    if (dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true)
#else
    if (dev_empty_buf(buffer, pmem_data_buf,0,0) != true)
#endif
    {
        DEBUG_PRINT_ERROR("ERROR: ETBProxy: dev_empty_buf failed");
#ifdef _ANDROID_ICS_
        omx_release_meta_buffer(buffer);
#endif
        post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
        /*Generate an async error and move to invalid state*/
        pending_input_buffers--;
        if (hw_overload) {
            return OMX_ErrorInsufficientResources;
        }
        return OMX_ErrorBadParameter;
    }
    return ret;
}

/* ======================================================================
   FUNCTION
   omx_video::FillThisBuffer

   DESCRIPTION
   IL client uses this method to release the frame buffer
   after displaying them.

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
{
    DEBUG_PRINT_LOW("FTB: buffer->pBuffer[%p]", buffer->pBuffer);
    if (m_state != OMX_StateExecuting &&
            m_state != OMX_StatePause &&
            m_state != OMX_StateIdle) {
        DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State");
        return OMX_ErrorInvalidState;
    }

    if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
        DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size");
        return OMX_ErrorBadParameter;
    }

    if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
        DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid");
        return OMX_ErrorVersionMismatch;
    }

    if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) {
        DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index");
        return OMX_ErrorBadPortIndex;
    }

    if (!m_sOutPortDef.bEnabled) {
        DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled");
        return OMX_ErrorIncorrectStateOperation;
    }

    post_event((unsigned long) hComp, (unsigned long)buffer,OMX_COMPONENT_GENERATE_FTB);
    return OMX_ErrorNone;
}

/* ======================================================================
   FUNCTION
   omx_video::fill_this_buffer_proxy

   DESCRIPTION
   IL client uses this method to release the frame buffer
   after displaying them.

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
OMX_ERRORTYPE  omx_video::fill_this_buffer_proxy(
        OMX_IN OMX_HANDLETYPE        hComp,
        OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
{
    (void)hComp;
    OMX_U8 *pmem_data_buf = NULL;
    OMX_ERRORTYPE nRet = OMX_ErrorNone;

    DEBUG_PRINT_LOW("FTBProxy: bufferAdd->pBuffer[%p]", bufferAdd->pBuffer);

    if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) {
        DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params");
        return OMX_ErrorBadParameter;
    }

    pending_output_buffers++;
    /*Return back the output buffer to client*/
    if ( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) {
        DEBUG_PRINT_LOW("o/p port is Disabled or Flush in Progress");
        post_event ((unsigned long)bufferAdd,0,
                OMX_COMPONENT_GENERATE_FBD);
        return OMX_ErrorNone;
    }

    if (output_use_buffer && !m_use_output_pmem) {
        DEBUG_PRINT_LOW("Heap UseBuffer case");
        pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
    }

    if (dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) {
        DEBUG_PRINT_ERROR("ERROR: dev_fill_buf() Failed");
        post_event ((unsigned long)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
        pending_output_buffers--;
        return OMX_ErrorBadParameter;
    }

    return OMX_ErrorNone;
}

/* ======================================================================
   FUNCTION
   omx_video::SetCallbacks

   DESCRIPTION
   Set the callbacks.

   PARAMETERS
   None.

   RETURN VALUE
   OMX Error None if everything successful.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
        OMX_IN OMX_CALLBACKTYPE* callbacks,
        OMX_IN OMX_PTR             appData)
{
    (void)hComp;
    m_pCallbacks       = *callbacks;
    DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
            m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
    m_app_data =    appData;
    return OMX_ErrorNotImplemented;
}


/* ======================================================================
   FUNCTION
   omx_venc::UseEGLImage

   DESCRIPTION
   OMX Use EGL Image method implementation <TBD>.

   PARAMETERS
   <TBD>.

   RETURN VALUE
   Not Implemented error.

   ========================================================================== */
OMX_ERRORTYPE  omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE   hComp,
        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
        OMX_IN OMX_U32                        port,
        OMX_IN OMX_PTR                     appData,
        OMX_IN void*                      eglImage)
{
    (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage;
    DEBUG_PRINT_ERROR("ERROR: use_EGL_image:  Not Implemented");
    return OMX_ErrorNotImplemented;
}

/* ======================================================================
   FUNCTION
   omx_venc::ComponentRoleEnum

   DESCRIPTION
   OMX Component Role Enum method implementation.

   PARAMETERS
   <TBD>.

   RETURN VALUE
   OMX Error None if everything is successful.
   ========================================================================== */
OMX_ERRORTYPE  omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
        OMX_OUT OMX_U8*        role,
        OMX_IN OMX_U32        index)
{
    (void)hComp;
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            eRet = OMX_ErrorNoMore;
        }
    } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            DEBUG_PRINT_ERROR("ERROR: No more roles");
            eRet = OMX_ErrorNoMore;
        }
    } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            DEBUG_PRINT_ERROR("ERROR: No more roles");
            eRet = OMX_ErrorNoMore;
        }
    } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            DEBUG_PRINT_ERROR("ERROR: No more roles");
            eRet = OMX_ErrorNoMore;
        }
    }
    if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            eRet = OMX_ErrorNoMore;
        }
    } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            DEBUG_PRINT_ERROR("ERROR: No more roles");
            eRet = OMX_ErrorNoMore;
        }
    } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            DEBUG_PRINT_ERROR("ERROR: No more roles");
            eRet = OMX_ErrorNoMore;
        }
    }
#ifdef _MSM8974_
    else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
        } else {
            DEBUG_PRINT_ERROR("ERROR: No more roles");
            eRet = OMX_ErrorNoMore;
        }
    }
#endif
    else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
        if ((0 == index) && role) {
            strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
            DEBUG_PRINT_LOW("component_role_enum: role %s", role);
        } else {
            DEBUG_PRINT_ERROR("ERROR: No more roles");
            eRet = OMX_ErrorNoMore;
        }
    }
    else {
        DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
        eRet = OMX_ErrorInvalidComponentName;
    }
    return eRet;
}




/* ======================================================================
   FUNCTION
   omx_venc::AllocateDone

   DESCRIPTION
   Checks if entire buffer pool is allocated by IL Client or not.
   Need this to move to IDLE state.

   PARAMETERS
   None.

   RETURN VALUE
   true/false.

   ========================================================================== */
bool omx_video::allocate_done(void)
{
    bool bRet = false;
    bool bRet_In = false;
    bool bRet_Out = false;

    bRet_In = allocate_input_done();
    bRet_Out = allocate_output_done();

    if (bRet_In && bRet_Out) {
        bRet = true;
    }

    return bRet;
}
/* ======================================================================
   FUNCTION
   omx_venc::AllocateInputDone

   DESCRIPTION
   Checks if I/P buffer pool is allocated by IL Client or not.

   PARAMETERS
   None.

   RETURN VALUE
   true/false.

   ========================================================================== */
bool omx_video::allocate_input_done(void)
{
    bool bRet = false;
    unsigned i=0;

    if (m_inp_mem_ptr == NULL) {
        return bRet;
    }
    if (m_inp_mem_ptr ) {
        for (; i<m_sInPortDef.nBufferCountActual; i++) {
            if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
                break;
            }
        }
    }
    if (i==m_sInPortDef.nBufferCountActual) {
        bRet = true;
    }
    if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) {
        m_sInPortDef.bPopulated = OMX_TRUE;
    }
    return bRet;
}
/* ======================================================================
   FUNCTION
   omx_venc::AllocateOutputDone

   DESCRIPTION
   Checks if entire O/P buffer pool is allocated by IL Client or not.

   PARAMETERS
   None.

   RETURN VALUE
   true/false.

   ========================================================================== */
bool omx_video::allocate_output_done(void)
{
    bool bRet = false;
    unsigned j=0;

    if (m_out_mem_ptr == NULL) {
        return bRet;
    }

    if (m_out_mem_ptr ) {
        for (; j<m_sOutPortDef.nBufferCountActual; j++) {
            if (BITMASK_ABSENT(&m_out_bm_count,j)) {
                break;
            }
        }
    }

    if (j==m_sOutPortDef.nBufferCountActual) {
        bRet = true;
    }

    if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) {
        m_sOutPortDef.bPopulated = OMX_TRUE;
    }
    return bRet;
}

/* ======================================================================
   FUNCTION
   omx_venc::ReleaseDone

   DESCRIPTION
   Checks if IL client has released all the buffers.

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
bool omx_video::release_done(void)
{
    bool bRet = false;
    DEBUG_PRINT_LOW("Inside release_done()");
    if (release_input_done()) {
        if (release_output_done()) {
            bRet = true;
        }
    }
    return bRet;
}


/* ======================================================================
   FUNCTION
   omx_venc::ReleaseOutputDone

   DESCRIPTION
   Checks if IL client has released all the buffers.

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
bool omx_video::release_output_done(void)
{
    bool bRet = false;
    unsigned i=0,j=0;

    DEBUG_PRINT_LOW("Inside release_output_done()");
    if (m_out_mem_ptr) {
        for (; j<m_sOutPortDef.nBufferCountActual; j++) {
            if (BITMASK_PRESENT(&m_out_bm_count,j)) {
                break;
            }
        }
        if (j==m_sOutPortDef.nBufferCountActual) {
            bRet = true;
        }
    } else {
        bRet = true;
    }
    return bRet;
}
/* ======================================================================
   FUNCTION
   omx_venc::ReleaseInputDone

   DESCRIPTION
   Checks if IL client has released all the buffers.

   PARAMETERS
   None.

   RETURN VALUE
   true/false

   ========================================================================== */
bool omx_video::release_input_done(void)
{
    bool bRet = false;
    unsigned i=0,j=0;

    DEBUG_PRINT_LOW("Inside release_input_done()");
    if (m_inp_mem_ptr) {
        for (; j<m_sInPortDef.nBufferCountActual; j++) {
            if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
                break;
            }
        }
        if (j==m_sInPortDef.nBufferCountActual) {
            bRet = true;
        }
    } else {
        bRet = true;
    }
    return bRet;
}

OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
        OMX_BUFFERHEADERTYPE * buffer)
{
#ifdef _MSM8974_
    int index = buffer - m_out_mem_ptr;
#endif
    DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %u",
            buffer->pBuffer, (unsigned)buffer->nFlags, (unsigned int)buffer->nFilledLen);
    if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) {
        return OMX_ErrorBadParameter;
    }

    pending_output_buffers--;

    if(!secure_session) {
        extra_data_handle.create_extra_data(buffer);
#ifndef _MSM8974_
        if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
            DEBUG_PRINT_LOW("parsing extradata");
            extra_data_handle.parse_extra_data(buffer);
        }
#endif
    }

    /* For use buffer we need to copy the data */
    if (m_pCallbacks.FillBufferDone) {
        if (buffer->nFilledLen > 0) {
            m_fbd_count++;

            if (dev_get_output_log_flag()) {
                dev_output_log_buffers((const char*)buffer->pBuffer, buffer->nFilledLen);
            }
        }
        if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
            if (!dev_handle_output_extradata((void *)buffer))
                DEBUG_PRINT_ERROR("Failed to parse output extradata");

            dev_extradata_log_buffers((char *)(((unsigned long)buffer->pBuffer + buffer->nOffset +
                        buffer->nFilledLen + 3) & (~3)));
        }
        m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
    } else {
        return OMX_ErrorBadParameter;
    }
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE         hComp,
        OMX_BUFFERHEADERTYPE* buffer)
{
    int buffer_index  = -1;

    buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
    DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer);
    if (buffer == NULL ||
            ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
        DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
        return OMX_ErrorBadParameter;
    }

    pending_input_buffers--;

    if (mUseProxyColorFormat &&
        (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
        if (!pdest_frame  && !input_flush_progress && mUsesColorConversion) {
            pdest_frame = buffer;
            DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
            return push_input_buffer(hComp);
        }
        //check if empty-EOS-buffer is being returned, treat this same as the
        //color-conversion case as we queued a color-conversion buffer to encoder
        bool handleEmptyEosBuffer = (mEmptyEosBuffer == buffer);
        if (mUsesColorConversion || handleEmptyEosBuffer) {
            if (handleEmptyEosBuffer) {
                mEmptyEosBuffer = NULL;
            }
            // return color-conversion buffer back to the pool
            DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer);
            if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) {
                DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full");
                return OMX_ErrorBadParameter;
            }
        } else {
            // We are not dealing with color-conversion, Buffer being returned
            // here is client's buffer, return it back to client
            if (m_pCallbacks.EmptyBufferDone && buffer) {
                m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
                DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
            }
        }
    } else if (m_pCallbacks.EmptyBufferDone) {
        m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
    }
    return OMX_ErrorNone;
}

void omx_video::complete_pending_buffer_done_cbs()
{
    unsigned long p1;
    unsigned long p2;
    unsigned long ident;
    omx_cmd_queue tmp_q, pending_bd_q;
    pthread_mutex_lock(&m_lock);
    // pop all pending GENERATE FDB from ftb queue
    while (m_ftb_q.m_size) {
        m_ftb_q.pop_entry(&p1,&p2,&ident);
        if (ident == OMX_COMPONENT_GENERATE_FBD) {
            pending_bd_q.insert_entry(p1,p2,ident);
        } else {
            tmp_q.insert_entry(p1,p2,ident);
        }
    }
    //return all non GENERATE FDB to ftb queue
    while (tmp_q.m_size) {
        tmp_q.pop_entry(&p1,&p2,&ident);
        m_ftb_q.insert_entry(p1,p2,ident);
    }
    // pop all pending GENERATE EDB from etb queue
    while (m_etb_q.m_size) {
        m_etb_q.pop_entry(&p1,&p2,&ident);
        if (ident == OMX_COMPONENT_GENERATE_EBD) {
            pending_bd_q.insert_entry(p1,p2,ident);
        } else {
            tmp_q.insert_entry(p1,p2,ident);
        }
    }
    //return all non GENERATE FDB to etb queue
    while (tmp_q.m_size) {
        tmp_q.pop_entry(&p1,&p2,&ident);
        m_etb_q.insert_entry(p1,p2,ident);
    }
    pthread_mutex_unlock(&m_lock);
    // process all pending buffer dones
    while (pending_bd_q.m_size) {
        pending_bd_q.pop_entry(&p1,&p2,&ident);
        switch (ident) {
            case OMX_COMPONENT_GENERATE_EBD:
                if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
                    DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
                    omx_report_error ();
                }
                break;

            case OMX_COMPONENT_GENERATE_FBD:
                if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
                    DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
                    omx_report_error ();
                }
                break;
        }
    }
}

#ifdef MAX_RES_720P
OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
{
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    if (!profileLevelType)
        return OMX_ErrorBadParameter;

    if (profileLevelType->nPortIndex == 1) {
        if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
            } else if (profileLevelType->nProfileIndex == 1) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
            } else if (profileLevelType->nProfileIndex == 2) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
            } else {
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
                        (int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
        } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) {
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
                profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
            } else {
                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
        } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
            } else if (profileLevelType->nProfileIndex == 1) {
                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
            } else {
                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
        }
    } else {
        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %d", (int)profileLevelType->nPortIndex);
        eRet = OMX_ErrorBadPortIndex;
    }
    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d",
            (int)profileLevelType->eProfile, (int)profileLevelType->eLevel);
    return eRet;
}
#endif

#ifdef MAX_RES_1080P
OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
{
    OMX_ERRORTYPE eRet = OMX_ErrorNone;
    if (!profileLevelType)
        return OMX_ErrorBadParameter;

    if (profileLevelType->nPortIndex == 1) {
        if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
#if defined _MSM8974_ && !defined _MSM8226_
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
            } else if (profileLevelType->nProfileIndex == 1) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
            } else if (profileLevelType->nProfileIndex == 2) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
            } else if (profileLevelType->nProfileIndex == 3) {
                profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
            } else if (profileLevelType->nProfileIndex == 4) {
                profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel52;
            } else {
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
                        (unsigned int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
#else
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;

            } else if (profileLevelType->nProfileIndex == 1) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
            } else if (profileLevelType->nProfileIndex == 2) {
                profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
#ifdef _MSM8226_
            } else if (profileLevelType->nProfileIndex == 3) {
                profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
#endif
            } else {
                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
                        (int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
#endif
        } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) {
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
                profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
            } else {
                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
        } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
            } else if (profileLevelType->nProfileIndex == 1) {
                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
            } else {
                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
        } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) {
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
                profileLevelType->eLevel   = OMX_VIDEO_VP8Level_Version0;
            } else if (profileLevelType->nProfileIndex == 1) {
                profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
                profileLevelType->eLevel   = OMX_VIDEO_VP8Level_Version1;
            } else {
                DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
                (unsigned int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
        } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC) {
            if (profileLevelType->nProfileIndex == 0) {
                profileLevelType->eProfile =  OMX_VIDEO_HEVCProfileMain;
                profileLevelType->eLevel   =  OMX_VIDEO_HEVCMainTierLevel52;
            } else if (profileLevelType->nProfileIndex == 1) {
                profileLevelType->eProfile =  OMX_VIDEO_HEVCProfileMain10;
                profileLevelType->eLevel   =  OMX_VIDEO_HEVCMainTierLevel52;
            } else {
                DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
                (unsigned int)profileLevelType->nProfileIndex);
                eRet = OMX_ErrorNoMore;
            }
        } else {
            DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore");
            eRet = OMX_ErrorNoMore;
        }
    } else {
        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
        eRet = OMX_ErrorBadPortIndex;
    }
    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
            (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
    return eRet;
}
#endif

#ifdef USE_ION
int omx_video::alloc_map_ion_memory(int size,
        struct ion_allocation_data *alloc_data,
        struct ion_fd_data *fd_data,int flag)
{
    struct venc_ion buf_ion_info;
    int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
    if (size <=0 || !alloc_data || !fd_data) {
        DEBUG_PRINT_ERROR("Invalid input to alloc_map_ion_memory");
        return -EINVAL;
    }

    ion_dev_flags = O_RDONLY;
    ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
    if (ion_device_fd < 0) {
        DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed");
        return ion_device_fd;
    }

    if(secure_session) {
        alloc_data->len = (size + (SECURE_ALIGN - 1)) & ~(SECURE_ALIGN - 1);
        alloc_data->align = SECURE_ALIGN;
        alloc_data->flags = flag;
        alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
        if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
            alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
        }
        DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u align %u flags %x",
                (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
                alloc_data->flags);
    } else {
        alloc_data->len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
        alloc_data->align = SZ_4K;
        alloc_data->flags = (flag & ION_FLAG_CACHED ? ION_FLAG_CACHED : 0);
#ifdef MAX_RES_720P
        alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
#else
        alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
                                 ION_HEAP(ION_IOMMU_HEAP_ID));
#endif
        DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u align %u flags %x",
                (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
                alloc_data->flags);
    }

    rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
    if (rc || !alloc_data->handle) {
        DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc);
        alloc_data->handle = 0;
        close(ion_device_fd);
        ion_device_fd = -1;
        return ion_device_fd;
    }
    fd_data->handle = alloc_data->handle;
    rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
    if (rc) {
        DEBUG_PRINT_ERROR("ION MAP failed ");
        buf_ion_info.ion_alloc_data = *alloc_data;
        buf_ion_info.ion_device_fd = ion_device_fd;
        buf_ion_info.fd_ion_data = *fd_data;
        free_ion_memory(&buf_ion_info);
        fd_data->fd =-1;
        ion_device_fd =-1;
    }
    return ion_device_fd;
}

void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
{
    if (!buf_ion_info) {
        DEBUG_PRINT_ERROR("Invalid input to free_ion_memory");
        return;
    }
    if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
                &buf_ion_info->ion_alloc_data.handle)) {
        DEBUG_PRINT_ERROR("ION free failed ");
        return;
    }
    close(buf_ion_info->ion_device_fd);
    buf_ion_info->ion_alloc_data.handle = 0;
    buf_ion_info->ion_device_fd = -1;
    buf_ion_info->fd_ion_data.fd = -1;
}
#endif

#ifdef _ANDROID_ICS_
void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
{
    if (buffer && meta_mode_enable) {
        encoder_media_buffer_type *media_ptr;
        struct pmem Input_pmem;
        unsigned int index_pmem = 0;
        bool meta_error = false;

        index_pmem = (buffer - m_inp_mem_ptr);
        if (mUsesColorConversion &&
                (index_pmem < m_sInPortDef.nBufferCountActual)) {
            if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) {
                DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed");
            }
        } else {
            media_ptr = (encoder_media_buffer_type *) buffer->pBuffer;
            if (media_ptr && media_ptr->meta_handle) {
                if (media_ptr->buffer_type == kMetadataBufferTypeCameraSource &&
                        media_ptr->meta_handle->numFds == 1 &&
                        media_ptr->meta_handle->numInts >= 2) {
                    Input_pmem.fd = media_ptr->meta_handle->data[0];
                    Input_pmem.buffer = media_ptr;
                    Input_pmem.size = media_ptr->meta_handle->data[2];
                    Input_pmem.offset = media_ptr->meta_handle->data[1];
                    DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
                            Input_pmem.offset,
                            Input_pmem.size);
                } else if (media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
                    private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle;
                    Input_pmem.buffer = media_ptr;
                    Input_pmem.fd = handle->fd;
                    Input_pmem.offset = 0;
                    Input_pmem.size = handle->size;
                } else {
                    meta_error = true;
                    DEBUG_PRINT_ERROR(" Meta Error set in EBD");
                }
                if (!meta_error)
                    meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
                if (meta_error) {
                    DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d",
                            input_flush_progress);
                }
            }
        }
    }
}
#endif
omx_video::omx_c2d_conv::omx_c2d_conv()
{
    c2dcc = NULL;
    mLibHandle = NULL;
    mConvertOpen = NULL;
    mConvertClose = NULL;
    src_format = NV12_128m;
    pthread_mutex_init(&c_lock, NULL);
}

bool omx_video::omx_c2d_conv::init()
{
    bool status = true;
    if (mLibHandle || mConvertOpen || mConvertClose) {
        DEBUG_PRINT_ERROR("omx_c2d_conv::init called twice");
        status = false;
    }
    if (status) {
        mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY);
        if (mLibHandle) {
            mConvertOpen = (createC2DColorConverter_t *)
                dlsym(mLibHandle,"createC2DColorConverter");
            mConvertClose = (destroyC2DColorConverter_t *)
                dlsym(mLibHandle,"destroyC2DColorConverter");
            if (!mConvertOpen || !mConvertClose)
                status = false;
        } else
            status = false;
    }
    if (!status && mLibHandle) {
        dlclose(mLibHandle);
        mLibHandle = NULL;
        mConvertOpen = NULL;
        mConvertClose = NULL;
    }
    return status;
}

bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr,
        int dest_fd, void *dest_base, void *dest_viraddr)
{
    int result;
    if (!src_viraddr || !dest_viraddr || !c2dcc || !src_base || !dest_base) {
        DEBUG_PRINT_ERROR("Invalid arguments omx_c2d_conv::convert");
        return false;
    }
    pthread_mutex_lock(&c_lock);
    result =  c2dcc->convertC2D(src_fd, src_base, src_viraddr,
            dest_fd, dest_base, dest_viraddr);
    pthread_mutex_unlock(&c_lock);
    DEBUG_PRINT_LOW("Color convert status %d",result);
    return ((result < 0)?false:true);
}

bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width,
        ColorConvertFormat src, ColorConvertFormat dest,unsigned int src_stride)
{
    bool status = false;
    pthread_mutex_lock(&c_lock);
    if (!c2dcc) {
        c2dcc = mConvertOpen(width, height, width, height,
                src,dest,0,src_stride);
        if (c2dcc) {
            src_format = src;
            status = true;
        } else
            DEBUG_PRINT_ERROR("mConvertOpen failed");
    }
    pthread_mutex_unlock(&c_lock);
    return status;
}

void omx_video::omx_c2d_conv::close()
{
    if (mLibHandle) {
        pthread_mutex_lock(&c_lock);
        if (mConvertClose && c2dcc)
            mConvertClose(c2dcc);
        pthread_mutex_unlock(&c_lock);
        c2dcc = NULL;
    }
}
omx_video::omx_c2d_conv::~omx_c2d_conv()
{
    DEBUG_PRINT_HIGH("Destroy C2D instance");
    if (mLibHandle) {
        if (mConvertClose && c2dcc) {
            pthread_mutex_lock(&c_lock);
            mConvertClose(c2dcc);
            pthread_mutex_unlock(&c_lock);
        }
        dlclose(mLibHandle);
    }
    c2dcc = NULL;
    mLibHandle = NULL;
    mConvertOpen = NULL;
    mConvertClose = NULL;
    pthread_mutex_destroy(&c_lock);
}

int omx_video::omx_c2d_conv::get_src_format()
{
    int format = -1;
    if (src_format == NV12_128m) {
        format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;
    } else if (src_format == RGBA8888) {
        format = HAL_PIXEL_FORMAT_RGBA_8888;
    }
    return format;
}

bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size)
{
    int cret = 0;
    bool ret = false;
    C2DBuffReq bufferreq;
    if (c2dcc) {
        bufferreq.size = 0;
        pthread_mutex_lock(&c_lock);
        cret = c2dcc->getBuffReq(port,&bufferreq);
        pthread_mutex_unlock(&c_lock);
        DEBUG_PRINT_LOW("Status of getbuffer is %d", cret);
        ret = (cret)?false:true;
        buf_size = bufferreq.size;
    }
    return ret;
}

bool omx_video::is_conv_needed(int hal_fmt, int hal_flags)
{
    bool bRet = hal_fmt == HAL_PIXEL_FORMAT_RGBA_8888 &&
        !(hal_flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED);
#ifdef _HW_RGBA
    bRet = false;
#endif
    DEBUG_PRINT_LOW("RGBA conversion %s", bRet ? "Needed":"Not-Needed");
    return bRet;
}

OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
{
    unsigned nBufIndex = 0;
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    encoder_media_buffer_type *media_buffer;
    private_handle_t *handle = NULL;
    DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer);

    if (buffer == NULL) {
        DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer);
        return OMX_ErrorBadParameter;
    }
    nBufIndex = buffer - meta_buffer_hdr;
    if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
        DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u",
                nBufIndex);
        return OMX_ErrorBadParameter;
    }
    media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
    if ((!media_buffer || !media_buffer->meta_handle) &&
            !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
        DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
            media_buffer);
        m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
        return OMX_ErrorBadParameter;
    } else if (media_buffer) {
        handle = (private_handle_t *)media_buffer->meta_handle;
    }

    if (media_buffer && media_buffer->buffer_type ==
         kMetadataBufferTypeCameraSource) {
        return empty_this_buffer_proxy(hComp, buffer);
    }

    /*Enable following code once private handle color format is
      updated correctly*/

    if (buffer->nFilledLen > 0 && handle) {
        if (c2d_opened && handle->format != c2d_conv.get_src_format()) {
            c2d_conv.close();
            c2d_opened = false;
        }

        if (!c2d_opened) {
            mUsesColorConversion = is_conv_needed(handle->format, handle->flags);
            if (mUsesColorConversion) {
                DEBUG_PRINT_INFO("open Color conv forW: %u, H: %u",
                        (unsigned int)m_sInPortDef.format.video.nFrameWidth,
                        (unsigned int)m_sInPortDef.format.video.nFrameHeight);
                if (!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
                            m_sInPortDef.format.video.nFrameWidth,
                            RGBA8888, NV12_128m, handle->width)) {
                    m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
                    DEBUG_PRINT_ERROR("Color conv open failed");
                    return OMX_ErrorBadParameter;
                }
                c2d_opened = true;
#ifdef _MSM8974_
                if (!dev_set_format(NV12_128m))
                    DEBUG_PRINT_ERROR("cannot set color format");
#endif
            }
        }
    }
    if (input_flush_progress == true) {
        m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
        DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Input flush in progress");
        return OMX_ErrorNone;
    }

    if (!psource_frame) {
        psource_frame = buffer;
        ret = push_input_buffer(hComp);
    } else {
        if (!m_opq_meta_q.insert_entry((unsigned long)buffer,0,0)) {
            DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full");
            m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
            ret = OMX_ErrorBadParameter;
        }
    }
    return ret;
}

OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp,
        struct pmem &Input_pmem_info)
{

    OMX_ERRORTYPE ret = OMX_ErrorNone;
    unsigned long address = 0,p2,id;

    DEBUG_PRINT_LOW("In queue Meta Buffer");
    if (!psource_frame || !pdest_frame) {
        DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
        return OMX_ErrorBadParameter;
    }

    if (psource_frame->nFilledLen > 0) {
        if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
            DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
            post_event ((unsigned long)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
            ret = OMX_ErrorBadParameter;
        }
    }

    if (ret == OMX_ErrorNone)
        ret = empty_this_buffer_proxy(hComp,psource_frame);

    if (ret == OMX_ErrorNone) {
        psource_frame = NULL;
        if (!psource_frame && m_opq_meta_q.m_size) {
            m_opq_meta_q.pop_entry(&address,&p2,&id);
            psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
        }
    } else {
        // there has been an error and source frame has been scheduled for an EBD
        psource_frame = NULL;
    }
    return ret;
}

OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
        struct pmem &Input_pmem_info,unsigned long &index)
{

    unsigned char *uva;
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    unsigned long address = 0,p2,id;

    DEBUG_PRINT_LOW("In Convert and queue Meta Buffer");
    if (!psource_frame || !pdest_frame) {
        DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
        return OMX_ErrorBadParameter;
    }
    if (secure_session) {
        DEBUG_PRINT_ERROR("cannot convert buffer during secure session");
        return OMX_ErrorInvalidState;
    }

    if (!psource_frame->nFilledLen) {
        if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
            pdest_frame->nFilledLen = psource_frame->nFilledLen;
            pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
            pdest_frame->nFlags = psource_frame->nFlags;
            DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer "
                    "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen);
        } else {
            pdest_frame->nOffset = 0;
            pdest_frame->nFilledLen = 0;
            pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
            pdest_frame->nFlags = psource_frame->nFlags;
            DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
                    pdest_frame, (unsigned int)pdest_frame->nFilledLen);
        }
    } else {
        uva = (unsigned char *)mmap(NULL, Input_pmem_info.size,
                PROT_READ|PROT_WRITE,
                MAP_SHARED,Input_pmem_info.fd,0);
        if (uva == MAP_FAILED) {
            ret = OMX_ErrorBadParameter;
        } else {
            if (!c2d_conv.convert(Input_pmem_info.fd, uva, uva,
                        m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) {
                DEBUG_PRINT_ERROR("Color Conversion failed");
                ret = OMX_ErrorBadParameter;
            } else {
                unsigned int buf_size = 0;
                if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size))
                    ret = OMX_ErrorBadParameter;
                else {
                    pdest_frame->nOffset = 0;
                    pdest_frame->nFilledLen = buf_size;
                    pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
                    pdest_frame->nFlags = psource_frame->nFlags;
                    DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
                            pdest_frame, (unsigned int)pdest_frame->nFilledLen);
                }
            }
            munmap(uva,Input_pmem_info.size);
        }
    }
    if (dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
        DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
        post_event ((unsigned long)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
        ret = OMX_ErrorBadParameter;
    }
    if (ret == OMX_ErrorNone)
        ret = empty_this_buffer_proxy(hComp,pdest_frame);
    if (ret == OMX_ErrorNone) {
        m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
        psource_frame = NULL;
        pdest_frame = NULL;
        if (!psource_frame && m_opq_meta_q.m_size) {
            m_opq_meta_q.pop_entry(&address,&p2,&id);
            psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
        }
        if (!pdest_frame && m_opq_pmem_q.m_size) {
            m_opq_pmem_q.pop_entry(&address,&p2,&id);
            pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
            DEBUG_PRINT_LOW("pdest_frame pop address is %p",pdest_frame);
        }
    } else {
        // there has been an error and source frame has been scheduled for an EBD
        psource_frame = NULL;
    }
    return ret;
}

OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
{
    unsigned long address = 0,p2,id, index = 0;
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    DEBUG_PRINT_LOW("In push input buffer");
    if (!psource_frame && m_opq_meta_q.m_size) {
        m_opq_meta_q.pop_entry(&address,&p2,&id);
        psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
    }
    if (!pdest_frame && m_opq_pmem_q.m_size) {
        m_opq_pmem_q.pop_entry(&address,&p2,&id);
        pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
    }
    while (psource_frame != NULL && pdest_frame != NULL &&
            ret == OMX_ErrorNone) {
        struct pmem Input_pmem_info;
        encoder_media_buffer_type *media_buffer;
        index = pdest_frame - m_inp_mem_ptr;
        if (index >= m_sInPortDef.nBufferCountActual) {
            DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u",
                    (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual);
            return OMX_ErrorBadParameter;
        }

        //Meta-Buffer with empty filled-length can contain garbage handle
        //Some clients queue such buffers to signal EOS. Handle this case
        // separately by queueing an intermediate color-conversion buffer
        // and propagate the EOS.
        if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
            return push_empty_eos_buffer(hComp, psource_frame);
        }
        media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer;
        /*Will enable to verify camcorder in current TIPS can be removed*/
        if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
            Input_pmem_info.buffer = media_buffer;
            Input_pmem_info.fd = media_buffer->meta_handle->data[0];
            Input_pmem_info.offset = media_buffer->meta_handle->data[1];
            Input_pmem_info.size = media_buffer->meta_handle->data[2];
            DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
                    Input_pmem_info.offset,
                    Input_pmem_info.size);
            ret = queue_meta_buffer(hComp,Input_pmem_info);
        } else {
            private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
            Input_pmem_info.buffer = media_buffer;
            Input_pmem_info.fd = handle->fd;
            Input_pmem_info.offset = 0;
            Input_pmem_info.size = handle->size;
            m_graphicBufferSize = handle->size;
            if (is_conv_needed(handle->format, handle->flags))
                ret = convert_queue_buffer(hComp,Input_pmem_info,index);
            else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
                    handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
                    handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
                    handle->format == HAL_PIXEL_FORMAT_RGBA_8888 ||
                    handle->format == QOMX_COLOR_Format32bitRGBA8888Compressed)
                ret = queue_meta_buffer(hComp,Input_pmem_info);
            else
                ret = OMX_ErrorBadParameter;
        }
    }
    return ret;
}

OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp,
        OMX_BUFFERHEADERTYPE* buffer) {
    OMX_BUFFERHEADERTYPE* opqBuf = NULL;
    OMX_ERRORTYPE retVal = OMX_ErrorNone;
    unsigned index = 0;

    DEBUG_PRINT_LOW("In push empty eos buffer");
    do {
        if (mUsesColorConversion) {
            if (pdest_frame) {
                //[1] use a checked out conversion buffer, if one is available
                opqBuf = pdest_frame;
                pdest_frame = NULL;
            } else if (m_opq_pmem_q.m_size) {
                //[2] else pop out one from the queue, if available
                unsigned long address = 0, p2, id;
                m_opq_pmem_q.pop_entry(&address,&p2,&id);
                opqBuf = (OMX_BUFFERHEADERTYPE* ) address;
            }
            index = opqBuf - m_inp_mem_ptr;
        } else {
            opqBuf = (OMX_BUFFERHEADERTYPE* ) buffer;
            index = opqBuf - meta_buffer_hdr;
        }

        if (!opqBuf || index >= m_sInPortDef.nBufferCountActual) {
            DEBUG_PRINT_ERROR("push_empty_eos_buffer: Could not find a "
                    "color-conversion buffer to queue ! defer until available");
            //[3] else, returning back will defer calling this function again
            //until a conversion buffer is returned by the encoder and also
            //hold on to the client's buffer
            return OMX_ErrorNone;
        }
        struct pmem Input_pmem_info;
        Input_pmem_info.buffer = opqBuf;
        Input_pmem_info.fd = m_pInput_pmem[index].fd;
        Input_pmem_info.offset = 0;
        Input_pmem_info.size = m_pInput_pmem[index].size;

        if (dev_use_buf(&Input_pmem_info, PORT_INDEX_IN, 0) != true) {
            DEBUG_PRINT_ERROR("ERROR: in dev_use_buf for empty eos buffer");
            retVal = OMX_ErrorBadParameter;
            break;
        }

        //Queue with null pBuffer, as pBuffer in client's hdr can be junk
        //Clone the color-conversion buffer to avoid overwriting original buffer
        OMX_BUFFERHEADERTYPE emptyEosBufHdr;
        memcpy(&emptyEosBufHdr, opqBuf, sizeof(OMX_BUFFERHEADERTYPE));
        emptyEosBufHdr.nFilledLen = 0;
        emptyEosBufHdr.nTimeStamp = buffer->nTimeStamp;
        emptyEosBufHdr.nFlags = buffer->nFlags;
        emptyEosBufHdr.pBuffer = NULL;
        if (!mUsesColorConversion && !mUseProxyColorFormat)
            emptyEosBufHdr.nAllocLen = m_sInPortDef.nBufferSize;
        else if (mUseProxyColorFormat)
            emptyEosBufHdr.nAllocLen = m_graphicBufferSize > 0 ? m_graphicBufferSize : m_sInPortDef.nBufferSize;
        if (dev_empty_buf(&emptyEosBufHdr, 0, index, m_pInput_pmem[index].fd) != true) {
            DEBUG_PRINT_ERROR("ERROR: in dev_empty_buf for empty eos buffer");
            dev_free_buf(&Input_pmem_info, PORT_INDEX_IN);
            retVal = OMX_ErrorBadParameter;
            break;
        }
        mEmptyEosBuffer = opqBuf;
    } while(false);

    //return client's buffer regardless since intermediate color-conversion
    //buffer is sent to the the encoder
    m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
    --pending_input_buffers;
    return retVal;
}
