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

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

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
#include<string.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include<unistd.h>
#include <fcntl.h>
#include "video_encoder_device.h"
#include "omx_video_encoder.h"
#include <linux/android_pmem.h>
#ifdef USE_ION
#include <linux/msm_ion.h>
#endif

#define MPEG4_SP_START 0
#define MPEG4_ASP_START (MPEG4_SP_START + 8)
#define MPEG4_720P_LEVEL 6
#define H263_BP_START 0
#define H264_BP_START 0
#define H264_HP_START (H264_BP_START + 13)
#define H264_MP_START (H264_BP_START + 26)

/* MPEG4 profile and level table*/
static const unsigned int mpeg4_profile_level_table[][5]=
{
    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
    {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
    {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
    {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
    {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
    {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
    {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
    {0,0,0,0,0},

    {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
    {0,0,0,0,0},
};

/* H264 profile and level table*/
static const unsigned int h264_profile_level_table[][5]=
{
     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
    {0,0,0,0,0},

    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
    {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
    {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
    {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
    {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
    {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
    {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
    {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
    {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
    {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
    {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
    {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
    {0,0,0,0,0},

    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
    {0,0,0,0,0}

};

/* H263 profile and level table*/
static const unsigned int h263_profile_level_table[][5]=
{
    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
    {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
    {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
    {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
    {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
    {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
    {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
    {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    {0,0,0,0,0}
};

#define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }

#ifdef INPUT_BUFFER_LOG
FILE *inputBufferFile1;
char inputfilename [] = "/data/input.yuv";
#endif
#ifdef OUTPUT_BUFFER_LOG
FILE *outputBufferFile1;
char outputfilename [] = "/data/output-bitstream.\0\0\0\0";
#endif
//constructor
venc_dev::venc_dev(class omx_venc *venc_class)
{
  m_max_allowed_bitrate_check = false;
  m_eLevel = 0;
  m_eProfile = 0;
  pthread_mutex_init(&loaded_start_stop_mlock, NULL);
  pthread_cond_init (&loaded_start_stop_cond, NULL);
  DEBUG_PRINT_LOW("venc_dev constructor");
}

venc_dev::~venc_dev()
{
  pthread_cond_destroy(&loaded_start_stop_cond);
  pthread_mutex_destroy(&loaded_start_stop_mlock);
  DEBUG_PRINT_LOW("venc_dev distructor");
}

void* async_venc_message_thread (void *input)
{
  struct venc_ioctl_msg ioctl_msg ={NULL,NULL};
  struct venc_timeout timeout;
  struct venc_msg venc_msg;
  int error_code = 0;
  omx_venc *omx = reinterpret_cast<omx_venc*>(input);

  prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
  timeout.millisec = VEN_TIMEOUT_INFINITE;
  while(1)
  {
    ioctl_msg.in = NULL;
    ioctl_msg.out = (void*)&venc_msg;

    /*Wait for a message from the video decoder driver*/
    error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg);
    if (error_code == -512)  // ERESTARTSYS
    {
        DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!");
    }
    else if (error_code <0)
    {
        DEBUG_PRINT_LOW("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed");
        break;
    }
    else if(omx->async_message_process(input,&venc_msg) < 0)
    {
        DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
        break;
    }
  }
  DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n");
  return NULL;
}

bool venc_dev::venc_open(OMX_U32 codec)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
  int r;
  unsigned int   alignment = 0,buffer_size = 0, temp =0;

  m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
  if(m_nDriver_fd == 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n");
    m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
  }

  if((int)m_nDriver_fd < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n");
    return false;
  }

  DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd);
#ifdef SINGLE_ENCODER_INSTANCE
  OMX_U32 num_instances = 0;
  ioctl_msg.in = NULL;
  ioctl_msg.out = &num_instances;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < 0 )
  {
    DEBUG_PRINT_ERROR("\nERROR: Request number of encoder instances failed");
  }
  else if (num_instances > 1)
  {
    DEBUG_PRINT_ERROR("\nSecond encoder instance rejected!");
    venc_close();
    return false;
  }
#endif
  // set the basic configuration of the video encoder driver
  m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
  m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
  m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
  m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
  m_sVenc_cfg.fps_num = 30;
  m_sVenc_cfg.fps_den = 1;
  m_sVenc_cfg.targetbitrate = 64000;
#ifdef MAX_RES_1080P
  m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
#else
  m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12;
#endif
// initializing QP range parameters
  qp_range.minqp = 2;
  if(codec == OMX_VIDEO_CodingAVC)
    qp_range.maxqp = 51;
  else
    qp_range.maxqp = 31;

  if(codec == OMX_VIDEO_CodingMPEG4)
  {
    m_sVenc_cfg.codectype = VEN_CODEC_MPEG4;
    codec_profile.profile = VEN_PROFILE_MPEG4_SP;
    profile_level.level = VEN_LEVEL_MPEG4_2;
#ifdef OUTPUT_BUFFER_LOG
    strcat(outputfilename, "m4v");
#endif
  }
  else if(codec == OMX_VIDEO_CodingH263)
  {
    m_sVenc_cfg.codectype = VEN_CODEC_H263;
    codec_profile.profile = VEN_PROFILE_H263_BASELINE;
    profile_level.level = VEN_LEVEL_H263_20;
#ifdef OUTPUT_BUFFER_LOG
    strcat(outputfilename, "263");
#endif
  }
  if(codec == OMX_VIDEO_CodingAVC)
  {
    m_sVenc_cfg.codectype = VEN_CODEC_H264;
    codec_profile.profile = VEN_PROFILE_H264_BASELINE;
    profile_level.level = VEN_LEVEL_H264_1p1;
#ifdef OUTPUT_BUFFER_LOG
    strcat(outputfilename, "264");
#endif
  }
  ioctl_msg.in = (void*)&m_sVenc_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 )
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed");
    return false;
  }
#ifdef INPUT_BUFFER_LOG
  inputBufferFile1 = fopen (inputfilename, "ab");
#endif
#ifdef OUTPUT_BUFFER_LOG
  outputBufferFile1 = fopen (outputfilename, "ab");
#endif
  // Get the I/P and O/P buffer requirements
  ioctl_msg.in = NULL;
  ioctl_msg.out = (void*)&m_sInput_buff_property;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
    return false;
  }
  ioctl_msg.in = NULL;
  ioctl_msg.out = (void*)&m_sOutput_buff_property;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
    return false;
  }

  m_profile_set = false;
  m_level_set = false;
  if(venc_set_profile_level(0, 0))
  {
    DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success",
        __func__);
  }
  recon_buffers_count = MAX_RECON_BUFFERS;
  ltrmode.ltr_mode = 0;
  ltrcount.ltr_count = 0;
  ltrperiod.ltr_period = 0;

  return true;
}

void venc_dev::venc_close()
{
  DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd);
  if((int)m_nDriver_fd >= 0)
  {
    DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
    (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
        NULL);
    DEBUG_PRINT_LOW("\nCalling close()\n");
    close(m_nDriver_fd);
    m_nDriver_fd = -1;
  }
#ifdef INPUT_BUFFER_LOG
  fclose (inputBufferFile1);
#endif
#ifdef OUTPUT_BUFFER_LOG
  fclose (outputBufferFile1);
#endif
}

bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
                                unsigned long *actual_buff_count,
                                unsigned long *buff_size,
                                unsigned long port)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
  unsigned long temp_count = 0;

  if(port == 0)
  {
    if(*actual_buff_count > m_sInput_buff_property.mincount)
    {
      temp_count = m_sInput_buff_property.actualcount;
      m_sInput_buff_property.actualcount = *actual_buff_count;
      ioctl_msg.in = (void*)&m_sInput_buff_property;
      ioctl_msg.out = NULL;
      if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
      {
        DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed");
        m_sInput_buff_property.actualcount = temp_count;
        return false;
      }
      DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count);
    }
  }
  else
  {
    if(*actual_buff_count > m_sOutput_buff_property.mincount)
    {
	  temp_count = m_sOutput_buff_property.actualcount;
      m_sOutput_buff_property.actualcount = *actual_buff_count;
      ioctl_msg.in = (void*)&m_sOutput_buff_property;
      ioctl_msg.out = NULL;
      if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
      {
        DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed");
		m_sOutput_buff_property.actualcount = temp_count;
        return false;
      }
      DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count);
    }
  }

  return true;

}

bool venc_dev::venc_loaded_start()
{
  struct timespec ts;
  int status = 0;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed");
    return false;
  }
  if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
  {
    DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
    return false;
  }
  ts.tv_sec += 1;
  pthread_mutex_lock(&loaded_start_stop_mlock);
  DEBUG_PRINT_LOW("%s: wait on start done", __func__);
  status = pthread_cond_timedwait(&loaded_start_stop_cond,
                &loaded_start_stop_mlock, &ts);
  if (status != 0)
  {
    DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
        status, strerror(status));
    pthread_mutex_unlock(&loaded_start_stop_mlock);
    return false;
  }
  DEBUG_PRINT_LOW("%s: wait over on start done", __func__);
  pthread_mutex_unlock(&loaded_start_stop_mlock);
  DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__);
  return true;
}

bool venc_dev::venc_loaded_stop()
{
  struct timespec ts;
  int status = 0;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed");
    return false;
  }
  if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
  {
    DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
    return false;
  }
  ts.tv_sec += 1;
  pthread_mutex_lock(&loaded_start_stop_mlock);
  DEBUG_PRINT_LOW("%s: wait on stop done", __func__);
  status = pthread_cond_timedwait(&loaded_start_stop_cond,
                &loaded_start_stop_mlock, &ts);
  if (status != 0)
  {
    DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
        status, strerror(status));
    pthread_mutex_unlock(&loaded_start_stop_mlock);
    return false;
  }
  DEBUG_PRINT_LOW("%s: wait over on stop done", __func__);
  pthread_mutex_unlock(&loaded_start_stop_mlock);
  DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__);
  return true;
}

bool venc_dev::venc_loaded_start_done()
{
  pthread_mutex_lock(&loaded_start_stop_mlock);
  DEBUG_PRINT_LOW("%s: signal start done", __func__);
  pthread_cond_signal(&loaded_start_stop_cond);
  pthread_mutex_unlock(&loaded_start_stop_mlock);
  return true;
}

bool venc_dev::venc_loaded_stop_done()
{
  pthread_mutex_lock(&loaded_start_stop_mlock);
  DEBUG_PRINT_LOW("%s: signal stop done", __func__);
  pthread_cond_signal(&loaded_start_stop_cond);
  pthread_mutex_unlock(&loaded_start_stop_mlock);
  return true;
}

bool venc_dev::venc_get_seq_hdr(void *buffer,
    unsigned buffer_size, unsigned *header_len)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
  int i = 0;
  DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr");
  venc_seqheader seq_in, seq_out;
  seq_in.hdrlen = 0;
  seq_in.bufsize = buffer_size;
  seq_in.hdrbufptr = (unsigned char*)buffer;
  if (seq_in.hdrbufptr == NULL) {
    DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed");
    return false;
  }
  DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr,
    seq_in.bufsize, seq_in.hdrlen);

  ioctl_msg.in = (void*)&seq_in;
  ioctl_msg.out = (void*)&seq_out;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed");
    return false;
  }
  if (seq_out.hdrlen == 0) {
    DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header");
    DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
      seq_out.bufsize, seq_out.hdrlen);
    return false;
  }
  *header_len = seq_out.hdrlen;
  DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
    seq_out.bufsize, seq_out.hdrlen);

  return true;
}

bool venc_dev::venc_get_capability_ltrcount(unsigned long *min,
    unsigned long *max, unsigned long *step_size)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
  venc_range  cap_ltr_count;
  ioctl_msg.in = NULL;
  ioctl_msg.out = (void*)&cap_ltr_count;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_CAPABILITY_LTRCOUNT,
            (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Get LTR Capability failed");
    return false;
  }
  else
  {
    *min = cap_ltr_count.min;
    *max = cap_ltr_count.max;
    *step_size = cap_ltr_count.step_size;
    DEBUG_PRINT_HIGH("LTR Capability: min=%x, max=%d, step_size=%d",
      *min, *max, *step_size);
  }
  return true;
}

bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
                                unsigned long *actual_buff_count,
                                unsigned long *buff_size,
                                unsigned long port)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};

  if(port == 0)
  {
    ioctl_msg.in = NULL;
    ioctl_msg.out = (void*)&m_sInput_buff_property;
    if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
      return false;
    }
    *min_buff_count = m_sInput_buff_property.mincount;
    *actual_buff_count = m_sInput_buff_property.actualcount;
#ifdef USE_ION
    // For ION memory allocations of the allocated buffer size
    // must be 4k aligned, hence aligning the input buffer
    // size to 4k.
    m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095)
                                       & (~4095);
#endif
    *buff_size = m_sInput_buff_property.datasize;
  }
  else
  {
    ioctl_msg.in = NULL;
    ioctl_msg.out = (void*)&m_sOutput_buff_property;
    if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
      return false;
    }
    *min_buff_count = m_sOutput_buff_property.mincount;
    *actual_buff_count = m_sOutput_buff_property.actualcount;
    *buff_size = m_sOutput_buff_property.datasize;
  }

  return true;

}

bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n");
  switch(index)
  {
  case OMX_IndexParamPortDefinition:
    {
      OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
      portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
      DEBUG_PRINT_HIGH("venc_set_param: OMX_IndexParamPortDefinition");
      if(portDefn->nPortIndex == PORT_INDEX_IN)
      {

        if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0))
        {
          return false;
        }

        if(!venc_set_color_format(portDefn->format.video.eColorFormat))
        {
          return false;
        }

        DEBUG_PRINT_LOW("Basic parameter has changed");
        m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
        m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;

        ioctl_msg.in = (void*)&m_sVenc_cfg;
        ioctl_msg.out = NULL;
        if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
            DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed");
            return false;
        }
        DEBUG_PRINT_HIGH("WxH (%dx%d), codec (%d), fps(nr/dr) (%d/%d), bitrate (%d), "
            "color_format (%d)", m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
            m_sVenc_cfg.codectype, m_sVenc_cfg.fps_num, m_sVenc_cfg.fps_den,
            m_sVenc_cfg.targetbitrate, m_sVenc_cfg.inputformat);

        DEBUG_PRINT_LOW("Updating the buffer count/size for the new resolution");
        ioctl_msg.in = NULL;
        ioctl_msg.out = (void*)&m_sInput_buff_property;
        if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
            DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed");
            return false;
        }
        DEBUG_PRINT_HIGH("Got updated m_sInput_buff_property values: "
                        "datasize = %u, maxcount = %u, actualcnt = %u, "
                        "mincount = %u", m_sInput_buff_property.datasize,
                        m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount,
                        m_sInput_buff_property.mincount);

        ioctl_msg.in = NULL;
        ioctl_msg.out = (void*)&m_sOutput_buff_property;
        if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
            DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed");
            return false;
        }

        DEBUG_PRINT_HIGH("Got updated m_sOutput_buff_property values: "
                        "datasize = %u, maxcount = %u, actualcnt = %u, "
                        "mincount = %u", m_sOutput_buff_property.datasize,
                        m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount,
                        m_sOutput_buff_property.mincount);
        ioctl_msg.in = (void*)&m_sOutput_buff_property;
        ioctl_msg.out = NULL;

        if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
            DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed");
            return false;
        }

        if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
           (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) {
            m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
            ioctl_msg.in = (void*)&m_sInput_buff_property;
            ioctl_msg.out = NULL;
            if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
              DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed");
              return false;
            }
        }
        if(m_sInput_buff_property.datasize != portDefn->nBufferSize) {
            DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u],"
                              "Driver's updated i/p bufsize = %u", portDefn->nBufferSize,
                              m_sInput_buff_property.datasize);
        }
        m_level_set = false;
        if(venc_set_profile_level(0, 0)) {
          DEBUG_PRINT_LOW("%s(): Profile/Level setting success", __func__);
        }
      }
      else if(portDefn->nPortIndex == PORT_INDEX_OUT)
      {
        if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0))
        {
          return false;
        }

        if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
            &&
            (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual)
            &&
            (m_sOutput_buff_property.datasize == portDefn->nBufferSize)
          )
        {
          m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
          ioctl_msg.in = (void*)&m_sOutput_buff_property;
          ioctl_msg.out = NULL;
          if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
          {
            DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
            return false;
          }
        }
        else
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
      }
      break;
    }
  case OMX_IndexParamVideoPortFormat:
    {
      OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
      portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
      DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n");

      if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
      {
        if(!venc_set_color_format(portFmt->eColorFormat))
        {
          return false;
        }
      }
      else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(!venc_set_encode_framerate(portFmt->xFramerate, 0))
        {
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
      }
      break;
    }
  case OMX_IndexParamVideoBitrate:
    {
      OMX_VIDEO_PARAM_BITRATETYPE* pParam;
      pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
      DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n");

      if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0))
        {
          DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed");
          return false;
        }
        if(!venc_set_ratectrl_cfg(pParam->eControlRate))
        {
          DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
      }
      break;
    }
  case OMX_IndexParamVideoMpeg4:
    {
      OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
      OMX_U32 bFrames = 0;

      pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
      DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n");
      if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(!venc_set_voptiming_cfg(pParam->nTimeIncRes))
        {
          DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed");
          return false;
        }
        m_profile_set = false;
        m_level_set = false;
        if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
        {
          DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
          return false;
        }
#ifdef MAX_RES_1080P
        else {
          if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
          {
            if(pParam->nBFrames)
            {
              DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
              bFrames = 1;
            }
          }
        else
          {
            if(pParam->nBFrames)
            {
              DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
              bFrames = 0;
            }
          }
        }
#endif
        if(!venc_set_intra_period (pParam->nPFrames,bFrames))
        {
          DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
          return false;
        }
        if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing))
        {
          DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
      }
      break;
    }
  case OMX_IndexParamVideoH263:
    {
      OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
      DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n");
      OMX_U32 bFrames = 0;
      if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        m_profile_set = false;
        m_level_set = false;
        if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
        {
          DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
          return false;
        }
        if (pParam->nBFrames)
          DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263");

        if(venc_set_intra_period (pParam->nPFrames, bFrames) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263");
      }
      break;
    }
  case OMX_IndexParamVideoAvc:
    {
      DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n");
      OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
      OMX_U32 bFrames = 0;

      if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n",
            pParam->eProfile,pParam->eLevel);

        m_profile_set = false;
        m_level_set = false;

        if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel))
        {
          DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d",
                            pParam->eProfile, pParam->eLevel);
          return false;
        }
#ifdef MAX_RES_1080P
        else {
          if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline)
          {
            if(pParam->nBFrames)
            {
              DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
              bFrames = 1;
            }
          }
        else
          {
            if(pParam->nBFrames)
            {
              DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
              bFrames = 0;
            }
          }
        }
#endif
        if(!venc_set_intra_period (pParam->nPFrames, bFrames))
        {
          DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
          return false;
        }
        if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc))
        {
          DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed");
          return false;
        }
        if(!venc_set_inloop_filter (pParam->eLoopFilterMode))
        {
          DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed");
          return false;
        }
        if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing))
        {
          DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
      }
      //TBD, lot of other variables to be updated, yet to decide
      break;
    }
  case OMX_IndexParamVideoIntraRefresh:
    {
      DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n");
      OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
        (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
      if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
      }
      break;
    }
  case OMX_IndexParamVideoErrorCorrection:
    {
      DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n");
      OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
        (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
      if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(venc_set_error_resilience(error_resilience) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
      }
      break;
    }
  case OMX_IndexParamVideoProfileLevelCurrent:
    {
      DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n");
      OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
      (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
      if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        m_profile_set = false;
        m_level_set = false;
        if(!venc_set_profile_level (profile_level->eProfile,
                                   profile_level->eLevel))
        {
          DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
      }
      break;
    }
  case OMX_IndexParamVideoQuantization:
    {
      DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n");
      OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
        (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
      if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(venc_set_session_qp (session_qp->nQpI,
                                session_qp->nQpP) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
      }
      break;
    }

  case OMX_QcomIndexParamVideoQPRange:
    {
      DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange\n");
      OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range =
        (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
      if(qp_range->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(venc_set_qp_range (qp_range->minQP,
                                qp_range->maxQP) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting QP Range failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
      }
      break;
    }

  case OMX_ExtraDataVideoEncoderSliceInfo:
    {
      DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
      OMX_U32 extra_data = *(OMX_U32 *)paramData;
      if(venc_set_extradata(extra_data) == false)
      {
         DEBUG_PRINT_ERROR("ERROR: Setting "
            "OMX_ExtraDataVideoEncoderSliceInfo failed");
         return false;
      }
      break;
    }
  case OMX_ExtraDataVideoLTRInfo:
    {
      DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoLTRInfo");
      OMX_U32 extra_data = *(OMX_U32 *)paramData;
      if(venc_set_extradata(extra_data) == false)
      {
         DEBUG_PRINT_ERROR("ERROR: Setting "
            "OMX_ExtraDataVideoLTRInfo failed");
         return false;
      }
      break;
    }
  case OMX_QcomIndexEnableSliceDeliveryMode:
    {
       QOMX_EXTNINDEX_PARAMTYPE* pParam =
          (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
       if(pParam->nPortIndex == PORT_INDEX_OUT)
       {
         if(venc_set_slice_delivery_mode(pParam->bEnable) == false)
         {
           DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
           return OMX_ErrorUnsupportedSetting;
         }
       }
       else
       {
         DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
            "called on wrong port(%d)", pParam->nPortIndex);
         return OMX_ErrorBadPortIndex;
       }
       break;
    }
  case OMX_QcomIndexEnableH263PlusPType:
    {
       QOMX_EXTNINDEX_PARAMTYPE* pParam =
          (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
       DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType");
       if(pParam->nPortIndex == PORT_INDEX_OUT)
       {
         if(venc_set_plusptype(pParam->bEnable) == false)
         {
           DEBUG_PRINT_ERROR("Setting PlusPType failed for H263");
           return OMX_ErrorUnsupportedSetting;
         }
       }
       else
       {
         DEBUG_PRINT_ERROR("OMX_QcomIndexEnableH263PlusPType "
            "called on wrong port(%d)", pParam->nPortIndex);
         return OMX_ErrorBadPortIndex;
       }
       break;
    }
  case QOMX_IndexParamVideoLTRMode:
    {
      QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam =
          (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData;
      if(pParam->nPortIndex == PORT_INDEX_OUT)
      {
        if(!venc_set_ltrmode(pParam->eLTRMode))
        {
            DEBUG_PRINT_ERROR("Setting ltr mode failed");
            return OMX_ErrorUnsupportedSetting;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRMode "
            "called on wrong port(%d)", pParam->nPortIndex);
            return OMX_ErrorBadPortIndex;
      }
      break;
    }
  case QOMX_IndexParamVideoLTRCount:
    {
      QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
          (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
      if(pParam->nPortIndex == PORT_INDEX_OUT)
      {
        if(!venc_set_ltrcount(pParam->nCount))
        {
            DEBUG_PRINT_ERROR("Setting ltr count failed");
            return OMX_ErrorUnsupportedSetting;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRCount "
            "called on wrong port(%d)", pParam->nPortIndex);
            return OMX_ErrorBadPortIndex;
      }
      break;
    }
  case OMX_IndexParamVideoSliceFMO:
  default:
    DEBUG_PRINT_ERROR("venc_set_param: Unsupported index 0x%x", index);
    break;
  }

  return true;
}

bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  DEBUG_PRINT_LOW("\n Inside venc_set_config");

  switch(index)
  {
  case OMX_IndexConfigVideoBitrate:
    {
      OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
        configData;
      if(m_max_allowed_bitrate_check &&
         !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate))
      {
        DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed");
        return false;
      }
      DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate");
      if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
      {
        if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
      }
      break;
    }
  case OMX_IndexConfigVideoFramerate:
    {
      OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
        configData;
      DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate");
      if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
      {
        if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
      }
      break;
    }
  case QOMX_IndexConfigVideoIntraperiod:
    {
      DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n");
      QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
      (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
      if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
      {
        if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
          return false;
        }
      }
      break;
    }
  case OMX_IndexConfigVideoIntraVOPRefresh:
    {
      OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
        configData;
      DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
      if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
      {
        if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false)
        {
          DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
          return false;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
      }
      break;
    }
  case OMX_IndexConfigCommonRotate:
    {
      OMX_CONFIG_ROTATIONTYPE *config_rotation =
         reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
      venc_ioctl_msg ioctl_msg = {NULL,NULL};
      OMX_U32 nFrameWidth;

      DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims");
      nFrameWidth = m_sVenc_cfg.input_width;
      m_sVenc_cfg.input_width  = m_sVenc_cfg.input_height;
      m_sVenc_cfg.input_height = nFrameWidth;
      ioctl_msg.in = (void*)&m_sVenc_cfg;
      ioctl_msg.out = NULL;
      if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
          DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed");
          return false;
      }
      break;
    }
  case QOMX_IndexConfigVideoLTRPeriod:
    {
      QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam =
          (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData;
      if(pParam->nPortIndex == PORT_INDEX_OUT)
      {
        if(!venc_set_ltrperiod(pParam->nFrames))
        {
            DEBUG_PRINT_ERROR("Setting ltr period failed");
            return OMX_ErrorUnsupportedSetting;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRPeriod "
            "called on wrong port(%d)", pParam->nPortIndex);
            return OMX_ErrorBadPortIndex;
      }
      break;
    }
  case QOMX_IndexConfigVideoLTRUse:
    {
      QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam =
          (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
      if(pParam->nPortIndex == PORT_INDEX_OUT)
      {
        if(!venc_set_ltruse(pParam->nID, pParam->nFrames))
        {
            DEBUG_PRINT_ERROR("Setting ltr use failed");
            return OMX_ErrorUnsupportedSetting;
        }
      }
      else
      {
        DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRUse "
            "called on wrong port(%d)", pParam->nPortIndex);
            return OMX_ErrorBadPortIndex;
      }
      break;
    }
  default:
    DEBUG_PRINT_ERROR("venc_set_config: Unsupported index = 0x%x", index);
    break;
  }

  return true;
}

unsigned venc_dev::venc_stop( void)
{
#ifdef MAX_RES_1080P
    pmem_free();
#endif
  return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL);
}

unsigned venc_dev::venc_pause(void)
{
  return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL);
}

unsigned venc_dev::venc_resume(void)
{
  return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ;
}

unsigned venc_dev::venc_start_done(void)
{
  return 0;
}

unsigned venc_dev::venc_set_message_thread_id(pthread_t)
{
  return 0;
}

unsigned venc_dev::venc_start(void)
{
  DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start",
        __func__);
  if (!venc_set_profile_level(0, 0))
  {
    DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET",
      __func__);
  }
  else
  {
    DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET",
      __func__, codec_profile.profile, profile_level.level);
  }

  if(m_max_allowed_bitrate_check &&
     !venc_max_allowed_bitrate_check(bitrate.target_bitrate))
  {
    DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed");
    return -1;
  }

  venc_config_print();

#ifdef MAX_RES_1080P
  if((codec_profile.profile == VEN_PROFILE_MPEG4_SP) ||
     (codec_profile.profile == VEN_PROFILE_H264_BASELINE) ||
     (codec_profile.profile == VEN_PROFILE_H263_BASELINE))
    recon_buffers_count = MAX_RECON_BUFFERS - 2;
  else
    recon_buffers_count = MAX_RECON_BUFFERS;

  if (ltrmode.ltr_mode == (unsigned long)QOMX_VIDEO_LTRMode_Auto)
  {
    recon_buffers_count = MAX_RECON_BUFFERS;
    DEBUG_PRINT_HIGH("ltr mode enabled, so set recon buffers "
       "count to %d", recon_buffers_count);
  }

  if (!venc_allocate_recon_buffers())
    return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
  else
  {
    DEBUG_PRINT_ERROR("Failed in creating Recon buffers\n");
    return -1;
  }
#else
    return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
#endif
}

#ifdef MAX_RES_1080P
OMX_U32 venc_dev::venc_allocate_recon_buffers()
{
  OMX_U32 yuv_size;
  struct venc_ioctl_msg ioctl_msg;
  struct venc_recon_buff_size recon_buff_size;

  recon_buff_size.width =  ((m_sVenc_cfg.input_width + 15) / 16) * 16;
  recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16;

  DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d\n", m_sVenc_cfg.input_width,
                    m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height);

  ioctl_msg.in = NULL;
  ioctl_msg.out = (void*)&recon_buff_size;

  if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\n VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" ,
      recon_buff_size.width, recon_buff_size.height);
    return OMX_ErrorInsufficientResources;
  }

  DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d\n",
                   m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width,
                   recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment,
                   recon_buffers_count);

  for(int i = 0; i < recon_buffers_count; i++)
  {
    if(pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i))
    {
      DEBUG_PRINT_ERROR("Error returned in allocating recon buffers\n");
      return -1;
    }
  }
  return 0;
}
OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count)
{
  OMX_U32 pmem_fd = -1;
  OMX_U32 width, height;
  void *buf_addr = NULL;
  struct venc_ioctl_msg ioctl_msg;
  struct venc_recon_addr recon_addr;
  int rc = 0;

#ifdef USE_ION
  recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY);
  if(recon_buff[count].ion_device_fd < 0)
  {
      DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
      return -1;
  }

  recon_buff[count].alloc_data.len = size;
#ifdef MAX_RES_720P
  recon_buff[count].alloc_data.heap_mask = ION_HEAP(MEM_HEAP_ID);
#else
  recon_buff[count].alloc_data.heap_mask = (ION_HEAP(MEM_HEAP_ID) |
                                        ION_HEAP(ION_IOMMU_HEAP_ID));
#endif
  recon_buff[count].alloc_data.flags = ION_FLAG_CACHED;
  recon_buff[count].alloc_data.align = clip2(alignment);
  if (recon_buff[count].alloc_data.align != 8192)
    recon_buff[count].alloc_data.align = 8192;

  rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data);
  if(rc || !recon_buff[count].alloc_data.handle) {
         DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
         recon_buff[count].alloc_data.handle=NULL;
         return -1;
  }

  recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle;
  rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd);
  if(rc) {
        DEBUG_PRINT_ERROR("\n ION MAP failed ");
        recon_buff[count].ion_alloc_fd.fd =-1;
        recon_buff[count].ion_alloc_fd.fd =-1;
        return -1;
  }
  pmem_fd = recon_buff[count].ion_alloc_fd.fd;
#else
  struct pmem_allocation allocation;
  pmem_fd = open(MEM_DEVICE, O_RDWR);

  if ((int)(pmem_fd) < 0)
  {
	DEBUG_PRINT_ERROR("\n Failed to get an pmem handle");
	return -1;
  }

  allocation.size = size;
  allocation.align = clip2(alignment);

  if (allocation.align != 8192)
    allocation.align = 8192;

  if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
  {
    DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
      allocation.align, allocation.size);
    return -1;
  }
#endif
  buf_addr = mmap(NULL, size,
               PROT_READ | PROT_WRITE,
               MAP_SHARED, pmem_fd, 0);

  if (buf_addr == (void*) MAP_FAILED)
  {
    close(pmem_fd);
    pmem_fd = -1;
    DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr);
#ifdef USE_ION
    if(ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE,
       &recon_buff[count].alloc_data.handle)) {
      DEBUG_PRINT_LOW("ion recon buffer free failed");
    }
    recon_buff[count].alloc_data.handle = NULL;
    recon_buff[count].ion_alloc_fd.fd =-1;
    close(recon_buff[count].ion_device_fd);
    recon_buff[count].ion_device_fd =-1;
#endif
    return -1;
  }

  DEBUG_PRINT_HIGH("\n Allocated virt:%p, FD: %d of size %d \n", buf_addr, pmem_fd, size);

  recon_addr.buffer_size = size;
  recon_addr.pmem_fd = pmem_fd;
  recon_addr.offset = 0;
  recon_addr.pbuffer = (unsigned char *)buf_addr;

  ioctl_msg.in = (void*)&recon_addr;
  ioctl_msg.out = NULL;

  if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("Failed to set the Recon_buffers\n");
    return -1;
  }

  recon_buff[count].virtual_address = (unsigned char *) buf_addr;
  recon_buff[count].size = size;
  recon_buff[count].offset = 0;
  recon_buff[count].pmem_fd = pmem_fd;

  DEBUG_PRINT_ERROR("\n Allocated virt:%p, FD: %d of size %d at index: %d\n", recon_buff[count].virtual_address,
                     recon_buff[count].pmem_fd, recon_buff[count].size, count);
  return 0;
}

OMX_U32 venc_dev::pmem_free()
{
  int cnt = 0;
  struct venc_ioctl_msg ioctl_msg;
  struct venc_recon_addr recon_addr;
  for (cnt = 0; cnt < recon_buffers_count; cnt++)
  {
    if(recon_buff[cnt].pmem_fd)
    {
      recon_addr.pbuffer = recon_buff[cnt].virtual_address;
      recon_addr.offset = recon_buff[cnt].offset;
      recon_addr.pmem_fd = recon_buff[cnt].pmem_fd;
      recon_addr.buffer_size = recon_buff[cnt].size;
      ioctl_msg.in = (void*)&recon_addr;
      ioctl_msg.out = NULL;
      if(ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0)
        DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed");
      munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size);
      close(recon_buff[cnt].pmem_fd);
#ifdef USE_ION
      if(ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE,
         &recon_buff[cnt].alloc_data.handle)) {
        DEBUG_PRINT_LOW("ion recon buffer free failed");
      }
      recon_buff[cnt].alloc_data.handle = NULL;
      recon_buff[cnt].ion_alloc_fd.fd =-1;
      close(recon_buff[cnt].ion_device_fd);
      recon_buff[cnt].ion_device_fd =-1;
#endif
      DEBUG_PRINT_LOW("\n cleaning Index %d of size %d \n",cnt,recon_buff[cnt].size);
      recon_buff[cnt].pmem_fd = -1;
      recon_buff[cnt].virtual_address = NULL;
      recon_buff[cnt].offset = 0;
      recon_buff[cnt].alignment = 0;
      recon_buff[cnt].size = 0;
    }
  }
  return 0;
}
#endif

void venc_dev::venc_config_print()
{

  DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %d, Profile %d, level : %d",
                   m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);

  DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %d, Height:%d, Fps: %d",
                   m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
                   m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);

  DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d",
                   bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);

  DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %d, qpP: %d, qpb: 0",
                   session_qp.iframeqp, session_qp.pframqp);

  DEBUG_PRINT_HIGH("\nENC_CONFIG: minQP: %d, maxQP: %d",
                   qp_range.minqp, qp_range.maxqp);

  DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d",
                   voptimecfg.voptime_resolution, multislice.mslice_mode,
                   multislice.mslice_size);

  DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %d",
                   entropy.longentropysel, entropy.cabacmodel);

  DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d\n",
                   dbkfilter.db_mode, dbkfilter.slicealpha_offset,
                   dbkfilter.slicebeta_offset);

  DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %d, HEC: %d\n",
                   intra_refresh.mbcount, hec.header_extension);
}

unsigned venc_dev::venc_flush( unsigned port)
{
  struct venc_ioctl_msg ioctl_msg;
  struct venc_bufferflush buffer_index;

  if(port == PORT_INDEX_IN)
  {
    DEBUG_PRINT_HIGH("Calling Input Flush");
    buffer_index.flush_mode = VEN_FLUSH_INPUT;
    ioctl_msg.in = (void*)&buffer_index;
    ioctl_msg.out = NULL;

    return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
  }
  else if(port == PORT_INDEX_OUT)
  {
    DEBUG_PRINT_HIGH("Calling Output Flush");
    buffer_index.flush_mode = VEN_FLUSH_OUTPUT;
    ioctl_msg.in = (void*)&buffer_index;
    ioctl_msg.out = NULL;
    return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
  }
  else
  {
    return -1;
  }
}

//allocating I/P memory from pmem and register with the device


bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct pmem *pmem_tmp;
  struct venc_bufferpayload dev_buffer = {0};
  struct venc_allocatorproperty buff_alloc_property = {0};

  pmem_tmp = (struct pmem *)buf_addr;

  DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);

  if(port == PORT_INDEX_IN)
  {
    dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    dev_buffer.fd  = pmem_tmp->fd;
    dev_buffer.maped_size = pmem_tmp->size;
    dev_buffer.sz = pmem_tmp->size;
    dev_buffer.offset = pmem_tmp->offset;

    if((m_sVenc_cfg.input_height %16 !=0) || (m_sVenc_cfg.input_width%16 != 0))
    {
      unsigned long ht = m_sVenc_cfg.input_height;
      unsigned long wd = m_sVenc_cfg.input_width;
      unsigned int luma_size, luma_size_2k;

      ht = (ht + 15) & ~15;
      wd = (wd + 15) & ~15;

      luma_size = ht * wd;
      luma_size_2k = (luma_size + 2047) & ~2047;

      dev_buffer.sz = luma_size_2k + ((luma_size/2 + 2047) & ~2047);
#ifdef USE_ION
      ioctl_msg.in = NULL;
      ioctl_msg.out = (void*)&buff_alloc_property;
      if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
      {
         DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:get input buffer failed ");
         return false;
      }
      if(buff_alloc_property.alignment < 4096)
      {
         dev_buffer.sz = ((dev_buffer.sz + 4095) & ~4095);
      }
      else
      {
         dev_buffer.sz = ((dev_buffer.sz + (buff_alloc_property.alignment - 1)) &
                                           ~(buff_alloc_property.alignment - 1));
      }
#endif
      dev_buffer.maped_size = dev_buffer.sz;
    }

    ioctl_msg.in  = (void*)&dev_buffer;
    ioctl_msg.out = NULL;

    DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
                dev_buffer.pbuffer, \
                dev_buffer.fd, \
                dev_buffer.offset, \
                dev_buffer.maped_size);

    if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed ");
      return false;
    }
  }
  else if(port == PORT_INDEX_OUT)
  {
    dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    dev_buffer.fd  = pmem_tmp->fd;
    dev_buffer.sz = pmem_tmp->size;
    dev_buffer.maped_size = pmem_tmp->size;
    dev_buffer.offset = pmem_tmp->offset;
    ioctl_msg.in  = (void*)&dev_buffer;
    ioctl_msg.out = NULL;

    DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
                dev_buffer.pbuffer, \
                dev_buffer.fd, \
                dev_buffer.offset, \
                dev_buffer.maped_size);

    if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed ");
      return false;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index ");
    return false;
  }

  return true;
}

bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct pmem *pmem_tmp;
  struct venc_bufferpayload dev_buffer = {0};

  pmem_tmp = (struct pmem *)buf_addr;

  DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);

  if(port == PORT_INDEX_IN)
  {
    dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    dev_buffer.fd  = pmem_tmp->fd;
    dev_buffer.maped_size = pmem_tmp->size;
    dev_buffer.sz = pmem_tmp->size;
    dev_buffer.offset = pmem_tmp->offset;
    ioctl_msg.in  = (void*)&dev_buffer;
    ioctl_msg.out = NULL;

    DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
                dev_buffer.pbuffer, \
                dev_buffer.fd, \
                dev_buffer.offset, \
                dev_buffer.maped_size);

    if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed ");
      return false;
    }
  }
  else if(port == PORT_INDEX_OUT)
  {
    dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    dev_buffer.fd  = pmem_tmp->fd;
    dev_buffer.sz = pmem_tmp->size;
    dev_buffer.maped_size = pmem_tmp->size;
    dev_buffer.offset = pmem_tmp->offset;
    ioctl_msg.in  = (void*)&dev_buffer;
    ioctl_msg.out = NULL;

    DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
                dev_buffer.pbuffer, \
                dev_buffer.fd, \
                dev_buffer.offset, \
                dev_buffer.maped_size);

    if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed ");
      return false;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index ");
    return false;
  }

  return true;
}

bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
{
  struct venc_buffer frameinfo;
  struct pmem *temp_buffer;
  struct venc_ioctl_msg ioctl_msg;
  struct OMX_BUFFERHEADERTYPE *bufhdr;

  if(buffer == NULL)
  {
    DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL");
    return false;
  }
  bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;

  DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen);

  if(pmem_data_buf)
  {
    DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
    frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
  }
  else
  {
    DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
    frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
  }

  frameinfo.clientdata = (void *) buffer;
  frameinfo.sz = bufhdr->nFilledLen;
  frameinfo.len = bufhdr->nFilledLen;
  frameinfo.flags = bufhdr->nFlags;
  frameinfo.offset = bufhdr->nOffset;
  frameinfo.timestamp = bufhdr->nTimeStamp;
  DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp);
  ioctl_msg.in = &frameinfo;
  ioctl_msg.out = NULL;

  DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
      bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
  if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
  {
    /*Generate an async error and move to invalid state*/
    return false;
  }
#ifdef INPUT_BUFFER_LOG
#ifdef MAX_RES_1080P

  int y_size = 0;
  int c_offset = 0;
  unsigned char *buf_addr = NULL;

  y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height;
  //chroma offset is y_size aligned to the 2k boundary
  c_offset= (y_size + 2047) & (~(2047));

  if(pmem_data_buf)
  {
    DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
    buf_addr = (OMX_U8 *)pmem_data_buf;
  }
  else
  {
    DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
    buf_addr = (unsigned char *)mmap(NULL,
          ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2],
          PROT_READ|PROT_WRITE, MAP_SHARED,
          ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[0], 0);
  }

  if(inputBufferFile1)
  {
    fwrite((const char *)buf_addr, y_size, 1,inputBufferFile1);
    fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1,inputBufferFile1);
  }

  munmap (buf_addr, ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2]);
#else
  if(inputBufferFile1)
  {
    fwrite((const char *)frameinfo.ptrbuffer, frameinfo.len, 1,inputBufferFile1);
  }
#endif

#endif
  return true;
}
bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
{
  struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct pmem *temp_buffer = NULL;
  struct venc_buffer  frameinfo;
  struct OMX_BUFFERHEADERTYPE *bufhdr;

  if(buffer == NULL)
  {
    return false;
  }
  bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;

  if(pmem_data_buf)
  {
    DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
    frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
  }
  else
  {
    DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
    frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
  }

  frameinfo.clientdata = buffer;
  frameinfo.sz = bufhdr->nAllocLen;
  frameinfo.flags = bufhdr->nFlags;
  frameinfo.offset = bufhdr->nOffset;

  ioctl_msg.in = &frameinfo;
  ioctl_msg.out = NULL;
  DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
      bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
  if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
    return false;
  }

  return true;
}

bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable);
  if(multislice.mslice_mode == VEN_MSLICE_CNT_MB)
  {
    if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0)
    {
      DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
      return false;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set "
       "slice delivery mode to the driver.", multislice.mslice_mode);
  }
  return true;
}

bool venc_dev::venc_set_plusptype(OMX_BOOL enable)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_plusptype plusptype = {0};
  DEBUG_PRINT_LOW("Set plusptype: %d", enable);
  plusptype.plusptype_enable = enable;
  ioctl_msg.in = (void*)&plusptype;
  ioctl_msg.out = NULL;
  if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_H263_PLUSPTYPE,(void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("Request for setting plusptype for h263 failed");
    return false;
  }
  return true;
}

bool venc_dev::venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  venc_ltrmode ltr_mode;
  ltr_mode.ltr_mode = (unsigned long)mode;
  DEBUG_PRINT_HIGH("Set ltr mode: %d", mode);
  ioctl_msg.in = (void*)&ltr_mode;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRMODE, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Setting ltrmode failed");
    return false;
  }
  ltrmode.ltr_mode = (unsigned long)mode;
  return true;
}

bool venc_dev::venc_set_ltrcount(OMX_U32 count)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  venc_ltrcount ltr_count;
  ltr_count.ltr_count = (unsigned long)count;
  DEBUG_PRINT_HIGH("Set ltr count: %d", count);
  ioctl_msg.in = (void*)&ltr_count;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRCOUNT, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Setting ltrcount failed");
    return false;
  }
  ltrcount.ltr_count = (unsigned long)count;
  return true;
}

bool venc_dev::venc_set_ltrperiod(OMX_U32 period)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  venc_ltrperiod ltr_period;
  ltr_period.ltr_period = (unsigned long)period;
  DEBUG_PRINT_HIGH("Set ltr period: %d", period);
  ioctl_msg.in = (void*)&ltr_period;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRPERIOD, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Setting ltrperiod failed");
    return false;
  }
  ltrperiod.ltr_period = (unsigned long)period;
  return true;
}

bool venc_dev::venc_set_ltruse(OMX_U32 id, OMX_U32 frames)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  venc_ltruse ltr_use;
  ltr_use.ltr_id = (unsigned long)id;
  ltr_use.ltr_frames = (unsigned long)frames;
  DEBUG_PRINT_HIGH("Set ltr use: id = %d, ltr_frames = %d", id, frames);
  ioctl_msg.in = (void*)&ltr_use;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRUSE, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Setting ltruse failed");
    return false;
  }
  return true;
}

bool venc_dev::venc_set_extradata(OMX_U32 extra_data)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data);
  ioctl_msg.in = (void*)&extra_data;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
    return false;
  }

  return true;
}

bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_sessionqp qp = {0, 0};
  DEBUG_PRINT_HIGH("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp,
    p_frame_qp);

  qp.iframeqp = i_frame_qp;
  qp.pframqp = p_frame_qp;

  ioctl_msg.in = (void*)&qp;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed");
    return false;
  }

  session_qp.iframeqp = i_frame_qp;
  session_qp.pframqp = p_frame_qp;

  return true;
}

bool venc_dev::venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_qprange qp = {0, 0};
  DEBUG_PRINT_LOW("venc_set_qp_range:: min_qp = %d, max_qp = %d", min_qp,
    max_qp);

  qp.minqp = min_qp;
  qp.maxqp = max_qp;

  ioctl_msg.in = (void*)&qp;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_QP_RANGE,(void*)&ioctl_msg)< 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting qp range failed");
    return false;
  }

  qp_range.minqp= min_qp;
  qp_range.maxqp= max_qp;

  return true;
}

bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_profile requested_profile;
  struct ven_profilelevel requested_level;
  unsigned const int *profile_tbl = NULL;
  unsigned long mb_per_frame = 0, mb_per_sec = 0;
  DEBUG_PRINT_HIGH("venc_set_profile_level:: eProfile = %d, Level = %d",
    eProfile, eLevel);
  mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
                  ((m_sVenc_cfg.input_width + 15) >> 4);
  if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set)
  {
    DEBUG_PRINT_HIGH("Set profile/level was done already");
    return true;
  }

  if(eProfile && eLevel)
  {
    /* non-zero values will be set by user, saving the same*/
    m_eProfile = eProfile;
    m_eLevel = eLevel;
    DEBUG_PRINT_HIGH("Save profile/level (%d/%d) for max allowed bitrate check",
      m_eProfile, m_eLevel);
  }

  DEBUG_PRINT_LOW("Validating Profile/Level from table");
  if(!venc_validate_profile_level(&eProfile, &eLevel))
  {
    DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed");
    return false;
  }

  if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
  {
    DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
      "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
      OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
    if(eProfile == OMX_VIDEO_MPEG4ProfileSimple)
    {
      requested_profile.profile = VEN_PROFILE_MPEG4_SP;
      profile_tbl = (unsigned int const *)
          (&mpeg4_profile_level_table[MPEG4_SP_START]);
      profile_tbl += MPEG4_720P_LEVEL*5;
    }
    else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
    {
      requested_profile.profile = VEN_PROFILE_MPEG4_ASP;
      profile_tbl = (unsigned int const *)
          (&mpeg4_profile_level_table[MPEG4_ASP_START]);
      profile_tbl += MPEG4_720P_LEVEL*5;
    }
    else
    {
      DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u",
        eProfile);
      return false;
    }

    DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
      "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
      "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
      OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);

    if(mb_per_frame >= 3600)
    {
      if(requested_profile.profile == VEN_PROFILE_MPEG4_ASP)
        requested_level.level = VEN_LEVEL_MPEG4_5;
      if(requested_profile.profile == VEN_PROFILE_MPEG4_SP)
        requested_level.level = VEN_LEVEL_MPEG4_6;
    }
    else
    {
      switch(eLevel)
      {
      case OMX_VIDEO_MPEG4Level0:
        requested_level.level = VEN_LEVEL_MPEG4_0;
        break;
      case OMX_VIDEO_MPEG4Level1:
        requested_level.level = VEN_LEVEL_MPEG4_1;
        break;
      case OMX_VIDEO_MPEG4Level2:
        requested_level.level = VEN_LEVEL_MPEG4_2;
        break;
      case OMX_VIDEO_MPEG4Level3:
        requested_level.level = VEN_LEVEL_MPEG4_3;
        break;
      case OMX_VIDEO_MPEG4Level4a:
        requested_level.level = VEN_LEVEL_MPEG4_4;
        break;
      case OMX_VIDEO_MPEG4Level5:
        mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den);
		if((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) &&
           (mb_per_sec >= profile_tbl[1]))
        {
          DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution");
          requested_level.level = VEN_LEVEL_MPEG4_6;
        }
        else
        {
          DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution");
          requested_level.level = VEN_LEVEL_MPEG4_5;
        }
        break;
      default:
        return false;
        // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
        break;
      }
    }
  }
  else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
  {
    if(eProfile == OMX_VIDEO_H263ProfileBaseline)
    {
      requested_profile.profile = VEN_PROFILE_H263_BASELINE;
    }
    else
    {
      DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u",
        requested_profile.profile);
      return false;
    }
    //profile level
    switch(eLevel)
    {
    case OMX_VIDEO_H263Level10:
      requested_level.level = VEN_LEVEL_H263_10;
      break;
    case OMX_VIDEO_H263Level20:
      requested_level.level = VEN_LEVEL_H263_20;
      break;
    case OMX_VIDEO_H263Level30:
      requested_level.level = VEN_LEVEL_H263_30;
      break;
    case OMX_VIDEO_H263Level40:
      requested_level.level = VEN_LEVEL_H263_40;
      break;
    case OMX_VIDEO_H263Level45:
      requested_level.level = VEN_LEVEL_H263_45;
      break;
    case OMX_VIDEO_H263Level50:
      requested_level.level = VEN_LEVEL_H263_50;
      break;
    case OMX_VIDEO_H263Level60:
      requested_level.level = VEN_LEVEL_H263_60;
      break;
    case OMX_VIDEO_H263Level70:
      requested_level.level = VEN_LEVEL_H263_70;
      break;
    default:
      return false;
      break;
    }
  }
  else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
  {
    if(eProfile == OMX_VIDEO_AVCProfileBaseline)
    {
      requested_profile.profile = VEN_PROFILE_H264_BASELINE;
    }
    else if(eProfile == OMX_VIDEO_AVCProfileMain)
    {
      requested_profile.profile = VEN_PROFILE_H264_MAIN;
    }
    else if(eProfile == OMX_VIDEO_AVCProfileHigh)
    {
      requested_profile.profile = VEN_PROFILE_H264_HIGH;
    }
    else
    {
      DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u",
        requested_profile.profile);
      return false;
    }
    //profile level
    switch(eLevel)
    {
    case OMX_VIDEO_AVCLevel1:
      requested_level.level = VEN_LEVEL_H264_1;
      break;
    case OMX_VIDEO_AVCLevel1b:
      requested_level.level = VEN_LEVEL_H264_1b;
      break;
    case OMX_VIDEO_AVCLevel11:
      requested_level.level = VEN_LEVEL_H264_1p1;
      break;
    case OMX_VIDEO_AVCLevel12:
      requested_level.level = VEN_LEVEL_H264_1p2;
      break;
    case OMX_VIDEO_AVCLevel13:
      requested_level.level = VEN_LEVEL_H264_1p3;
      break;
    case OMX_VIDEO_AVCLevel2:
      requested_level.level = VEN_LEVEL_H264_2;
      break;
    case OMX_VIDEO_AVCLevel21:
      requested_level.level = VEN_LEVEL_H264_2p1;
      break;
    case OMX_VIDEO_AVCLevel22:
      requested_level.level = VEN_LEVEL_H264_2p2;
      break;
    case OMX_VIDEO_AVCLevel3:
      requested_level.level = VEN_LEVEL_H264_3;
      break;
    case OMX_VIDEO_AVCLevel31:
      requested_level.level = VEN_LEVEL_H264_3p1;
      break;
    case OMX_VIDEO_AVCLevel32:
      requested_level.level = VEN_LEVEL_H264_3p2;
      break;
    case OMX_VIDEO_AVCLevel4:
      requested_level.level = VEN_LEVEL_H264_4;
      break;
    default :
      DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %u",
        requested_level.level);
      return false;
      break;
    }
  }
  if(!m_profile_set)
  {
    ioctl_msg.in = (void*)&requested_profile;
    ioctl_msg.out = NULL;
    if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: Request for setting profile failed");
      return false;
    }
    codec_profile.profile = requested_profile.profile;
    m_profile_set = true;
    DEBUG_PRINT_HIGH("Set codec profile = 0x%x", codec_profile.profile);
  }

  if(!m_level_set)
  {
    ioctl_msg.in = (void*)&requested_level;
    ioctl_msg.out = NULL;
    if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: Request for setting profile level failed");
      return false;
    }
    profile_level.level = requested_level.level;
    m_level_set = true;
    DEBUG_PRINT_HIGH("Set codec level = 0x%x", profile_level.level);
  }

  return true;
}

bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_voptimingcfg vop_timing_cfg;

  DEBUG_PRINT_HIGH("venc_set_voptiming_cfg: TimeRes = %u",
    TimeIncRes);

  vop_timing_cfg.voptime_resolution = TimeIncRes;

  ioctl_msg.in = (void*)&vop_timing_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting Vop Timing failed");
    return false;
  }

  voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
  return true;
}

bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_intraperiod intraperiod_cfg;

  DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u",
    nPFrames);
  intraperiod_cfg.num_pframes = nPFrames;
  if((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) ||
     (codec_profile.profile == VEN_PROFILE_H264_MAIN) ||
     (codec_profile.profile == VEN_PROFILE_H264_HIGH))
  {
#ifdef MAX_RES_1080P
    if (nBFrames)
    {
      DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
      intraperiod_cfg.num_bframes = 1;
    }
    else
      intraperiod_cfg.num_bframes = 0;
#else
    if(nBFrames)
    {
      DEBUG_PRINT_ERROR("B frames not supported");
      intraperiod_cfg.num_bframes = 0;
    }
    else
    {
      DEBUG_PRINT_ERROR("B frames not supported");
      intraperiod_cfg.num_bframes = 0;
    }
#endif
  }
  else
    intraperiod_cfg.num_bframes = 0;

  DEBUG_PRINT_HIGH("venc_set_intra_period: nPFrames = %u nBFrames = %u",
                    intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes);
  ioctl_msg.in = (void*)&intraperiod_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
    return false;
  }

  intra_period.num_pframes = intraperiod_cfg.num_pframes;
  intra_period.num_bframes = intraperiod_cfg.num_bframes;
  return true;
}

bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_entropycfg entropy_cfg;

  memset(&entropy_cfg,0,sizeof(entropy_cfg));
  DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level);

  if(enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)){
    entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC;
      if (i_cabac_level == 0) {
         entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
      }
#ifdef MAX_RES_1080P
      else
      {
        DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to  model 0",i_cabac_level);
        entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
      }
#else
      else if (i_cabac_level == 1) {
         entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1;
      }
      else if (i_cabac_level == 2) {
         entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2;
      }
#endif
  }
  else if(!enable){
    entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC;
    }
  else{
    DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile");
    return false;
  }

  ioctl_msg.in = (void*)&entropy_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting entropy config failed");
    return false;
  }
  entropy.longentropysel = entropy_cfg.longentropysel;
  entropy.cabacmodel  = entropy_cfg.cabacmodel;
  return true;
}

bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
{
 venc_ioctl_msg ioctl_msg = {NULL, NULL};
  bool status = true;
  struct venc_multiclicecfg multislice_cfg;

  if((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)){
    multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB;
    multislice_cfg.mslice_size = nSlicesize;
    }
  else{
    multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
    multislice_cfg.mslice_size = 0;
  }

  DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
                  multislice_cfg.mslice_size);

  ioctl_msg.in = (void*)&multislice_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
    status = false;
  }
  else
  {
    multislice.mslice_mode = multislice_cfg.mslice_mode;
    multislice.mslice_size = nSlicesize;
  }
  return status;
}

bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
{
 venc_ioctl_msg ioctl_msg = {NULL, NULL};
  bool status = true;
  struct venc_intrarefresh intraRefresh_cfg;

  // There is no disabled mode.  Disabled mode is indicated by a 0 count.
  if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax)
  {
    intraRefresh_cfg.irmode = VEN_IR_OFF;
    intraRefresh_cfg.mbcount = 0;
  }
  else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
           (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8)))
  {
    intraRefresh_cfg.irmode = VEN_IR_CYCLIC;
    intraRefresh_cfg.mbcount = irMBs;
  }
  else
  {
    DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:"
                      "mb count: %d, mb mode:%d", irMBs, ir_mode);
    return false;
  }

  ioctl_msg.in = (void*)&intraRefresh_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra Refresh failed");
    status = false;
  }
  else
  {
    intra_refresh.irmode = intraRefresh_cfg.irmode;
    intra_refresh.mbcount = intraRefresh_cfg.mbcount;
  }
  return status;
}

bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
{
   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   bool status = true;
   struct venc_headerextension hec_cfg;
   struct venc_multiclicecfg multislice_cfg;

   if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) {
      if (error_resilience->bEnableHEC) {
         hec_cfg.header_extension = 1;
      }
      else {
         hec_cfg.header_extension = 0;
      }

      ioctl_msg.in = (void*)&hec_cfg;
      ioctl_msg.out = NULL;
      if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) {
         DEBUG_PRINT_ERROR("\nERROR: Request for setting HEader Error correction failed");
         return false;
      }
      hec.header_extension = error_resilience->bEnableHEC;
   }

   if (error_resilience->bEnableRVLC) {
     DEBUG_PRINT_ERROR("\n RVLC is not Supported");
     return false;
   }

   if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
       (error_resilience->bEnableDataPartitioning)) {
     DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264");
     return false;
     }

   if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
            (error_resilience->nResynchMarkerSpacing)) {
     multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
       multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
     }
   else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 &&
            error_resilience->bEnableDataPartitioning) {
      multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
      multislice_cfg.mslice_size = 0;
      }
      else {
        multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
        multislice_cfg.mslice_size = 0;
        }
   DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
                   multislice_cfg.mslice_size);
   ioctl_msg.in = (void*)&multislice_cfg;
   ioctl_msg.out = NULL;
   if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) {
      DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
      status = false;
   }
   else
   {
     multislice.mslice_mode = multislice_cfg.mslice_mode ;
     multislice.mslice_size = multislice_cfg.mslice_size;

   }
   return status;
}

bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  struct venc_dbcfg filter_cfg;

  memset(&filter_cfg, 0, sizeof(filter_cfg));
  DEBUG_PRINT_LOW("\n venc_set_inloop_filter: %u",loopfilter);

  if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){
    filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY;
  }
  else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){
    filter_cfg.db_mode = VEN_DB_DISABLE;
  }
  else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){
    filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY;
  }
  filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0;

  ioctl_msg.in = (void*)&filter_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting inloop filter failed");
    return false;
  }

  dbkfilter.db_mode = filter_cfg.db_mode;
  dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
  return true;
}

bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
{
  venc_ioctl_msg ioctl_msg = {NULL, NULL};
  struct venc_targetbitrate bitrate_cfg;

  DEBUG_PRINT_HIGH("venc_set_target_bitrate: bitrate = %u",
    nTargetBitrate);
  bitrate_cfg.target_bitrate = nTargetBitrate ;
  ioctl_msg.in = (void*)&bitrate_cfg;
  ioctl_msg.out = NULL;
  if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed");
    return false;
  }
  m_sVenc_cfg.targetbitrate = nTargetBitrate;
  bitrate.target_bitrate = nTargetBitrate;
  if(!config)
  {
    m_level_set = false;
    if(venc_set_profile_level(0, 0))
    {
      DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d\n",profile_level.level);
    }
  }
  return true;
}

bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
{
  venc_ioctl_msg ioctl_msg = {NULL, NULL};
  struct venc_framerate frame_rate_cfg;

  Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);

  DEBUG_PRINT_HIGH("venc_set_encode_framerate: framerate(Q16) = %u, NR: %d, DR: %d",
                  encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);

  ioctl_msg.in = (void*)&frame_rate_cfg;
  ioctl_msg.out = NULL;
  if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE,
      (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed");
    return false;
  }

  m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
  m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
  if(!config)
  {
    m_level_set = false;
    if(venc_set_profile_level(0, 0))
    {
      DEBUG_PRINT_LOW("Calling set level (Framerate) with %d",profile_level.level);
    }
  }
  return true;
}

bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
{
  venc_ioctl_msg ioctl_msg = {NULL, NULL};
  if(color_format == OMX_COLOR_FormatYUV420SemiPlanar)
  {
#ifdef MAX_RES_1080P
  m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
#else
    m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
#endif
  }
  else
  {
    DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format);
#ifdef MAX_RES_1080P
    m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
#else
    m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
#endif
    DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set");
  }
  ioctl_msg.in = (void*)&m_sVenc_cfg;
  ioctl_msg.out = NULL;
  if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed");
    return false;
  }
  return true;
}

bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
{
  DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
  if(intra_vop_refresh == OMX_TRUE)
  {
    if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed");
      return false;
    }
  }
  else
  {
    DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect");
  }
  return true;
}

bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  bool status = true;
  struct venc_ratectrlcfg ratectrl_cfg;

  //rate control
  switch(eControlRate)
  {
  case OMX_Video_ControlRateDisable:
    ratectrl_cfg.rcmode = VEN_RC_OFF;
    break;
  case OMX_Video_ControlRateVariableSkipFrames:
    ratectrl_cfg.rcmode = VEN_RC_VBR_VFR;
    break;
  case OMX_Video_ControlRateVariable:
    ratectrl_cfg.rcmode = VEN_RC_VBR_CFR;
    break;
  case OMX_Video_ControlRateConstantSkipFrames:
    ratectrl_cfg.rcmode = VEN_RC_CBR_VFR;
    break;
  case OMX_Video_ControlRateConstant:
    ratectrl_cfg.rcmode = VEN_RC_CBR_CFR;
    break;
  default:
    status = false;
    break;
  }

  if(status)
  {
    ioctl_msg.in = (void*)&ratectrl_cfg;
    ioctl_msg.out = NULL;
    if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0)
    {
      DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed");
      status = false;
    }
    else
      rate_ctrl.rcmode = ratectrl_cfg.rcmode;
  }
  return status;
}

bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
{
  bool status = true;
  if(eProfile == NULL || eLevel == NULL)
  {
    return false;
  }

  if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
  {
    switch(codec_profile.profile)
    {
    case VEN_PROFILE_MPEG4_SP:
      *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
      break;
    case VEN_PROFILE_MPEG4_ASP:
      *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
      break;
    default:
      *eProfile = OMX_VIDEO_MPEG4ProfileMax;
      status = false;
      break;
    }

    if(!status)
    {
      return status;
    }

    //profile level
    switch(profile_level.level)
    {
    case VEN_LEVEL_MPEG4_0:
      *eLevel = OMX_VIDEO_MPEG4Level0;
      break;
    case VEN_LEVEL_MPEG4_1:
      *eLevel = OMX_VIDEO_MPEG4Level1;
      break;
    case VEN_LEVEL_MPEG4_2:
      *eLevel = OMX_VIDEO_MPEG4Level2;
      break;
    case VEN_LEVEL_MPEG4_3:
      *eLevel = OMX_VIDEO_MPEG4Level3;
      break;
    case VEN_LEVEL_MPEG4_4:
      *eLevel = OMX_VIDEO_MPEG4Level4a;
      break;
    case VEN_LEVEL_MPEG4_5:
    case VEN_LEVEL_MPEG4_6:
      *eLevel = OMX_VIDEO_MPEG4Level5;
      break;
    default:
      *eLevel = OMX_VIDEO_MPEG4LevelMax;
      status =  false;
      break;
    }
  }
  else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
  {
    if(codec_profile.profile == VEN_PROFILE_H263_BASELINE)
    {
      *eProfile = OMX_VIDEO_H263ProfileBaseline;
    }
    else
    {
      *eProfile = OMX_VIDEO_H263ProfileMax;
      return false;
    }
    switch(profile_level.level)
    {
    case VEN_LEVEL_H263_10:
      *eLevel = OMX_VIDEO_H263Level10;
      break;
    case VEN_LEVEL_H263_20:
      *eLevel = OMX_VIDEO_H263Level20;
      break;
    case VEN_LEVEL_H263_30:
      *eLevel = OMX_VIDEO_H263Level30;
      break;
    case VEN_LEVEL_H263_40:
      *eLevel = OMX_VIDEO_H263Level40;
      break;
    case VEN_LEVEL_H263_45:
      *eLevel = OMX_VIDEO_H263Level45;
      break;
    case VEN_LEVEL_H263_50:
      *eLevel = OMX_VIDEO_H263Level50;
      break;
    case VEN_LEVEL_H263_60:
      *eLevel = OMX_VIDEO_H263Level60;
      break;
    case VEN_LEVEL_H263_70:
      *eLevel = OMX_VIDEO_H263Level70;
      break;
    default:
      *eLevel = OMX_VIDEO_H263LevelMax;
      status = false;
      break;
    }
  }
  else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
  {
    switch(codec_profile.profile)
    {
    case VEN_PROFILE_H264_BASELINE:
      *eProfile = OMX_VIDEO_AVCProfileBaseline;
      break;
    case VEN_PROFILE_H264_MAIN:
      *eProfile = OMX_VIDEO_AVCProfileMain;
      break;
    case VEN_PROFILE_H264_HIGH:
      *eProfile = OMX_VIDEO_AVCProfileHigh;
      break;
    default:
      *eProfile = OMX_VIDEO_AVCProfileMax;
      status = false;
      break;
    }

    if(!status)
    {
      return status;
    }

    switch(profile_level.level)
    {
    case VEN_LEVEL_H264_1:
      *eLevel = OMX_VIDEO_AVCLevel1;
      break;
    case VEN_LEVEL_H264_1b:
      *eLevel = OMX_VIDEO_AVCLevel1b;
      break;
    case VEN_LEVEL_H264_1p1:
      *eLevel = OMX_VIDEO_AVCLevel11;
      break;
    case VEN_LEVEL_H264_1p2:
      *eLevel = OMX_VIDEO_AVCLevel12;
      break;
    case VEN_LEVEL_H264_1p3:
      *eLevel = OMX_VIDEO_AVCLevel13;
      break;
    case VEN_LEVEL_H264_2:
      *eLevel = OMX_VIDEO_AVCLevel2;
      break;
    case VEN_LEVEL_H264_2p1:
      *eLevel = OMX_VIDEO_AVCLevel21;
      break;
    case VEN_LEVEL_H264_2p2:
      *eLevel = OMX_VIDEO_AVCLevel22;
      break;
    case VEN_LEVEL_H264_3:
      *eLevel = OMX_VIDEO_AVCLevel3;
      break;
    case VEN_LEVEL_H264_3p1:
      *eLevel = OMX_VIDEO_AVCLevel31;
      break;
    case VEN_LEVEL_H264_3p2:
      *eLevel = OMX_VIDEO_AVCLevel32;
      break;
    case VEN_LEVEL_H264_4:
      *eLevel = OMX_VIDEO_AVCLevel4;
      break;
	  default :
      *eLevel = OMX_VIDEO_AVCLevelMax;
      status = false;
      break;
    }
  }
  return status;
}

bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
{
  OMX_U32 new_profile = 0, new_level = 0;
  unsigned const int *profile_tbl = NULL;
  OMX_U32 mb_per_frame, mb_per_sec;
  bool profile_level_found = false;

  DEBUG_PRINT_LOW("\n Init profile table for respective codec");
  //validate the ht,width,fps,bitrate and set the appropriate profile and level
  if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
  {
      if(*eProfile == 0)
      {
        if(!m_profile_set)
        {
          *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
        }
        else
        {
          switch(codec_profile.profile)
          {
          case VEN_PROFILE_MPEG4_ASP:
              *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
            break;
          case VEN_PROFILE_MPEG4_SP:
              *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
            break;
          default:
            DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
            return false;
          }
        }
      }

      if(*eLevel == 0 && !m_level_set)
      {
        *eLevel = OMX_VIDEO_MPEG4LevelMax;
      }

      if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple)
      {
        profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
      }
      else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
      {
        profile_tbl = (unsigned int const *)
          (&mpeg4_profile_level_table[MPEG4_ASP_START]);
      }
      else
      {
        DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile);
        return false;
      }
  }
  else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
  {
      if(*eProfile == 0)
      {
        if(!m_profile_set)
        {
          *eProfile = OMX_VIDEO_AVCProfileBaseline;
        }
        else
        {
          switch(codec_profile.profile)
          {
          case VEN_PROFILE_H264_BASELINE:
            *eProfile = OMX_VIDEO_AVCProfileBaseline;
            break;
          case VEN_PROFILE_H264_MAIN:
            *eProfile = OMX_VIDEO_AVCProfileMain;
            break;
          case VEN_PROFILE_H264_HIGH:
            *eProfile = OMX_VIDEO_AVCProfileHigh;
            break;
          default:
            DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
            return false;
          }
        }
      }

      if(*eLevel == 0 && !m_level_set)
      {
        *eLevel = OMX_VIDEO_AVCLevelMax;
      }

      if(*eProfile == OMX_VIDEO_AVCProfileBaseline)
      {
        profile_tbl = (unsigned int const *)h264_profile_level_table;
      }
      else if(*eProfile == OMX_VIDEO_AVCProfileHigh)
      {
        profile_tbl = (unsigned int const *)
          (&h264_profile_level_table[H264_HP_START]);
      }
      else if(*eProfile == OMX_VIDEO_AVCProfileMain)
      {
        profile_tbl = (unsigned int const *)
          (&h264_profile_level_table[H264_MP_START]);
      }
      else
      {
        DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile);
        return false;
      }
  }
  else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
  {
      if(*eProfile == 0)
      {
        if(!m_profile_set)
        {
          *eProfile = OMX_VIDEO_H263ProfileBaseline;
        }
        else
        {
          switch(codec_profile.profile)
          {
          case VEN_PROFILE_H263_BASELINE:
            *eProfile = OMX_VIDEO_H263ProfileBaseline;
            break;
          default:
            DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
            return false;
          }
        }
      }

      if(*eLevel == 0 && !m_level_set)
      {
        *eLevel = OMX_VIDEO_H263LevelMax;
      }

      if(*eProfile == OMX_VIDEO_H263ProfileBaseline)
      {
        profile_tbl = (unsigned int const *)h263_profile_level_table;
      }
      else
      {
        DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile);
        return false;
      }
  }
  else
  {
    DEBUG_PRINT_LOW("\n Invalid codec type");
    return false;
  }

  mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
                   ((m_sVenc_cfg.input_width + 15)>> 4);

  if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4))
  {
    if(codec_profile.profile == VEN_PROFILE_MPEG4_ASP)
      profile_level.level = VEN_LEVEL_MPEG4_5;
    if(codec_profile.profile == VEN_PROFILE_MPEG4_SP)
      profile_level.level = VEN_LEVEL_MPEG4_6;
    {
      new_level = profile_level.level;
      new_profile = codec_profile.profile;
      return true;
    }
  }

  mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;

  do{
      if(mb_per_frame <= (int)profile_tbl[0])
      {
        if(mb_per_sec <= (int)profile_tbl[1])
        {
          if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2])
          {
              new_level = (int)profile_tbl[3];
              new_profile = (int)profile_tbl[4];
              profile_level_found = true;
              DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level);
              break;
          }
        }
      }
      profile_tbl = profile_tbl + 5;
  }while(profile_tbl[0] != 0);

  if (profile_level_found != true)
  {
    DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n");
    return false;
  }

  if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
     || (*eLevel == OMX_VIDEO_H263LevelMax))
  {
    *eLevel = new_level;
  }
  DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu"
      "Level = %lu", __func__, *eProfile, *eLevel);

  return true;
}

bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate)
{
  unsigned const int *profile_tbl = NULL;

  switch(m_sVenc_cfg.codectype)
  {
    case VEN_CODEC_MPEG4:
      if(m_eProfile == OMX_VIDEO_MPEG4ProfileSimple)
      {
        profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
      }
      else if(m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
      {
        profile_tbl = (unsigned int const *)
          (&mpeg4_profile_level_table[MPEG4_ASP_START]);
      }
      else
      {
        DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile);
        return false;
      }
      break;
    case VEN_CODEC_H264:
      if(m_eProfile == OMX_VIDEO_AVCProfileBaseline)
      {
        profile_tbl = (unsigned int const *)h264_profile_level_table;
      }
      else if(m_eProfile == OMX_VIDEO_AVCProfileHigh)
      {
        profile_tbl = (unsigned int const *)
          (&h264_profile_level_table[H264_HP_START]);
      }
      else if(m_eProfile == OMX_VIDEO_AVCProfileMain)
      {
        profile_tbl = (unsigned int const *)
          (&h264_profile_level_table[H264_MP_START]);
      }
      else
      {
        DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile);
        return false;
      }

      break;
    case VEN_CODEC_H263:
      if(m_eProfile == OMX_VIDEO_H263ProfileBaseline)
      {
        profile_tbl = (unsigned int const *)h263_profile_level_table;
      }
      else
      {
        DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile);
        return false;
      }
      break;
    default:
      DEBUG_PRINT_ERROR("%s: unknown codec type", __func__);
      return false;
  }
  while(profile_tbl[0] != 0)
  {
    if(profile_tbl[3] == m_eLevel)
    {
      if(nTargetBitrate > profile_tbl[2])
      {
         DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]"
            " is %u", m_eProfile, m_eLevel, profile_tbl[2]);
        return false;
      }
    }
    profile_tbl += 5;
  }
  return true;
}

#ifdef _ANDROID_ICS_
bool venc_dev::venc_set_meta_mode(bool mode)
{
  venc_ioctl_msg ioctl_msg = {NULL,NULL};
  ioctl_msg.in = &mode;
  DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode);
  if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0)
  {
    DEBUG_PRINT_ERROR(" Set meta buffer mode failed");
    return false;
  }
  return true;
}
#endif
