/*--------------------------------------------------------------------------
Copyright (c) 2010-2012, Code Aurora Forum. 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 Code Aurora 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
//////////////////////////////////////////////////////////////////////////////

#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 IS_NOT_ALIGNED( num, to) (num & (to-1))
#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
#define SZ_2K (2048)

typedef struct OMXComponentCapabilityFlagsType
{
    ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
    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
#ifdef OUTPUT_BUFFER_LOG
extern FILE *outputBufferFile1;
#endif

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

  DEBUG_PRINT_LOW("omx_venc: message thread start\n");
  prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
  while(1)
  {
    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)) break;
#endif
  }
  DEBUG_PRINT_LOW("omx_venc: message thread stop\n");
  return 0;
}

void post_message(omx_video *omx, unsigned char id)
{
  DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id);
  write(omx->m_pipe_out, &id, 1);
}

// 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 p1, unsigned p2, unsigned 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\n");
  }
  return ret;
}

// omx cmd queue pop
bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *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(): m_state(OMX_StateInvalid),
                        m_app_data(NULL),
                        m_inp_mem_ptr(NULL),
                        m_out_mem_ptr(NULL),
                        m_pInput_pmem(NULL),
                        m_pOutput_pmem(NULL),
#ifdef USE_ION
                        m_pInput_ion(NULL),
                        m_pOutput_ion(NULL),
#endif
                        pending_input_buffers(0),
                        pending_output_buffers(0),
                        m_out_bm_count(0),
                        m_inp_bm_count(0),
                        m_flags(0),
                        m_event_port_settings_sent(false),
                        output_flush_progress (false),
                        input_flush_progress (false),
                        input_use_buffer (false),
                        output_use_buffer (false),
                        m_use_input_pmem(OMX_FALSE),
                        m_use_output_pmem(OMX_FALSE),
                        m_etb_count(0),
                        m_fbd_count(0),
                        m_error_propogated(false),
                        m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
                        psource_frame(NULL),
                        pdest_frame(NULL),
                        c2d_opened(false),
                        secure_session(false)
{
  DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()");
  memset(&m_cmp,0,sizeof(m_cmp));
  memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
  secure_color_format = (int) OMX_COLOR_FormatYUV420SemiPlanar;
  pthread_mutex_init(&m_lock, NULL);
  sem_init(&m_cmd_lock,0,0);
}


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

DESCRIPTION
  Destructor

PARAMETERS
  None

RETURN VALUE
  None.
========================================================================== */
omx_video::~omx_video()
{
  DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()");
  if(m_pipe_in) close(m_pipe_in);
  if(m_pipe_out) close(m_pipe_out);
  DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n");
  pthread_join(msg_thread_id,NULL);
  DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n");
  pthread_join(async_thread_id,NULL);
  pthread_mutex_destroy(&m_lock);
  sem_destroy(&m_cmd_lock);
  DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count,
      m_fbd_count);
  DEBUG_PRINT_HIGH("omx_video: Destructor exit\n");
  DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n");
}

/* ======================================================================
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 p1; // Parameter - 1
  unsigned p2; // Parameter - 2
  unsigned ident;
  unsigned qsize=0; // qsize
  omx_video *pThis = (omx_video *) ctxt;

  if(!pThis)
  {
    DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n");
    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 \n", 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("\nERROR: OMX_EventError: p2 = %d\n", p2);
            if(p2 == 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, NULL, NULL );

            }
            break;

          case OMX_CommandPortDisable:
            DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \
                        "state \n", 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 %d set PORT_STATE_ENABLED state\n" \
                        , p2);
            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
                                             OMX_EventCmdComplete, p1, p2, NULL );
            break;

          default:
            DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", 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\n");
        }
        break;
      case OMX_COMPONENT_GENERATE_ETB_OPQ:
        DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n");
        if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
                                          (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
        {
          DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
          pThis->omx_report_error ();
        }
        break;
      case OMX_COMPONENT_GENERATE_ETB:
        DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n");
        if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
                                          (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
        {
          DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
          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("\nERROR: FTBProxy() failed!\n");
          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("\nERROR: empty_buffer_done() failed!\n");
          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("\nERROR: fill_buffer_done() failed!\n");
          pThis->omx_report_error ();
        }
        break;

      case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:

        pThis->input_flush_progress = false;
        DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", 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("\n dev_stop called after input flush complete\n");
              if(dev_stop() != 0)
              {
                DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n");
                pThis->omx_report_error ();
              }
            }
          }
        }

        break;

      case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:

        pThis->output_flush_progress = false;
        DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", 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("\n dev_stop called after Output flush complete\n");
            if(!pThis->input_flush_progress)
            {
              if(dev_stop() != 0)
              {
                DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n");
                pThis->omx_report_error ();
              }
            }
          }
        }
        break;

      case OMX_COMPONENT_GENERATE_START_DONE:
        DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg");

        if(pThis->m_pCallbacks.EventHandler)
        {
          DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
          if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
          {
            DEBUG_PRINT_LOW("\n 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("\nERROR: dev_pause() failed in Start Done!\n");
              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_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
          }
        }
        else
        {
          DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
        }
        break;

      case OMX_COMPONENT_GENERATE_PAUSE_DONE:
        DEBUG_PRINT_LOW("\n 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\n");
            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("\n 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("\n 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_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
          }
        }

        break;

      case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
        DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n");
        pThis->omx_report_error ();
        break;

      default:
        DEBUG_PRINT_LOW("\n 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("\n exited the while loop\n");

}




/* ======================================================================
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
)
{
  if(m_state == OMX_StateInvalid)
  {
    DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n");
    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
                                      )
{
  if(m_state == OMX_StateInvalid)
  {
    DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
    return OMX_ErrorInvalidState;
  }

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

  post_event((unsigned)cmd,(unsigned)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
                                            )
{
  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\n");
        }
        else
        {
          DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n");
          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\n");
        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\n");
      }
      /* Requesting transition from Loaded to Executing */
      else if(eState == OMX_StateExecuting)
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n");
        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\n");
        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\n");
        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
        eRet = OMX_ErrorInvalidState;
      }
      else
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\
                          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\n");
          if(dev_stop() != 0)
          {
            DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded");
            eRet = OMX_ErrorHardware;
          }
        }
        else
        {
          DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n");
          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("\nERROR: dev_start() failed in SCP on Idle --> Exe\n");
          omx_report_error ();
          eRet = OMX_ErrorHardware;
        }
        else
        {
          BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
          DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
          bFlag = 0;
        }

	dev_start_done();
      }
      /* Requesting transition from Idle to Idle */
      else if(eState == OMX_StateIdle)
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n");
        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\n");
        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("\nERROR: dev_start() failed in SCP on Idle --> Pause\n");
          omx_report_error ();
          eRet = OMX_ErrorHardware;
        }
        else
        {
          BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
          DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n");
          bFlag = 0;
        }
      }
      /* Requesting transition from Idle to Invalid */
      else if(eState == OMX_StateInvalid)
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n");
        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
        eRet = OMX_ErrorInvalidState;
      }
      else
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",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("\n OMXCORE-SM: Executing --> Idle \n");
        //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;
	dev_stop_done();
      }
      /* Requesting transition from Executing to Paused */
      else if(eState == OMX_StatePause)
      {

        if(dev_pause())
        {
          DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n");
          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\n");
          bFlag = 0;
        }
      }
      /* Requesting transition from Executing to Loaded */
      else if(eState == OMX_StateLoaded)
      {
        DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n");
        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("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n");
        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("\nERROR: OMXCORE-SM: Executing --> Executing \n");
        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("\nERROR: OMXCORE-SM: Executing --> Invalid \n");
        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
        eRet = OMX_ErrorInvalidState;
      }
      else
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",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("\n Pause --> Executing \n");
        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\n");
          post_event (NULL, NULL, 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("\n Pause --> Idle \n");
        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("\nERROR: Pause --> loaded \n");
        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("\nERROR: Pause --> WaitForResources \n");
        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("\nERROR: Pause --> Pause \n");
        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("\nERROR: Pause --> Invalid \n");
        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
        eRet = OMX_ErrorInvalidState;
      }
      else
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",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\n");
      }
      /* Requesting transition from WaitForResources to WaitForResources */
      else if(eState == OMX_StateWaitForResources)
      {
        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n");
        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\n");
        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\n");
        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\n");
        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)\n",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\n");
      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\n");
        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\n");
        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)\n",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("\n execute_omx_flush -  %d\n", flushType);
  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();
  }
  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      p1 = 0; // Parameter - 1
  unsigned      p2 = 0; // Parameter - 2
  unsigned      ident = 0;
  bool bRet = true;

  /*Generate FBD for all Buffers in the FTBq*/
  DEBUG_PRINT_LOW("\n execute_output_flush\n");
  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("\nERROR: 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      p1 = 0; // Parameter - 1
  unsigned      p2 = 0; // Parameter - 2
  unsigned      ident = 0;
  bool bRet = true;

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

  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 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 int)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("\nERROR: i/p dev_flush() Failed");
    return false;
  }

  return bRet;
}


/* ======================================================================
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 int p1,
                           unsigned int p2,
                           unsigned int id)
{
  bool bRet      =                      false;


  pthread_mutex_lock(&m_lock);

  if( id == OMX_COMPONENT_GENERATE_FTB || \
      (id == OMX_COMPONENT_GENERATE_FRAME_DONE))
  {
    m_ftb_q.insert_entry(p1,p2,id);
  }
  else if((id == m_input_msg_id) \
          || (id == OMX_COMPONENT_GENERATE_EBD))
  {
    m_etb_q.insert_entry(p1,p2,id);
  }
  else
  {
    m_cmd_q.insert_entry(p1,p2,id);
  }

  bRet = true;
  DEBUG_PRINT_LOW("\n 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)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  unsigned int height=0,width = 0;

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

      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
      if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN)
      {
        DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d",
            m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin,
            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(secure_session) {
          portDefn->format.video.eColorFormat =
            (OMX_COLOR_FORMATTYPE)secure_color_format;
        }
        else if (mUseProxyColorFormat) {
            portDefn->format.video.eColorFormat =
              (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
        }
#endif
      }
      else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
                         &m_sOutPortDef.nBufferCountActual,
                         &m_sOutPortDef.nBufferSize,
                         m_sOutPortDef.nPortIndex);
        DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d",
            m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin,
            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:
    {
      OMX_PORT_PARAM_TYPE *portParamType =
      (OMX_PORT_PARAM_TYPE *) paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");

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

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

          if (index > 1) {
              eRet = OMX_ErrorNoMore;
          } else {
              memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
#ifdef _ANDROID_ICS_
              if (index == 1) {
                  //we support two formats
                  //index 0 - YUV420SP
                  //index 1 - opaque which internally maps to YUV420SP.
                  //this can be extended in the future
                  portFmt->nIndex = index; //restore index set from client
                  portFmt->eColorFormat =
                    (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
              }
          }
#endif
      }
      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:
    {
      OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n");

      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:
    {
      OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n");
      memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
      break;
    }
  case OMX_IndexParamVideoH263:
    {
      OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n");
      memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
      break;
    }
  case OMX_IndexParamVideoAvc:
    {
      OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n");
      memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
      break;
    }
  case OMX_IndexParamVideoProfileLevelQuerySupported:
    {
      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n");
      eRet = get_supported_profile_level(pParam);
      if(eRet)
        DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d",
                          pParam->eProfile, pParam->eLevel);
      break;
     }
  case OMX_IndexParamVideoProfileLevelCurrent:
    {
      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n");
      memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
      break;
    }
    /*Component should support this port definition*/
  case OMX_IndexParamAudioInit:
    {
      OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
      memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
      break;
    }
    /*Component should support this port definition*/
  case OMX_IndexParamImageInit:
    {
      OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
      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\n", paramIndex);
      eRet =OMX_ErrorUnsupportedIndex;
      break;
    }
  case OMX_IndexParamStandardComponentRole:
    {
      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\n",paramIndex);
      if(NULL != comp_role->cRole)
      {
        strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
      }
      else
      {
        DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex);
        eRet =OMX_ErrorBadParameter;
      }
      break;
    }
    /* Added for parameter test */
  case OMX_IndexParamPriorityMgmt:
    {

      OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
      memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
      break;
    }
    /* Added for parameter test */
  case OMX_IndexParamCompBufferSupplier:
    {
      OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
      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:
    {
      OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n");
      memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
      break;
    }

    case OMX_IndexParamVideoErrorCorrection:
    {
      OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
      DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n");
      errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
      errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
      errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
      break;
    }
  case OMX_IndexParamVideoIntraRefresh:
    {
      OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
      DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n");
      DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n");
      intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
      intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
      break;
    }
  case OMX_QcomIndexPortDefn:
    //TODO
    break;
  case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
   {
        OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
        DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n");
        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;
   }
#ifndef MAX_RES_720P
  case OMX_QcomIndexParamIndexExtraDataType:
    {
      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 & VEN_EXTRADATA_SLICEINFO) ? 1 : 0);
          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
      {
        DEBUG_PRINT_ERROR("get_parameter: unsupported index (%x), "
            "only slice information extradata is supported", pParam->nIndex);
        eRet =OMX_ErrorUnsupportedIndex;
      }
      break;
    }
#endif
  case QOMX_IndexParamVideoSyntaxHdr:
    {
       DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
       QOMX_EXTNINDEX_PARAMTYPE* pParam =
          reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData);
       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 *)&pParam->nDataSize))
       {
         DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %d)",
            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_IndexParamVideoSliceFMO:
  default:
    {
      DEBUG_PRINT_ERROR("ERROR: get_parameter: unknown param %08x\n", 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)
{
  ////////////////////////////////////////////////////////////////
  // 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(configIndex)
  {
  case OMX_IndexConfigVideoBitrate:
    {
      OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
      memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
      break;
    }
  case OMX_IndexConfigVideoFramerate:
    {
      OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
      memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
      break;
    }
  case OMX_IndexConfigCommonRotate:
    {
      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\n");
      QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
      memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
      break;
    }
  default:
    DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
    return OMX_ErrorUnsupportedIndex;
  }
  return OMX_ErrorNone;

}

/* ======================================================================
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)
{
  char *extns[] = {
    "OMX.QCOM.index.param.SliceDeliveryMode",
    "OMX.google.android.index.storeMetaDataInBuffers",
    "OMX.google.android.index.prependSPSPPSToIDRFrames",
    "OMX.google.android.index.setVUIStreamRestrictFlag"
  };

  if(m_state == OMX_StateInvalid)
  {
    DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n");
    return OMX_ErrorInvalidState;
  }
#ifdef MAX_RES_1080P
  if (!strncmp(paramName, extns[0], strlen(extns[0]))) {
    *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
    return OMX_ErrorNone;
  }
#endif
#ifdef _ANDROID_ICS_
  if (!strncmp(paramName, extns[1], strlen(extns[1]))) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
        return OMX_ErrorNone;
  } else if (!strncmp(paramName, extns[2], strlen(extns[2]))) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
        return OMX_ErrorNone;
  } else if (!strncmp(paramName, extns[3], strlen(extns[3]))) {
        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamEnableVUIStreamRestrictFlag;
        return OMX_ErrorNone;
  }
#endif
  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)
{
  *state = m_state;
  DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*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)
{
  DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n");
  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)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;

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

  DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer);
  if(bytes != m_sInPortDef.nBufferSize || secure_session)
  {
    DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! "
                      "bytes[%d] != Port.nBufferSize[%d]", bytes, 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("\nERROR: calloc() Failed for m_inp_mem_ptr");
      return OMX_ErrorInsufficientResources;
    }


    m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
    if(m_pInput_pmem == NULL)
    {
      DEBUG_PRINT_ERROR("\nERROR: 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("\nERROR: 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=NULL;
#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
      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);
      if(m_pInput_ion[i].ion_device_fd < 0) {
        DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /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 = (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("\nERROR: mmap() Failed");
        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:%d,offset:0x%x)", pParam->pmem_fd, 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("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
            pParam->pmem_fd, pParam->offset);
      }
      else
      {
        DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
        return OMX_ErrorBadParameter;
      }
    }

    DEBUG_PRINT_LOW("\nuse_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("\nERROR: dev_use_buf() Failed for i/p buf");
      return OMX_ErrorInsufficientResources;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("\nERROR: 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)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
  unsigned                         i= 0; // Temporary counter
  unsigned char *buf_addr = NULL;

  DEBUG_PRINT_HIGH("\n Inside use_output_buffer()");
  if(bytes != m_sOutPortDef.nBufferSize || secure_session)
  {
    DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! "
                      "bytes[%d] != Port.nBufferSize[%d]", bytes, 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(%d)\n",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("\nERROR: 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("\nERROR: 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("\nERROR: 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\n",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 =NULL;
#endif
      }
    }
    else
    {
      DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",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;
      BITMASK_SET(&m_out_bm_count,i);

      if(!m_use_output_pmem)
      {
#ifdef USE_ION
        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);
      if(m_pOutput_ion[i].ion_device_fd < 0) {
        DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /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 = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
                                                         MAP_SHARED,m_pOutput_pmem[i].fd,0);
        if(m_pOutput_pmem[i].buffer == MAP_FAILED)
        {
          DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
          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:0x%x )", pParam);

        if(pParam)
        {
          DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, 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("\n 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;
      }
    }
    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\n");
    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\n",(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 - ((!mUseProxyColorFormat)?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("\nERROR: dev_free_buf() Failed for i/p buf");
  }

  if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem)
  {
    if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false)
    {
      DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case");
      munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
      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("\n FreeBuffer:: i/p Heap UseBuffer case");
      if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
      {
        DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf");
      }
      munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
      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("\n 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("\n FreeBuffer:: o/p AllocateBuffer case");
      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 if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
      && m_use_output_pmem == OMX_FALSE))
    {
      DEBUG_PRINT_LOW("\n 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");
      }
      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("\n 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 %d",
                     bufferHdr,bytes);
    return OMX_ErrorBadParameter;
  }
  if(!m_inp_mem_ptr && !mUseProxyColorFormat)
    m_inp_mem_ptr = meta_buffer_hdr;
  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 = bytes;
  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 int)opaque_buffer_hdr[index],0,0);
    DEBUG_PRINT_HIGH("\n 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)
{

  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  unsigned   i = 0;

  DEBUG_PRINT_HIGH("\n allocate_input_buffer()::");
  if(bytes != m_sInPortDef.nBufferSize || secure_session)
  {
    DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n",
      bytes, m_sInPortDef.nBufferSize);
    return OMX_ErrorBadParameter;
  }

  if(!m_inp_mem_ptr)
  {
    DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
        m_sInPortDef.nBufferSize, 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("\nERROR: calloc() Failed for m_inp_mem_ptr");
      return OMX_ErrorInsufficientResources;
    }

    m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);

    if(m_pInput_pmem == NULL)
    {
      DEBUG_PRINT_ERROR("\nERROR: 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("\nERROR: 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=NULL;
#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;

#ifdef USE_ION
    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,0);
    if(m_pInput_ion[i].ion_device_fd < 0) {
      DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /dev/pmem_adsp open() Failed\n");
      return OMX_ErrorInsufficientResources;
    }
#endif
    m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
    m_pInput_pmem[i].offset = 0;

    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("\nERROR: mmap FAILED= %d\n", errno);
      close(m_pInput_pmem[i].fd);
#ifdef USE_ION
      free_ion_memory(&m_pInput_ion[i]);
#endif
      return OMX_ErrorInsufficientResources;
    }

    (*bufferHdr)->pBuffer           = (OMX_U8 *)m_pInput_pmem[i].buffer;
    DEBUG_PRINT_LOW("\n 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("\nERROR: dev_use_buf FAILED for i/p buf\n");
      return OMX_ErrorInsufficientResources;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call"
                      "for index [%d]\n", 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)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
  unsigned                         i= 0; // Temporary counter

  DEBUG_PRINT_HIGH("\n allocate_output_buffer()::");
  if(!m_out_mem_ptr)
  {
    int nBufHdrSize        = 0;
    DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
        m_sOutPortDef.nBufferSize, 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("\nERROR: 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("\nERROR: 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          = 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 =NULL;
#endif
      }
    }
    else
    {
      DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
      eRet = OMX_ErrorInsufficientResources;
    }
  }

  DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual);
  for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
  {
    if(BITMASK_ABSENT(&m_out_bm_count,i))
    {
      DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
      break;
    }
  }
  if(eRet == OMX_ErrorNone)
  {
    if(i < m_sOutPortDef.nBufferCountActual)
    {
#ifdef USE_ION
      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);
      if(m_pOutput_ion[i].ion_device_fd < 0) {
        DEBUG_PRINT_ERROR("\nERROR: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("\nERROR: /dev/pmem_adsp open() failed");
        return OMX_ErrorInsufficientResources;
      }
#endif
      m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
      m_pOutput_pmem[i].offset = 0;
      if(!secure_session) {
          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);
          if(m_pOutput_pmem[i].buffer == MAP_FAILED)
          {
              DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer");
              close (m_pOutput_pmem[i].fd);
#ifdef USE_ION
              free_ion_memory(&m_pOutput_ion[i]);
#endif
              return OMX_ErrorInsufficientResources;
          }
      }

      *bufferHdr = (m_out_mem_ptr + i );
      if(!secure_session)
        (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
      else {
        m_pOutput_pmem[i].buffer = (OMX_U8 *)(i + 12345);
        (*bufferHdr)->pBuffer = (OMX_U8 *)(i + 12345);
      }
      (*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("\nERROR: dev_use_buf FAILED for o/p buf");
        return OMX_ErrorInsufficientResources;
      }
    }
    else
    {
      DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call"
                        "for index [%d]\n", i);
    }
  }

  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("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port);
  if(m_state == OMX_StateInvalid)
  {
    DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n");
    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\n",(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\n",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)
{
  OMX_ERRORTYPE eRet = OMX_ErrorNone;
  unsigned int nPortIndex;

  DEBUG_PRINT_LOW("In for decoder free_buffer \n");

  if(m_state == OMX_StateIdle &&
     (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
  {
    DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
  }
  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 %d disabled\n", 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\n");
    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\n");
    post_event(OMX_EventError,
               OMX_ErrorPortUnpopulated,
               OMX_COMPONENT_GENERATE_EVENT);
  }

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

    DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n",
                    nPortIndex, m_sInPortDef.nBufferCountActual);
    if(nPortIndex < m_sInPortDef.nBufferCountActual)
    {
      // 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\n");
          free (m_inp_mem_ptr);
          m_inp_mem_ptr = NULL;
        }
        if(m_pInput_pmem)
        {
          DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n");
          free(m_pInput_pmem);
          m_pInput_pmem = NULL;
        }
#ifdef USE_ION
        if(m_pInput_ion)
        {
          DEBUG_PRINT_LOW("Freeing m_pInput_ion\n");
          free(m_pInput_ion);
          m_pInput_ion = NULL;
        }
#endif
      }
    }
    else
    {
      DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n");
      eRet = OMX_ErrorBadPortIndex;
    }

    if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
       && release_input_done())
    {
      DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
      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 %d, actual cnt %d \n",
                    nPortIndex, m_sOutPortDef.nBufferCountActual);
    if(nPortIndex < m_sOutPortDef.nBufferCountActual)
    {
      // 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\n");
          free (m_out_mem_ptr);
          m_out_mem_ptr = NULL;
        }
        if(m_pOutput_pmem)
        {
          DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n");
          free(m_pOutput_pmem);
          m_pOutput_pmem = NULL;
        }
#ifdef USE_ION
        if(m_pOutput_ion)
        {
          DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n");
          free(m_pOutput_ion);
          m_pOutput_ion = NULL;
        }
#endif
      }
    }
    else
    {
      DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n");
      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\n");

      DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
      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\n");
        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);
    }
  }

  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 ;

  DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer);
  if(m_state == OMX_StateInvalid)
  {
    DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n");
    return OMX_ErrorInvalidState;
  }

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

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

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

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

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

  m_etb_count++;
  DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
  post_event ((unsigned)hComp,(unsigned)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)
{
  OMX_U8 *pmem_data_buf = NULL;
  int push_cnt = 0;
  unsigned nBufIndex = 0,nBufIndex_meta = 0;
  OMX_ERRORTYPE ret = OMX_ErrorNone;

  DEBUG_PRINT_LOW("\n ETBProxy: buffer[%p]\n", buffer);

  if(buffer == NULL)
  {
    DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer);
    return OMX_ErrorBadParameter;
  }

  nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
  nBufIndex_meta = buffer - meta_buffer_hdr;
  if(nBufIndex >= m_sInPortDef.nBufferCountActual &&
     nBufIndex_meta >= m_sInPortDef.nBufferCountActual)
  {
    DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex);
    return OMX_ErrorBadParameter;
  }

  pending_input_buffers++;
  if(input_flush_progress == true)
  {
    post_event ((unsigned int)buffer,0,
                OMX_COMPONENT_GENERATE_EBD);
    DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress");
    return OMX_ErrorNone;
  }
#ifdef _ANDROID_ICS_
  if(meta_mode_enable && !mUseProxyColorFormat)
  {
    encoder_media_buffer_type *media_buffer;
    bool met_error = false;
    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 if((media_buffer->meta_handle->numFds != 1 &&
                   media_buffer->meta_handle->numInts != 2))
          {
            met_error = true;
          }
        }
      }
    } else {
      met_error = true;
    }
    if(met_error)
    {
      DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call");
      post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
      return OMX_ErrorBadParameter;
    }

    struct pmem Input_pmem_info;
    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);

    } else {
      private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
      if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
        DEBUG_PRINT_ERROR("\n Incorrect pixel format");
        post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
        return OMX_ErrorBadParameter;
      }
      Input_pmem_info.buffer = media_buffer;
      Input_pmem_info.fd = handle->fd;
      Input_pmem_info.offset = 0;
      Input_pmem_info.size = handle->size;
    }
    if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
      DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
      post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
      return OMX_ErrorBadParameter;
    }
  }
  else if(input_use_buffer && !m_use_input_pmem)
#else
  if(input_use_buffer && !m_use_input_pmem)
#endif
  {
    DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data");
    pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;

    memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
            buffer->nFilledLen);
    DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
  } else if (m_sInPortDef.format.video.eColorFormat ==
      OMX_COLOR_FormatYUV420SemiPlanar && !mUseProxyColorFormat) {
      //For the case where YUV420SP buffers are qeueued to component
      //by sources other than camera (Apps via MediaCodec), alignment
      //of chroma-plane to 2K is necessary.
      //For RGB buffers, color-conversion takes care of such alignment
      OMX_U32 width = m_sInPortDef.format.video.nFrameWidth;
      OMX_U32 height = m_sInPortDef.format.video.nFrameHeight;
      OMX_U32 chromaOffset = width * height;
      if (IS_NOT_ALIGNED(chromaOffset, SZ_2K)) {
          OMX_U32 chromaSize = (width * height)/2;
          chromaOffset = ALIGN(chromaOffset,SZ_2K);
          if (buffer->nAllocLen >= chromaOffset + chromaSize) {
              OMX_U8* buf = buffer->pBuffer;
              memmove(buf + chromaOffset, buf + (width*height), chromaSize);
          } else {
             DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
                 Insufficient bufferLen=%u v/s Required=%u",
                 (width*height), chromaOffset, buffer->nAllocLen,
                 chromaOffset+chromaSize);
          }
      }
  }
#ifdef _COPPER_
  if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,m_pInput_pmem[nBufIndex].fd) != true)
#else
  if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true)
#endif
  {
    DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed");
#ifdef _ANDROID_ICS_
    omx_release_meta_buffer(buffer);
#endif
    post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
    /*Generate an async error and move to invalid state*/
    pending_input_buffers--;
    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("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer);
  if(m_state == OMX_StateInvalid)
  {
    DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n");
    return OMX_ErrorInvalidState;
  }

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

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

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

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

  post_event((unsigned) hComp, (unsigned)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)
{
  OMX_U8 *pmem_data_buf = NULL;
  OMX_ERRORTYPE nRet = OMX_ErrorNone;

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

  if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) )
  {
    DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n");
    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("\n o/p port is Disabled or Flush in Progress");
    post_event ((unsigned int)bufferAdd,0,
                OMX_COMPONENT_GENERATE_FBD);
    return OMX_ErrorNone;
  }

  if(output_use_buffer && !m_use_output_pmem)
  {
    DEBUG_PRINT_LOW("\n 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("\nERROR: dev_fill_buf() Failed");
    post_event ((unsigned int)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)
{

  m_pCallbacks       = *callbacks;
  DEBUG_PRINT_LOW("\n 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)
{
  DEBUG_PRINT_ERROR("ERROR: use_EGL_image:  Not Implemented \n");
  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)
{
  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\n",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\n",role);
    }
    else
    {
      DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
      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\n",role);
    }
    else
    {
      DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
      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\n",role);
    }
    else
    {
      DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
      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\n",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\n",role);
    }
    else
    {
      DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
      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\n",role);
    }
    else
    {
      DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
      eRet = OMX_ErrorNoMore;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n");
    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()\n");
  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()\n");
  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()\n");
  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)
{
  DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %d",
     buffer->pBuffer, buffer->nFlags,buffer->nFilledLen);
  if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual))
  {
    return OMX_ErrorBadParameter;
  }

  pending_output_buffers--;
  if(!secure_session)
  {
    extra_data_handle.create_extra_data(buffer);
  }

  if (!secure_session && m_sDebugSliceinfo) {
    if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
       DEBUG_PRINT_HIGH("parsing extradata");
       extra_data_handle.parse_extra_data(buffer);
    }
  }
  /* For use buffer we need to copy the data */
  if(m_pCallbacks.FillBufferDone)
  {
    if(buffer->nFilledLen > 0)
    {
      m_fbd_count++;

#ifdef OUTPUT_BUFFER_LOG
      if(outputBufferFile1)
      {
        fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1);
      }
#endif
    }
    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;
  int buffer_index_meta = -1;

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

  pending_input_buffers--;

  if(mUseProxyColorFormat && (buffer_index < m_sInPortDef.nBufferCountActual)) {
    if(!pdest_frame) {
      pdest_frame = buffer;
      DEBUG_PRINT_LOW("\n empty_buffer_done pdest_frame address is %p",pdest_frame);
      return push_input_buffer(hComp);

    } else {
      DEBUG_PRINT_LOW("\n empty_buffer_done insert address is %p",buffer);
      if (!m_opq_pmem_q.insert_entry((unsigned int)buffer, 0, 0)) {
        DEBUG_PRINT_ERROR("\n empty_buffer_done: pmem queue is full");
        return OMX_ErrorBadParameter;
      }
    }
  } 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 p1;
  unsigned p2;
  unsigned 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("\nERROR: empty_buffer_done() failed!\n");
          omx_report_error ();
        }
        break;

      case OMX_COMPONENT_GENERATE_FBD:
        if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
        {
          DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
          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\n",
            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\n", 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\n", profileLevelType->nProfileIndex);
        eRet = OMX_ErrorNoMore;
      }
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
    eRet = OMX_ErrorBadPortIndex;
  }
  DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
                    profileLevelType->eProfile,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 (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;
      }
      else
      {
        DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
            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\n", 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\n", profileLevelType->nProfileIndex);
        eRet = OMX_ErrorNoMore;
      }
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
    eRet = OMX_ErrorBadPortIndex;
  }
  DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
                    profileLevelType->eProfile,profileLevelType->eLevel);
  return eRet;
}

#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("\nInvalid 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("\nERROR: ION Device open() Failed");
           return ion_device_fd;
        }
        alloc_data->len = size;
        alloc_data->align = 4096;
        alloc_data->flags = 0;
        if(!secure_session && (flag & ION_FLAG_CACHED))
        {
          alloc_data->flags = ION_FLAG_CACHED;
        }

        if (secure_session)
           alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE);
        else
           alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) |
                ION_HEAP(ION_IOMMU_HEAP_ID));

        rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
        if(rc || !alloc_data->handle) {
           DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
           alloc_data->handle =NULL;
           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("\n 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("\n 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("\n ION free failed ");
         return;
     }
     close(buf_ion_info->ion_device_fd);
     buf_ion_info->ion_alloc_data.handle = NULL;
     buf_ion_info->ion_device_fd = -1;
     buf_ion_info->fd_ion_data.fd = -1;
}
#endif
#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(mUseProxyColorFormat &&
       (index_pmem < m_sInPortDef.nBufferCountActual)) {
        if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){
          DEBUG_PRINT_ERROR("\n 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_2K;
}

bool omx_video::omx_c2d_conv::init() {
  bool status = true;
  if(mLibHandle || mConvertOpen || mConvertClose) {
    DEBUG_PRINT_ERROR("\n 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){
    DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert");
    return false;
  }
  result =  c2dcc->convertC2D(src_fd, src_base, src_viraddr,
                              dest_fd, dest_base, dest_viraddr);
  DEBUG_PRINT_LOW("\n 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)
{
  bool status = false;
  size_t srcStride = 0;
  if(!c2dcc) {
     c2dcc = mConvertOpen(width, height, width, height,
             src, dest, 0, srcStride);
     if(c2dcc) {
       src_format = src;
       status = true;
     } else
       DEBUG_PRINT_ERROR("\n mConvertOpen failed");
  }
   return status;
}
void omx_video::omx_c2d_conv::close()
{
  if(mLibHandle) {
    if(mConvertClose && c2dcc)
     mConvertClose(c2dcc);
    c2dcc = NULL;
  }
}
omx_video::omx_c2d_conv::~omx_c2d_conv()
{
  DEBUG_PRINT_ERROR("\n Destroy C2D instance");
  if(mLibHandle) {
    if(mConvertClose && c2dcc)
      mConvertClose(c2dcc);
    dlclose(mLibHandle);
  }
  c2dcc = NULL;
  mLibHandle = NULL;
  mConvertOpen = NULL;
  mConvertClose = NULL;
}
int omx_video::omx_c2d_conv::get_src_format()
{
  int format = -1;
  if(src_format == NV12_2K) {
    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;
    cret = c2dcc->getBuffReq(port,&bufferreq);
    DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret);
    ret = (cret)?false:true;
    buf_size = bufferreq.size;
  }
  return ret;
}
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;
  DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer);

  if(buffer == NULL) {
    DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer);
    return OMX_ErrorBadParameter;
  }
  nBufIndex = buffer - meta_buffer_hdr;
  if(nBufIndex >= m_sInPortDef.nBufferCountActual) {
    DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n",
                      nBufIndex);
    return OMX_ErrorBadParameter;
  }
  media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
  private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
  /*Enable following code once private handle color format is
    updated correctly*/

  if(buffer->nFilledLen > 0) {
    if(c2d_opened && handle->format != c2d_conv.get_src_format()) {
      c2d_conv.close();
      c2d_opened = false;
    }
    if (!c2d_opened) {
        if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
          DEBUG_PRINT_ERROR("\n open Color conv for RGBA888");
          if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
               m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_2K)){
             m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
             DEBUG_PRINT_ERROR("\n Color conv open failed");
             return OMX_ErrorBadParameter;
          }
          c2d_opened = true;
        } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
          DEBUG_PRINT_ERROR("\n Incorrect color format");
          m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
          return OMX_ErrorBadParameter;
        }
    }
  }

  if(input_flush_progress == true)
  {
    m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
    DEBUG_PRINT_ERROR("\nERROR: 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)buffer,0,0)) {
      DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full");
      ret = OMX_ErrorBadParameter;
    }
  }
  if(ret != OMX_ErrorNone) {
    m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
    DEBUG_PRINT_LOW("\nERROR: ETBOpaque failed:");
  }
  return ret;
}
OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp,
     struct pmem &Input_pmem_info) {

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

  DEBUG_PRINT_LOW("\n In queue Meta Buffer");
  if(!psource_frame || !pdest_frame) {
    DEBUG_PRINT_ERROR("\n 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("\nERROR: in dev_use_buf");
     post_event ((unsigned int)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;
    }
  }
  return ret;
}

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

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

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

  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("\n Skipping color conversion for empty EOS \
          Buffer header=%p filled-len=%d", pdest_frame,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("\n Buffer header %p Filled len size %d",
           pdest_frame,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("\n 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;
            if(!buf_size || buf_size > pdest_frame->nAllocLen) {
              DEBUG_PRINT_ERROR("\n convert_queue_buffer buffer"
               "size mismatch buf size %d alloc size %d",
                      buf_size, pdest_frame->nAllocLen);
              ret = OMX_ErrorBadParameter;
              buf_size = 0;
            }
            pdest_frame->nFilledLen = buf_size;
            pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
            pdest_frame->nFlags = psource_frame->nFlags;
            DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
               pdest_frame,pdest_frame->nFilledLen);
           }
         }
         munmap(uva,Input_pmem_info.size);
      }
    }
    if((ret == OMX_ErrorNone) &&
       dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
      DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
      post_event ((unsigned int)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("\n pdest_frame pop address is %p",pdest_frame);
      }
    }
    return ret;
}

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

  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("\n Output buffer index is wrong %d act count %d",
                         index,m_sInPortDef.nBufferCountActual);
       return OMX_ErrorBadParameter;
    }
    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 if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS & mUseProxyColorFormat) {
       ret = convert_queue_buffer(hComp,Input_pmem_info,index);
    } 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;
      if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
        ret = convert_queue_buffer(hComp,Input_pmem_info,index);
      else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
        ret = queue_meta_buffer(hComp,Input_pmem_info);
      else
        ret = OMX_ErrorBadParameter;
    }
   }
  return ret;
}
