Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010, Code Aurora Forum. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of Code Aurora nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 #include<string.h>
     29 #include <sys/ioctl.h>
     30 #include<unistd.h>
     31 #include <fcntl.h>
     32 #include "video_encoder_device.h"
     33 #include "omx_video_encoder.h"
     34 
     35 #define MPEG4_SP_START 0
     36 #define MPEG4_ASP_START (MPEG4_SP_START + 8)
     37 #define MPEG4_720P_LEVEL 6
     38 #define H263_BP_START 0
     39 #define H264_BP_START 0
     40 #define H264_HP_START (H264_BP_START + 11)
     41 #define H264_MP_START (H264_BP_START + 21)
     42 
     43 /* MPEG4 profile and level table*/
     44 static const unsigned int mpeg4_profile_level_table[][5]=
     45 {
     46     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
     47     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
     48     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
     49     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
     50     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
     51     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
     52     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     53     {3600,108000,14000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     54     {0,0,0,0,0},
     55 
     56     {99,2970,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     57     {99,2970,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     58     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     59     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     60     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     61     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     62     {3600,108000,14000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     63     {0,0,0,0,0}
     64 };
     65 
     66 /* H264 profile and level table*/
     67 static const unsigned int h264_profile_level_table[][5]=
     68 {
     69      /*max mb per frame, max mb per sec, max bitrate, level, profile*/
     70     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
     71     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
     72     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
     73     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
     74     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
     75     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
     76     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
     77     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
     78     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
     79     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
     80     {0,0,0,0,0},
     81 
     82     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
     83     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
     84     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
     85     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
     86     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
     87     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
     88     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
     89     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
     90     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
     91     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
     92     {0,0,0,0,0},
     93 
     94     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
     95     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
     96     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
     97     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
     98     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
     99     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
    100     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
    101     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
    102     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
    103     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
    104     {0,0,0,0,0}
    105 };
    106 
    107 /* H263 profile and level table*/
    108 static const unsigned int h263_profile_level_table[][5]=
    109 {
    110     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    111     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
    112     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
    113     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
    114     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
    115     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
    116     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
    117     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
    118     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    119     {0,0,0,0,0}
    120 };
    121 
    122 //constructor
    123 venc_dev::venc_dev()
    124 {
    125 //nothing to do
    126 
    127 }
    128 
    129 venc_dev::~venc_dev()
    130 {
    131   //nothing to do
    132 }
    133 
    134 void* async_venc_message_thread (void *input)
    135 {
    136   struct venc_ioctl_msg ioctl_msg ={NULL,NULL};
    137   struct venc_timeout timeout;
    138   struct venc_msg venc_msg;
    139   omx_venc *omx = reinterpret_cast<omx_venc*>(input);
    140 
    141   timeout.millisec = VEN_TIMEOUT_INFINITE;
    142   while(1)
    143   {
    144     ioctl_msg.inputparam = NULL;
    145     ioctl_msg.outputparam = (void*)&venc_msg;
    146 
    147     /*Wait for a message from the video decoder driver*/
    148     if(ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg) < 0)
    149     {
    150       DEBUG_PRINT_ERROR("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed/stopped");
    151       break;
    152     }
    153     else
    154     {
    155       /*Call Instance specific process function*/
    156       if(omx->async_message_process(input,&venc_msg) < 0)
    157       {
    158         DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
    159         break;
    160       }
    161     }
    162   }
    163   DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n");
    164   return NULL;
    165 }
    166 
    167 bool venc_dev::venc_open(OMX_U32 codec)
    168 {
    169   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    170   int r;
    171   unsigned int   alignment = 0,buffer_size = 0, temp =0;
    172 
    173   m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
    174   if(m_nDriver_fd == 0)
    175   {
    176     DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n");
    177     m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK);
    178   }
    179 
    180   if((int)m_nDriver_fd < 0)
    181   {
    182     DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n");
    183     return false;
    184   }
    185 
    186   DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd);
    187   // set the basic configuration of the video encoder driver
    188   m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
    189   m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
    190   m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
    191   m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
    192   m_sVenc_cfg.fps_num = 30;
    193   m_sVenc_cfg.fps_den = 1;
    194   m_sVenc_cfg.targetbitrate = 64000;
    195   m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12;
    196   if(codec == OMX_VIDEO_CodingMPEG4)
    197   {
    198     m_sVenc_cfg.codectype = VEN_CODEC_MPEG4;
    199     codec_profile.profile = VEN_PROFILE_MPEG4_SP;
    200     profile_level.level = VEN_LEVEL_MPEG4_2;
    201   }
    202   else if(codec == OMX_VIDEO_CodingH263)
    203   {
    204     m_sVenc_cfg.codectype = VEN_CODEC_H263;
    205     codec_profile.profile = VEN_PROFILE_H263_BASELINE;
    206     profile_level.level = VEN_LEVEL_H263_20;
    207   }
    208   if(codec == OMX_VIDEO_CodingAVC)
    209   {
    210     m_sVenc_cfg.codectype = VEN_CODEC_H264;
    211     codec_profile.profile = VEN_PROFILE_H264_BASELINE;
    212     profile_level.level = VEN_LEVEL_H264_1p1;
    213   }
    214   ioctl_msg.inputparam = (void*)&m_sVenc_cfg;
    215   ioctl_msg.outputparam = NULL;
    216   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 )
    217   {
    218     DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed");
    219     return false;
    220   }
    221 
    222   // Get the I/P and O/P buffer requirements
    223   ioctl_msg.inputparam = NULL;
    224   ioctl_msg.outputparam = (void*)&m_sInput_buff_property;
    225   if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    226   {
    227     DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
    228     return false;
    229   }
    230   ioctl_msg.inputparam = NULL;
    231   ioctl_msg.outputparam = (void*)&m_sOutput_buff_property;
    232   if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    233   {
    234     DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
    235     return false;
    236   }
    237 
    238   m_profile_set = false;
    239   m_level_set = false;
    240   if(venc_set_profile_level(0, 0))
    241   {
    242     DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success",
    243         __func__);
    244   }
    245 
    246   return true;
    247 }
    248 
    249 void venc_dev::venc_close()
    250 {
    251   DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd);
    252   if((int)m_nDriver_fd >= 0)
    253   {
    254     DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
    255     (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
    256         NULL);
    257     DEBUG_PRINT_LOW("\nCalling close()\n");
    258     close(m_nDriver_fd);
    259     m_nDriver_fd = -1;
    260   }
    261 }
    262 
    263 bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
    264                                 unsigned long *actual_buff_count,
    265                                 unsigned long *buff_size,
    266                                 unsigned long port)
    267 {
    268   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    269   unsigned long temp_count = 0;
    270 
    271   if(port == 0)
    272   {
    273     if(*actual_buff_count > m_sInput_buff_property.mincount)
    274     {
    275       temp_count = m_sInput_buff_property.actualcount;
    276       m_sInput_buff_property.actualcount = *actual_buff_count;
    277       ioctl_msg.inputparam = (void*)&m_sInput_buff_property;
    278       ioctl_msg.outputparam = NULL;
    279       if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    280       {
    281         DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed");
    282         m_sInput_buff_property.actualcount = temp_count;
    283         return false;
    284       }
    285       DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count);
    286     }
    287   }
    288   else
    289   {
    290     if(*actual_buff_count > m_sOutput_buff_property.mincount)
    291     {
    292 	  temp_count = m_sOutput_buff_property.actualcount;
    293       m_sOutput_buff_property.actualcount = *actual_buff_count;
    294       ioctl_msg.inputparam = (void*)&m_sOutput_buff_property;
    295       ioctl_msg.outputparam = NULL;
    296       if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    297       {
    298         DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed");
    299 		m_sOutput_buff_property.actualcount = temp_count;
    300         return false;
    301       }
    302       DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count);
    303     }
    304   }
    305 
    306   return true;
    307 
    308 }
    309 
    310 bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
    311                                 unsigned long *actual_buff_count,
    312                                 unsigned long *buff_size,
    313                                 unsigned long port)
    314 {
    315   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    316 
    317   if(port == 0)
    318   {
    319     ioctl_msg.inputparam = NULL;
    320     ioctl_msg.outputparam = (void*)&m_sInput_buff_property;
    321     if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    322     {
    323       DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
    324       return false;
    325     }
    326     *min_buff_count = m_sInput_buff_property.mincount;
    327     *actual_buff_count = m_sInput_buff_property.actualcount;
    328     *buff_size = m_sInput_buff_property.datasize
    329                  + (m_sInput_buff_property.datasize % m_sInput_buff_property.alignment) ;
    330   }
    331   else
    332   {
    333     ioctl_msg.inputparam = NULL;
    334     ioctl_msg.outputparam = (void*)&m_sOutput_buff_property;
    335     if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    336     {
    337       DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
    338       return false;
    339     }
    340     *min_buff_count = m_sOutput_buff_property.mincount;
    341     *actual_buff_count = m_sOutput_buff_property.actualcount;
    342     *buff_size = m_sOutput_buff_property.datasize
    343                  + (m_sOutput_buff_property.datasize % m_sOutput_buff_property.alignment) ;
    344   }
    345 
    346   return true;
    347 
    348 }
    349 
    350 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
    351 {
    352   venc_ioctl_msg ioctl_msg = {NULL,NULL};
    353   OMX_U32 temp_out_buf_count = 0;
    354   DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n");
    355   switch(index)
    356   {
    357   case OMX_IndexParamPortDefinition:
    358     {
    359       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
    360       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
    361       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n");
    362       if(portDefn->nPortIndex == PORT_INDEX_IN)
    363       {
    364         if(!venc_set_color_format(portDefn->format.video.eColorFormat))
    365         {
    366           return false;
    367         }
    368         if(m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
    369           m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth)
    370         {
    371           DEBUG_PRINT_LOW("\n Basic parameter has changed");
    372           m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
    373           m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
    374 
    375           temp_out_buf_count = m_sOutput_buff_property.actualcount;
    376           ioctl_msg.inputparam = (void*)&m_sVenc_cfg;
    377           ioctl_msg.outputparam = NULL;
    378           if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0)
    379           {
    380             DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed");
    381             return false;
    382           }
    383 
    384           DEBUG_PRINT_LOW("\n Updating the buffer count/size for the new resolution");
    385           ioctl_msg.inputparam = NULL;
    386           ioctl_msg.outputparam = (void*)&m_sInput_buff_property;
    387           if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    388           {
    389             DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed");
    390             return false;
    391           }
    392           DEBUG_PRINT_LOW("\n Got updated m_sInput_buff_property values: "
    393                       "datasize = %u, maxcount = %u, actualcnt = %u, "
    394                       "mincount = %u", m_sInput_buff_property.datasize,
    395                       m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount,
    396                       m_sInput_buff_property.mincount);
    397 
    398           ioctl_msg.inputparam = NULL;
    399           ioctl_msg.outputparam = (void*)&m_sOutput_buff_property;
    400           if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    401           {
    402             DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed");
    403             return false;
    404           }
    405 
    406           DEBUG_PRINT_LOW("\n Got updated m_sOutput_buff_property values: "
    407                       "datasize = %u, maxcount = %u, actualcnt = %u, "
    408                       "mincount = %u", m_sOutput_buff_property.datasize,
    409                       m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount,
    410                       m_sOutput_buff_property.mincount);
    411 
    412           if(temp_out_buf_count < 7)
    413             temp_out_buf_count = 7;
    414           m_sOutput_buff_property.actualcount = temp_out_buf_count;
    415           ioctl_msg.inputparam = (void*)&m_sOutput_buff_property;
    416           ioctl_msg.outputparam = NULL;
    417           if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    418           {
    419             DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed");
    420             return false;
    421           }
    422 
    423           if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
    424            (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount))
    425           {
    426             m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
    427             ioctl_msg.inputparam = (void*)&m_sInput_buff_property;
    428             ioctl_msg.outputparam = NULL;
    429             if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    430             {
    431               DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed");
    432               return false;
    433             }
    434           }
    435           if(m_sInput_buff_property.datasize != portDefn->nBufferSize)
    436           {
    437             DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u],"
    438                               "Driver's updated i/p bufsize = %u", portDefn->nBufferSize,
    439                               m_sInput_buff_property.datasize);
    440           }
    441           m_level_set = false;
    442           if(venc_set_profile_level(0, 0))
    443           {
    444             DEBUG_PRINT_HIGH("\n %s(): Dynamic Profile/Level setting success",
    445                 __func__);
    446           }
    447         }
    448         else
    449         {
    450           if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
    451            (m_sInput_buff_property.actualcount <= portDefn->nBufferCountActual) &&
    452             (m_sInput_buff_property.datasize == portDefn->nBufferSize))
    453           {
    454             m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
    455             ioctl_msg.inputparam = (void*)&m_sInput_buff_property;
    456             ioctl_msg.outputparam = NULL;
    457             if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    458             {
    459               DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_INPUT_BUFFER_REQ failed");
    460               return false;
    461             }
    462           }
    463           else
    464           {
    465             DEBUG_PRINT_ERROR("\nERROR: Setting Input buffer requirements failed");
    466             return false;
    467           }
    468         }
    469       }
    470       else if(portDefn->nPortIndex == PORT_INDEX_OUT)
    471       {
    472         if(!venc_set_encode_framerate(portDefn->format.video.xFramerate))
    473         {
    474           return false;
    475         }
    476 
    477         if(!venc_set_target_bitrate(portDefn->format.video.nBitrate))
    478         {
    479           return false;
    480         }
    481 
    482         if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
    483             &&
    484             (m_sOutput_buff_property.actualcount <= portDefn->nBufferCountActual)
    485             &&
    486             (m_sOutput_buff_property.datasize == portDefn->nBufferSize)
    487           )
    488         {
    489           m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
    490           ioctl_msg.inputparam = (void*)&m_sOutput_buff_property;
    491           ioctl_msg.outputparam = NULL;
    492           if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    493           {
    494             DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
    495             return false;
    496           }
    497         }
    498         else
    499         {
    500           DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed");
    501           return false;
    502         }
    503       }
    504       else
    505       {
    506         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
    507       }
    508       break;
    509     }
    510   case OMX_IndexParamVideoPortFormat:
    511     {
    512       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
    513       portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
    514       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n");
    515 
    516       if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
    517       {
    518         if(!venc_set_color_format(portFmt->eColorFormat))
    519         {
    520           return false;
    521         }
    522       }
    523       else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    524       {
    525         if(!venc_set_encode_framerate(portFmt->xFramerate))
    526         {
    527           return false;
    528         }
    529       }
    530       else
    531       {
    532         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
    533       }
    534       break;
    535     }
    536   case OMX_IndexParamVideoBitrate:
    537     {
    538       OMX_VIDEO_PARAM_BITRATETYPE* pParam;
    539       pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
    540       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n");
    541 
    542       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    543       {
    544         if(!venc_set_target_bitrate(pParam->nTargetBitrate))
    545         {
    546           DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed");
    547           return false;
    548         }
    549         if(!venc_set_ratectrl_cfg(pParam->eControlRate))
    550         {
    551           DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed");
    552           return false;
    553         }
    554       }
    555       else
    556       {
    557         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
    558       }
    559       break;
    560     }
    561   case OMX_IndexParamVideoMpeg4:
    562     {
    563       OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
    564       pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
    565       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n");
    566       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    567       {
    568         if(!venc_set_intra_period (pParam->nPFrames))
    569         {
    570           DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
    571           return false;
    572         }
    573 
    574         m_profile_set = false;
    575         m_level_set = false;
    576         if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
    577         {
    578           DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
    579           return false;
    580         }
    581       }
    582       else
    583       {
    584         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
    585       }
    586       break;
    587     }
    588   case OMX_IndexParamVideoH263:
    589     {
    590       OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
    591       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n");
    592       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    593       {
    594         if(venc_set_intra_period (pParam->nPFrames) == false)
    595         {
    596           DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
    597           return false;
    598         }
    599 
    600         m_profile_set = false;
    601         m_level_set = false;
    602         if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
    603         {
    604           DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
    605           return false;
    606         }
    607       }
    608       else
    609       {
    610         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263");
    611       }
    612       break;
    613     }
    614   case OMX_IndexParamVideoAvc:
    615     {
    616       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n");
    617       OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
    618       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    619       {
    620         if(venc_set_intra_period (pParam->nPFrames) == false)
    621         {
    622           DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
    623           return false;
    624         }
    625         DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n",
    626             pParam->eProfile,pParam->eLevel);
    627 
    628         m_profile_set = false;
    629         m_level_set = false;
    630         if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel))
    631         {
    632           DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
    633           return false;
    634         }
    635       }
    636       else
    637       {
    638         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
    639       }
    640       //TBD, lot of other variables to be updated, yet to decide
    641       break;
    642     }
    643   case OMX_IndexParamVideoProfileLevelCurrent:
    644     {
    645       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n");
    646       OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
    647       (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
    648       if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    649       {
    650         m_profile_set = false;
    651         m_level_set = false;
    652         if(!venc_set_profile_level (profile_level->eProfile,
    653                                    profile_level->eLevel))
    654         {
    655           DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
    656           return false;
    657         }
    658       }
    659       else
    660       {
    661         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
    662       }
    663       break;
    664     }
    665   case OMX_IndexParamVideoQuantization:
    666     {
    667       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n");
    668       OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
    669         (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
    670       if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    671       {
    672         if(venc_set_session_qp (session_qp->nQpI,
    673                                 session_qp->nQpP) == false)
    674         {
    675           DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed");
    676           return false;
    677         }
    678       }
    679       else
    680       {
    681         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
    682       }
    683       break;
    684     }
    685   case OMX_IndexParamVideoSliceFMO:
    686     {
    687       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoSliceFMO\n");
    688       OMX_VIDEO_PARAM_AVCSLICEFMO *avc_slice_fmo =
    689         (OMX_VIDEO_PARAM_AVCSLICEFMO*)paramData;
    690       DEBUG_PRINT_LOW("\n portindex = %u", avc_slice_fmo->nPortIndex);
    691       if(avc_slice_fmo->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    692       {
    693         if(venc_set_multislice_cfg(avc_slice_fmo->eSliceMode) == false)
    694         {
    695           DEBUG_PRINT_ERROR("\nERROR: Setting Multislice cfg failed");
    696           return false;
    697         }
    698       }
    699       else
    700       {
    701         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for Multislice cfg");
    702       }
    703       break;
    704     }
    705   default:
    706 	  DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u",
    707       index);
    708     break;
    709     //case
    710   }
    711 
    712   return true;
    713 }
    714 
    715 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
    716 {
    717   venc_ioctl_msg ioctl_msg = {NULL,NULL};
    718   DEBUG_PRINT_LOW("\n Inside venc_set_config");
    719 
    720   switch(index)
    721   {
    722   case OMX_IndexConfigVideoBitrate:
    723     {
    724       OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
    725         configData;
    726       DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate");
    727       if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
    728       {
    729         if(venc_set_target_bitrate(bit_rate->nEncodeBitrate) == false)
    730         {
    731           DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed");
    732           return false;
    733         }
    734       }
    735       else
    736       {
    737         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
    738       }
    739       break;
    740     }
    741   case OMX_IndexConfigVideoFramerate:
    742     {
    743       OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
    744         configData;
    745       DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate");
    746       if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
    747       {
    748         if(venc_set_encode_framerate(frame_rate->xEncodeFramerate) == false)
    749         {
    750           DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
    751           return false;
    752         }
    753       }
    754       else
    755       {
    756         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
    757       }
    758       break;
    759     }
    760   case OMX_IndexConfigVideoIntraVOPRefresh:
    761     {
    762       OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
    763         configData;
    764       DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
    765       if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
    766       {
    767         if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false)
    768         {
    769           DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
    770           return false;
    771         }
    772       }
    773       else
    774       {
    775         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
    776       }
    777       break;
    778     }
    779   default:
    780     DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index);
    781     break;
    782   }
    783 
    784   return true;
    785 }
    786 
    787 unsigned venc_dev::venc_stop( void)
    788 {
    789   return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL);
    790 }
    791 
    792 unsigned venc_dev::venc_pause(void)
    793 {
    794   return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL);
    795 }
    796 
    797 unsigned venc_dev::venc_resume(void)
    798 {
    799   return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ;
    800 }
    801 
    802 unsigned venc_dev::venc_start(void)
    803 {
    804   DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start",
    805         __func__);
    806   if (!venc_set_profile_level(0, 0))
    807   {
    808     DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET",
    809       __func__);
    810   }
    811   else
    812   {
    813     DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET",
    814       __func__, codec_profile.profile, profile_level.level);
    815   }
    816 
    817   return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
    818 }
    819 
    820 unsigned venc_dev::venc_flush( unsigned port)
    821 {
    822   struct venc_ioctl_msg ioctl_msg;
    823   struct venc_bufferflush buffer_index;
    824 
    825   if(port == PORT_INDEX_IN)
    826   {
    827     buffer_index.flush_mode = VEN_FLUSH_INPUT;
    828     ioctl_msg.inputparam = (void*)&buffer_index;
    829     ioctl_msg.outputparam = NULL;
    830 
    831     return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
    832   }
    833   else if(port == PORT_INDEX_OUT)
    834   {
    835     buffer_index.flush_mode = VEN_FLUSH_OUTPUT;
    836     ioctl_msg.inputparam = (void*)&buffer_index;
    837     ioctl_msg.outputparam = NULL;
    838     return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
    839   }
    840   else
    841   {
    842     return -1;
    843   }
    844 }
    845 
    846 //allocating I/P memory from pmem and register with the device
    847 
    848 
    849 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port)
    850 {
    851   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    852   struct pmem *pmem_tmp;
    853   struct venc_bufferpayload dev_buffer = {0};
    854 
    855   pmem_tmp = (struct pmem *)buf_addr;
    856 
    857   DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
    858 
    859   if(port == PORT_INDEX_IN)
    860   {
    861     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    862     dev_buffer.fd  = pmem_tmp->fd;
    863     dev_buffer.maped_size = pmem_tmp->size;
    864     dev_buffer.nsize = pmem_tmp->size;
    865     dev_buffer.offset = pmem_tmp->offset;
    866     ioctl_msg.inputparam  = (void*)&dev_buffer;
    867     ioctl_msg.outputparam = NULL;
    868 
    869     DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
    870                 dev_buffer.pbuffer, \
    871                 dev_buffer.fd, \
    872                 dev_buffer.offset, \
    873                 dev_buffer.maped_size);
    874 
    875     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0)
    876     {
    877       DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed ");
    878       return false;
    879     }
    880   }
    881   else if(port == PORT_INDEX_OUT)
    882   {
    883     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    884     dev_buffer.fd  = pmem_tmp->fd;
    885     dev_buffer.nsize = pmem_tmp->size;
    886     dev_buffer.maped_size = pmem_tmp->size;
    887     dev_buffer.offset = pmem_tmp->offset;
    888     ioctl_msg.inputparam  = (void*)&dev_buffer;
    889     ioctl_msg.outputparam = NULL;
    890 
    891     DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
    892                 dev_buffer.pbuffer, \
    893                 dev_buffer.fd, \
    894                 dev_buffer.offset, \
    895                 dev_buffer.maped_size);
    896 
    897     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0)
    898     {
    899       DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed ");
    900       return false;
    901     }
    902   }
    903   else
    904   {
    905     DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index ");
    906     return false;
    907   }
    908 
    909   return true;
    910 }
    911 
    912 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
    913 {
    914   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    915   struct pmem *pmem_tmp;
    916   struct venc_bufferpayload dev_buffer = {0};
    917 
    918   pmem_tmp = (struct pmem *)buf_addr;
    919 
    920   DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
    921 
    922   if(port == PORT_INDEX_IN)
    923   {
    924     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    925     dev_buffer.fd  = pmem_tmp->fd;
    926     dev_buffer.maped_size = pmem_tmp->size;
    927     dev_buffer.nsize = pmem_tmp->size;
    928     dev_buffer.offset = pmem_tmp->offset;
    929     ioctl_msg.inputparam  = (void*)&dev_buffer;
    930     ioctl_msg.outputparam = NULL;
    931 
    932     DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
    933                 dev_buffer.pbuffer, \
    934                 dev_buffer.fd, \
    935                 dev_buffer.offset, \
    936                 dev_buffer.maped_size);
    937 
    938     if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0)
    939     {
    940       DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed ");
    941       return false;
    942     }
    943   }
    944   else if(port == PORT_INDEX_OUT)
    945   {
    946     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
    947     dev_buffer.fd  = pmem_tmp->fd;
    948     dev_buffer.nsize = pmem_tmp->size;
    949     dev_buffer.maped_size = pmem_tmp->size;
    950     dev_buffer.offset = pmem_tmp->offset;
    951     ioctl_msg.inputparam  = (void*)&dev_buffer;
    952     ioctl_msg.outputparam = NULL;
    953 
    954     DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
    955                 dev_buffer.pbuffer, \
    956                 dev_buffer.fd, \
    957                 dev_buffer.offset, \
    958                 dev_buffer.maped_size);
    959 
    960     if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0)
    961     {
    962       DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed ");
    963       return false;
    964     }
    965   }
    966   else
    967   {
    968     DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index ");
    969     return false;
    970   }
    971 
    972   return true;
    973 }
    974 
    975 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf)
    976 {
    977   struct venc_buffer frameinfo;
    978   struct pmem *temp_buffer;
    979   struct venc_ioctl_msg ioctl_msg;
    980   struct OMX_BUFFERHEADERTYPE *bufhdr;
    981 
    982   if(buffer == NULL)
    983   {
    984     DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL");
    985     return false;
    986   }
    987   bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
    988 
    989   DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen);
    990 
    991   if(pmem_data_buf)
    992   {
    993     DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
    994     frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
    995   }
    996   else
    997   {
    998     DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
    999     frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
   1000   }
   1001 
   1002   frameinfo.clientdata = (void *) buffer;
   1003   frameinfo.size = bufhdr->nFilledLen;
   1004   frameinfo.len = bufhdr->nFilledLen;
   1005   frameinfo.flags = bufhdr->nFlags;
   1006   frameinfo.offset = bufhdr->nOffset;
   1007   frameinfo.timestamp = bufhdr->nTimeStamp;
   1008   DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp);
   1009   ioctl_msg.inputparam = &frameinfo;
   1010   ioctl_msg.outputparam = NULL;
   1011 
   1012   DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
   1013       bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
   1014   if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
   1015   {
   1016     /*Generate an async error and move to invalid state*/
   1017     return false;
   1018   }
   1019 
   1020   return true;
   1021 }
   1022 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf)
   1023 {
   1024   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1025   struct pmem *temp_buffer = NULL;
   1026   struct venc_buffer  frameinfo;
   1027   struct OMX_BUFFERHEADERTYPE *bufhdr;
   1028 
   1029   if(buffer == NULL)
   1030   {
   1031     return false;
   1032   }
   1033   bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
   1034 
   1035   if(pmem_data_buf)
   1036   {
   1037     DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
   1038     frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
   1039   }
   1040   else
   1041   {
   1042     DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
   1043     frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
   1044   }
   1045 
   1046   frameinfo.clientdata = buffer;
   1047   frameinfo.size = bufhdr->nAllocLen;
   1048   frameinfo.flags = bufhdr->nFlags;
   1049   frameinfo.offset = bufhdr->nOffset;
   1050 
   1051   ioctl_msg.inputparam = &frameinfo;
   1052   ioctl_msg.outputparam = NULL;
   1053   DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
   1054       bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
   1055   if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
   1056   {
   1057     DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
   1058     return false;
   1059   }
   1060 
   1061   return true;
   1062 }
   1063 
   1064 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp)
   1065 {
   1066   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1067   struct venc_sessionqp qp = {0, 0};
   1068   DEBUG_PRINT_LOW("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp,
   1069     p_frame_qp);
   1070 
   1071   qp.iframeqp = i_frame_qp;
   1072   qp.pframqp = p_frame_qp;
   1073 
   1074   ioctl_msg.inputparam = (void*)&qp;
   1075   ioctl_msg.outputparam = NULL;
   1076   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0)
   1077   {
   1078     DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed");
   1079     return false;
   1080   }
   1081 
   1082   session_qp.iframeqp = i_frame_qp;
   1083   session_qp.pframqp = p_frame_qp;
   1084 
   1085   return true;
   1086 }
   1087 
   1088 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
   1089 {
   1090   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1091   struct venc_profile requested_profile;
   1092   struct ven_profilelevel requested_level;
   1093   unsigned const int *profile_tbl = NULL;
   1094   unsigned long mb_per_frame = 0, mb_per_sec = 0;
   1095   DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d",
   1096     eProfile, eLevel);
   1097 
   1098   if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set)
   1099   {
   1100     DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start");
   1101     return true;
   1102   }
   1103 
   1104   DEBUG_PRINT_LOW("\n Validating Profile/Level from table");
   1105   if(!venc_validate_profile_level(&eProfile, &eLevel))
   1106   {
   1107     DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed");
   1108     return false;
   1109   }
   1110 
   1111   if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
   1112   {
   1113     DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
   1114       "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
   1115       OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
   1116     if(eProfile == OMX_VIDEO_MPEG4ProfileSimple)
   1117     {
   1118       requested_profile.profile = VEN_PROFILE_MPEG4_SP;
   1119       profile_tbl = (unsigned int const *)
   1120           (&mpeg4_profile_level_table[MPEG4_SP_START]);
   1121       profile_tbl += MPEG4_720P_LEVEL*5;
   1122     }
   1123     else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
   1124     {
   1125       requested_profile.profile = VEN_PROFILE_MPEG4_ASP;
   1126       profile_tbl = (unsigned int const *)
   1127           (&mpeg4_profile_level_table[MPEG4_ASP_START]);
   1128       profile_tbl += MPEG4_720P_LEVEL*5;
   1129     }
   1130     else
   1131     {
   1132       DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u",
   1133         eProfile);
   1134       return false;
   1135     }
   1136 
   1137     DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
   1138       "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
   1139       "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
   1140       OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
   1141 
   1142     switch(eLevel)
   1143     {
   1144     case OMX_VIDEO_MPEG4Level0:
   1145       requested_level.level = VEN_LEVEL_MPEG4_0;
   1146       break;
   1147     case OMX_VIDEO_MPEG4Level1:
   1148       requested_level.level = VEN_LEVEL_MPEG4_1;
   1149       break;
   1150     case OMX_VIDEO_MPEG4Level2:
   1151       requested_level.level = VEN_LEVEL_MPEG4_2;
   1152       break;
   1153     case OMX_VIDEO_MPEG4Level3:
   1154       requested_level.level = VEN_LEVEL_MPEG4_3;
   1155       break;
   1156     case OMX_VIDEO_MPEG4Level4a:
   1157       requested_level.level = VEN_LEVEL_MPEG4_4;
   1158       break;
   1159     case OMX_VIDEO_MPEG4Level5:
   1160       mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
   1161                         ((m_sVenc_cfg.input_width + 15) >> 4);
   1162       mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den);
   1163 
   1164       if((mb_per_frame >= profile_tbl[0]) &&
   1165          (mb_per_sec >= profile_tbl[1]))
   1166       {
   1167         DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution");
   1168         requested_level.level = VEN_LEVEL_MPEG4_6;
   1169       }
   1170       else
   1171       {
   1172         DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution");
   1173         requested_level.level = VEN_LEVEL_MPEG4_5;
   1174       }
   1175       break;
   1176     default:
   1177       return false;
   1178       // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
   1179       break;
   1180     }
   1181   }
   1182   else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
   1183   {
   1184     if(eProfile == OMX_VIDEO_H263ProfileBaseline)
   1185     {
   1186       requested_profile.profile = VEN_PROFILE_H263_BASELINE;
   1187     }
   1188     else
   1189     {
   1190       DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u",
   1191         requested_profile.profile);
   1192       return false;
   1193     }
   1194     //profile level
   1195     switch(eLevel)
   1196     {
   1197     case OMX_VIDEO_H263Level10:
   1198       requested_level.level = VEN_LEVEL_H263_10;
   1199       break;
   1200     case OMX_VIDEO_H263Level20:
   1201       requested_level.level = VEN_LEVEL_H263_20;
   1202       break;
   1203     case OMX_VIDEO_H263Level30:
   1204       requested_level.level = VEN_LEVEL_H263_30;
   1205       break;
   1206     case OMX_VIDEO_H263Level40:
   1207       requested_level.level = VEN_LEVEL_H263_40;
   1208       break;
   1209     case OMX_VIDEO_H263Level45:
   1210       requested_level.level = VEN_LEVEL_H263_45;
   1211       break;
   1212     case OMX_VIDEO_H263Level50:
   1213       requested_level.level = VEN_LEVEL_H263_50;
   1214       break;
   1215     case OMX_VIDEO_H263Level60:
   1216       requested_level.level = VEN_LEVEL_H263_60;
   1217       break;
   1218     case OMX_VIDEO_H263Level70:
   1219       requested_level.level = VEN_LEVEL_H263_70;
   1220       break;
   1221     default:
   1222       return false;
   1223       break;
   1224     }
   1225   }
   1226   else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
   1227   {
   1228     if(eProfile == OMX_VIDEO_AVCProfileBaseline)
   1229     {
   1230       requested_profile.profile = VEN_PROFILE_H264_BASELINE;
   1231     }
   1232     else if(eProfile == OMX_VIDEO_AVCProfileMain)
   1233     {
   1234       requested_profile.profile = VEN_PROFILE_H264_MAIN;
   1235     }
   1236     else if(eProfile == OMX_VIDEO_AVCProfileHigh)
   1237     {
   1238       requested_profile.profile = VEN_PROFILE_H264_HIGH;
   1239     }
   1240     else
   1241     {
   1242       DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u",
   1243         requested_profile.profile);
   1244       return false;
   1245     }
   1246     //profile level
   1247     switch(eLevel)
   1248     {
   1249     case OMX_VIDEO_AVCLevel1:
   1250       requested_level.level = VEN_LEVEL_H264_1;
   1251       break;
   1252     case OMX_VIDEO_AVCLevel1b:
   1253       requested_level.level = VEN_LEVEL_H264_1b;
   1254       break;
   1255     case OMX_VIDEO_AVCLevel11:
   1256       requested_level.level = VEN_LEVEL_H264_1p1;
   1257       break;
   1258     case OMX_VIDEO_AVCLevel12:
   1259       requested_level.level = VEN_LEVEL_H264_1p2;
   1260       break;
   1261     case OMX_VIDEO_AVCLevel13:
   1262       requested_level.level = VEN_LEVEL_H264_1p3;
   1263       break;
   1264     case OMX_VIDEO_AVCLevel2:
   1265       requested_level.level = VEN_LEVEL_H264_2;
   1266       break;
   1267     case OMX_VIDEO_AVCLevel21:
   1268       requested_level.level = VEN_LEVEL_H264_2p1;
   1269       break;
   1270     case OMX_VIDEO_AVCLevel22:
   1271       requested_level.level = VEN_LEVEL_H264_2p2;
   1272       break;
   1273     case OMX_VIDEO_AVCLevel3:
   1274       requested_level.level = VEN_LEVEL_H264_3;
   1275       break;
   1276     case OMX_VIDEO_AVCLevel31:
   1277       requested_level.level = VEN_LEVEL_H264_3p1;
   1278       break;
   1279     default :
   1280       return false;
   1281       break;
   1282     }
   1283   }
   1284 
   1285   if(!m_profile_set)
   1286   {
   1287     ioctl_msg.inputparam = (void*)&requested_profile;
   1288     ioctl_msg.outputparam = NULL;
   1289     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0)
   1290     {
   1291       DEBUG_PRINT_LOW("\nERROR: Request for setting profile failed");
   1292       return false;
   1293     }
   1294     codec_profile.profile = requested_profile.profile;
   1295     m_profile_set = true;
   1296   }
   1297 
   1298   if(!m_level_set)
   1299   {
   1300     ioctl_msg.inputparam = (void*)&requested_level;
   1301     ioctl_msg.outputparam = NULL;
   1302     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0)
   1303     {
   1304       DEBUG_PRINT_LOW("\nERROR: Request for setting profile level failed");
   1305       return false;
   1306     }
   1307     profile_level.level = requested_level.level;
   1308     m_level_set = true;
   1309   }
   1310 
   1311   return true;
   1312 }
   1313 
   1314 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames)
   1315 {
   1316   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1317   struct venc_intraperiod intra_period;
   1318 
   1319   DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u",
   1320     nPFrames);
   1321   intra_period.num_pframes = nPFrames;
   1322   ioctl_msg.inputparam = (void*)&intra_period;
   1323   ioctl_msg.outputparam = NULL;
   1324   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0)
   1325   {
   1326     DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
   1327     return false;
   1328   }
   1329 
   1330   return true;
   1331 }
   1332 
   1333 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate)
   1334 {
   1335   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   1336   struct venc_targetbitrate bit_rate;
   1337 
   1338   DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u",
   1339     nTargetBitrate);
   1340   bit_rate.target_bitrate = nTargetBitrate ;
   1341   ioctl_msg.inputparam = (void*)&bit_rate;
   1342   ioctl_msg.outputparam = NULL;
   1343   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0)
   1344   {
   1345     DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed");
   1346     return false;
   1347   }
   1348   m_sVenc_cfg.targetbitrate = nTargetBitrate;
   1349   m_level_set = false;
   1350   if(venc_set_profile_level(0, 0))
   1351   {
   1352     DEBUG_PRINT_HIGH("\n %s(): Dynamic Profile/Level setting success",
   1353         __func__);
   1354   }
   1355 
   1356   return true;
   1357 }
   1358 
   1359 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate)
   1360 {
   1361   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   1362   struct venc_framerate frame_rate;
   1363 
   1364   DEBUG_PRINT_LOW("\n venc_set_encode_framerate: framerate(Q16) = %u",
   1365     encode_framerate);
   1366   frame_rate.fps_numerator = 30;
   1367   if((encode_framerate >> 16)== 30)
   1368   {
   1369     frame_rate.fps_denominator = 1;
   1370   }
   1371   else if((encode_framerate >>16) == 15)
   1372   {
   1373     frame_rate.fps_denominator = 2;
   1374   }
   1375   else if((encode_framerate >> 16)== 7.5)
   1376   {
   1377     frame_rate.fps_denominator = 4;
   1378   }
   1379   else
   1380   {
   1381     frame_rate.fps_denominator = 1;
   1382   }
   1383 
   1384   ioctl_msg.inputparam = (void*)&frame_rate;
   1385   ioctl_msg.outputparam = NULL;
   1386   if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE,
   1387       (void*)&ioctl_msg) < 0)
   1388   {
   1389     DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed");
   1390     return false;
   1391   }
   1392 
   1393   m_sVenc_cfg.fps_den = frame_rate.fps_denominator;
   1394   m_sVenc_cfg.fps_num = frame_rate.fps_numerator;
   1395   m_level_set = false;
   1396   if(venc_set_profile_level(0, 0))
   1397   {
   1398     DEBUG_PRINT_HIGH("\n %s(): Dynamic Profile/Level setting success",
   1399         __func__);
   1400   }
   1401 
   1402   return true;
   1403 }
   1404 
   1405 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
   1406 {
   1407   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   1408   DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format);
   1409 
   1410   if(color_format == OMX_COLOR_FormatYUV420SemiPlanar)
   1411   {
   1412     m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
   1413   }
   1414   else
   1415   {
   1416     DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format);
   1417     m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
   1418     DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set");
   1419   }
   1420   ioctl_msg.inputparam = (void*)&m_sVenc_cfg;
   1421   ioctl_msg.outputparam = NULL;
   1422   if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0)
   1423   {
   1424     DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed");
   1425     return false;
   1426   }
   1427   return true;
   1428 }
   1429 
   1430 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
   1431 {
   1432   DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
   1433   if(intra_vop_refresh == OMX_TRUE)
   1434   {
   1435     if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0)
   1436     {
   1437       DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed");
   1438       return false;
   1439     }
   1440   }
   1441   else
   1442   {
   1443     DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect");
   1444   }
   1445   return true;
   1446 }
   1447 
   1448 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
   1449 {
   1450   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1451   bool status = true;
   1452 
   1453   //rate control
   1454   switch(eControlRate)
   1455   {
   1456   case OMX_Video_ControlRateDisable:
   1457     rate_ctrl.rcmode = VEN_RC_OFF;
   1458     break;
   1459   case OMX_Video_ControlRateVariableSkipFrames:
   1460     rate_ctrl.rcmode = VEN_RC_VBR_VFR;
   1461     break;
   1462   case OMX_Video_ControlRateVariable:
   1463     rate_ctrl.rcmode = VEN_RC_VBR_CFR;
   1464     break;
   1465   case OMX_Video_ControlRateConstantSkipFrames:
   1466     rate_ctrl.rcmode = VEN_RC_CBR_VFR;
   1467     break;
   1468   default:
   1469     status = false;
   1470     break;
   1471   }
   1472 
   1473   if(status)
   1474   {
   1475     ioctl_msg.inputparam = (void*)&rate_ctrl;
   1476     ioctl_msg.outputparam = NULL;
   1477     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0)
   1478     {
   1479       DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed");
   1480       status = false;
   1481     }
   1482   }
   1483   return status;
   1484 }
   1485 
   1486 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
   1487 {
   1488   bool status = true;
   1489   if(eProfile == NULL || eLevel == NULL)
   1490   {
   1491     return false;
   1492   }
   1493 
   1494   if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
   1495   {
   1496     switch(codec_profile.profile)
   1497     {
   1498     case VEN_PROFILE_MPEG4_SP:
   1499       *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   1500       break;
   1501     case VEN_PROFILE_MPEG4_ASP:
   1502       *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   1503       break;
   1504     default:
   1505       *eProfile = OMX_VIDEO_MPEG4ProfileMax;
   1506       status = false;
   1507       break;
   1508     }
   1509 
   1510     if(!status)
   1511     {
   1512       return status;
   1513     }
   1514 
   1515     //profile level
   1516     switch(profile_level.level)
   1517     {
   1518     case VEN_LEVEL_MPEG4_0:
   1519       *eLevel = OMX_VIDEO_MPEG4Level0;
   1520       break;
   1521     case VEN_LEVEL_MPEG4_1:
   1522       *eLevel = OMX_VIDEO_MPEG4Level1;
   1523       break;
   1524     case VEN_LEVEL_MPEG4_2:
   1525       *eLevel = OMX_VIDEO_MPEG4Level2;
   1526       break;
   1527     case VEN_LEVEL_MPEG4_3:
   1528       *eLevel = OMX_VIDEO_MPEG4Level3;
   1529       break;
   1530     case VEN_LEVEL_MPEG4_4:
   1531       *eLevel = OMX_VIDEO_MPEG4Level4a;
   1532       break;
   1533     case VEN_LEVEL_MPEG4_5:
   1534     case VEN_LEVEL_MPEG4_6:
   1535       *eLevel = OMX_VIDEO_MPEG4Level5;
   1536       break;
   1537     default:
   1538       *eLevel = OMX_VIDEO_MPEG4LevelMax;
   1539       status =  false;
   1540       break;
   1541     }
   1542   }
   1543   else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
   1544   {
   1545     if(codec_profile.profile == VEN_PROFILE_H263_BASELINE)
   1546     {
   1547       *eProfile = OMX_VIDEO_H263ProfileBaseline;
   1548     }
   1549     else
   1550     {
   1551       *eProfile = OMX_VIDEO_H263ProfileMax;
   1552       return false;
   1553     }
   1554     switch(profile_level.level)
   1555     {
   1556     case VEN_LEVEL_H263_10:
   1557       *eLevel = OMX_VIDEO_H263Level10;
   1558       break;
   1559     case VEN_LEVEL_H263_20:
   1560       *eLevel = OMX_VIDEO_H263Level20;
   1561       break;
   1562     case VEN_LEVEL_H263_30:
   1563       *eLevel = OMX_VIDEO_H263Level30;
   1564       break;
   1565     case VEN_LEVEL_H263_40:
   1566       *eLevel = OMX_VIDEO_H263Level40;
   1567       break;
   1568     case VEN_LEVEL_H263_45:
   1569       *eLevel = OMX_VIDEO_H263Level45;
   1570       break;
   1571     case VEN_LEVEL_H263_50:
   1572       *eLevel = OMX_VIDEO_H263Level50;
   1573       break;
   1574     case VEN_LEVEL_H263_60:
   1575       *eLevel = OMX_VIDEO_H263Level60;
   1576       break;
   1577     case VEN_LEVEL_H263_70:
   1578       *eLevel = OMX_VIDEO_H263Level70;
   1579       break;
   1580     default:
   1581       *eLevel = OMX_VIDEO_H263LevelMax;
   1582       status = false;
   1583       break;
   1584     }
   1585   }
   1586   else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
   1587   {
   1588     switch(codec_profile.profile)
   1589     {
   1590     case VEN_PROFILE_H264_BASELINE:
   1591       *eProfile = OMX_VIDEO_AVCProfileBaseline;
   1592       break;
   1593     case VEN_PROFILE_H264_MAIN:
   1594       *eProfile = OMX_VIDEO_AVCProfileMain;
   1595       break;
   1596     case VEN_PROFILE_H264_HIGH:
   1597       *eProfile = OMX_VIDEO_AVCProfileHigh;
   1598       break;
   1599     default:
   1600       *eProfile = OMX_VIDEO_AVCProfileMax;
   1601       status = false;
   1602       break;
   1603     }
   1604 
   1605     if(!status)
   1606     {
   1607       return status;
   1608     }
   1609 
   1610     switch(profile_level.level)
   1611     {
   1612     case VEN_LEVEL_H264_1:
   1613       *eLevel = OMX_VIDEO_AVCLevel1;
   1614       break;
   1615     case VEN_LEVEL_H264_1b:
   1616       *eLevel = OMX_VIDEO_AVCLevel1b;
   1617       break;
   1618     case VEN_LEVEL_H264_1p1:
   1619       *eLevel = OMX_VIDEO_AVCLevel11;
   1620       break;
   1621     case VEN_LEVEL_H264_1p2:
   1622       *eLevel = OMX_VIDEO_AVCLevel12;
   1623       break;
   1624     case VEN_LEVEL_H264_1p3:
   1625       *eLevel = OMX_VIDEO_AVCLevel13;
   1626       break;
   1627     case VEN_LEVEL_H264_2:
   1628       *eLevel = OMX_VIDEO_AVCLevel2;
   1629       break;
   1630     case VEN_LEVEL_H264_2p1:
   1631       *eLevel = OMX_VIDEO_AVCLevel21;
   1632       break;
   1633     case VEN_LEVEL_H264_2p2:
   1634       *eLevel = OMX_VIDEO_AVCLevel22;
   1635       break;
   1636     case VEN_LEVEL_H264_3:
   1637       *eLevel = OMX_VIDEO_AVCLevel3;
   1638       break;
   1639     case VEN_LEVEL_H264_3p1:
   1640       *eLevel = OMX_VIDEO_AVCLevel31;
   1641       break;
   1642     default :
   1643       *eLevel = OMX_VIDEO_AVCLevelMax;
   1644       status = false;
   1645       break;
   1646     }
   1647   }
   1648   return status;
   1649 }
   1650 
   1651 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
   1652 {
   1653   OMX_U32 new_profile = 0, new_level = 0;
   1654   unsigned const int *profile_tbl = NULL;
   1655   OMX_U32 mb_per_frame, mb_per_sec;
   1656   bool profile_level_found = false;
   1657 
   1658   DEBUG_PRINT_LOW("\n Init profile table for respective codec");
   1659   //validate the ht,width,fps,bitrate and set the appropriate profile and level
   1660   if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
   1661   {
   1662       if(*eProfile == 0)
   1663       {
   1664         if(!m_profile_set)
   1665         {
   1666           *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   1667         }
   1668         else
   1669         {
   1670           switch(codec_profile.profile)
   1671           {
   1672           case VEN_PROFILE_MPEG4_ASP:
   1673               *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   1674             break;
   1675           case VEN_PROFILE_MPEG4_SP:
   1676               *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   1677             break;
   1678           default:
   1679             DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
   1680             return false;
   1681           }
   1682         }
   1683       }
   1684 
   1685       if(*eLevel == 0 && !m_level_set)
   1686       {
   1687         *eLevel = OMX_VIDEO_MPEG4LevelMax;
   1688       }
   1689 
   1690       if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple)
   1691       {
   1692         profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
   1693       }
   1694       else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
   1695       {
   1696         profile_tbl = (unsigned int const *)
   1697           (&mpeg4_profile_level_table[MPEG4_ASP_START]);
   1698       }
   1699       else
   1700       {
   1701         DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile);
   1702         return false;
   1703       }
   1704   }
   1705   else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
   1706   {
   1707       if(*eProfile == 0)
   1708       {
   1709         if(!m_profile_set)
   1710         {
   1711           *eProfile = OMX_VIDEO_AVCProfileBaseline;
   1712         }
   1713         else
   1714         {
   1715           switch(codec_profile.profile)
   1716           {
   1717           case VEN_PROFILE_H264_BASELINE:
   1718             *eProfile = OMX_VIDEO_AVCProfileBaseline;
   1719             break;
   1720           case VEN_PROFILE_H264_MAIN:
   1721             *eProfile = OMX_VIDEO_AVCProfileMain;
   1722             break;
   1723           case VEN_PROFILE_H264_HIGH:
   1724             *eProfile = OMX_VIDEO_AVCProfileHigh;
   1725             break;
   1726           default:
   1727             DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
   1728             return false;
   1729           }
   1730         }
   1731       }
   1732 
   1733       if(*eLevel == 0 && !m_level_set)
   1734       {
   1735         *eLevel = OMX_VIDEO_AVCLevelMax;
   1736       }
   1737 
   1738       if(*eProfile == OMX_VIDEO_AVCProfileBaseline)
   1739       {
   1740         profile_tbl = (unsigned int const *)h264_profile_level_table;
   1741       }
   1742       else if(*eProfile == OMX_VIDEO_AVCProfileHigh)
   1743       {
   1744         profile_tbl = (unsigned int const *)
   1745           (&h264_profile_level_table[H264_HP_START]);
   1746       }
   1747       else if(*eProfile == OMX_VIDEO_AVCProfileMain)
   1748       {
   1749         profile_tbl = (unsigned int const *)
   1750           (&h264_profile_level_table[H264_MP_START]);
   1751       }
   1752       else
   1753       {
   1754         DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile);
   1755         return false;
   1756       }
   1757   }
   1758   else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
   1759   {
   1760       if(*eProfile == 0)
   1761       {
   1762         if(!m_profile_set)
   1763         {
   1764           *eProfile = OMX_VIDEO_H263ProfileBaseline;
   1765         }
   1766         else
   1767         {
   1768           switch(codec_profile.profile)
   1769           {
   1770           case VEN_PROFILE_H263_BASELINE:
   1771             *eProfile = OMX_VIDEO_H263ProfileBaseline;
   1772             break;
   1773           default:
   1774             DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
   1775             return false;
   1776           }
   1777         }
   1778       }
   1779 
   1780       if(*eLevel == 0 && !m_level_set)
   1781       {
   1782         *eLevel = OMX_VIDEO_H263LevelMax;
   1783       }
   1784 
   1785       if(*eProfile == OMX_VIDEO_H263ProfileBaseline)
   1786       {
   1787         profile_tbl = (unsigned int const *)h263_profile_level_table;
   1788       }
   1789       else
   1790       {
   1791         DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile);
   1792         return false;
   1793       }
   1794   }
   1795   else
   1796   {
   1797     DEBUG_PRINT_LOW("\n Invalid codec type");
   1798     return false;
   1799   }
   1800 
   1801   mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
   1802                    ((m_sVenc_cfg.input_width + 15)>> 4);
   1803 
   1804   mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
   1805 
   1806   do{
   1807       if(mb_per_frame <= (int)profile_tbl[0])
   1808       {
   1809         if(mb_per_sec <= (int)profile_tbl[1])
   1810         {
   1811           if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2])
   1812           {
   1813               DEBUG_PRINT_LOW("\n Appropriate profile/level found \n");
   1814               new_level = (int)profile_tbl[3];
   1815               new_profile = (int)profile_tbl[4];
   1816               profile_level_found = true;
   1817               break;
   1818           }
   1819         }
   1820       }
   1821       profile_tbl = profile_tbl + 5;
   1822   }while(profile_tbl[0] != 0);
   1823 
   1824   if ((profile_level_found != true) || (new_profile != *eProfile)
   1825       || (new_level > *eLevel))
   1826   {
   1827     DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n");
   1828     return false;
   1829   }
   1830 
   1831   if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
   1832      || (*eLevel == OMX_VIDEO_H263LevelMax))
   1833   {
   1834     *eLevel = new_level;
   1835   }
   1836   DEBUG_PRINT_HIGH("%s: Returning with eProfile = %lu"
   1837       "Level = %lu", __func__, *eProfile, *eLevel);
   1838 
   1839   return true;
   1840 }
   1841 bool venc_dev::venc_set_multislice_cfg(OMX_VIDEO_AVCSLICEMODETYPE eSliceMode)
   1842 {
   1843   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   1844   bool status = true;
   1845   DEBUG_PRINT_LOW("\n %s(): eSliceMode = %u", __func__, eSliceMode);
   1846   switch(eSliceMode)
   1847   {
   1848   case OMX_VIDEO_SLICEMODE_AVCDefault:
   1849     DEBUG_PRINT_LOW("\n %s(): OMX_VIDEO_SLICEMODE_AVCDefault", __func__);
   1850     multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
   1851     multislice_cfg.mslice_size = 0;
   1852     break;
   1853   case OMX_VIDEO_SLICEMODE_AVCMBSlice:
   1854     DEBUG_PRINT_LOW("\n %s(): OMX_VIDEO_SLICEMODE_AVCMBSlice", __func__);
   1855     multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB;
   1856     multislice_cfg.mslice_size = ((m_sVenc_cfg.input_width/16) *
   1857       (m_sVenc_cfg.input_height/16))/2;
   1858     break;
   1859   case OMX_VIDEO_SLICEMODE_AVCByteSlice:
   1860     DEBUG_PRINT_LOW("\n %s(): OMX_VIDEO_SLICEMODE_AVCByteSlice", __func__);
   1861     multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
   1862     multislice_cfg.mslice_size = 1920;
   1863     break;
   1864   default:
   1865     DEBUG_PRINT_ERROR("\n %s(): Unsupported SliceMode = %u",__func__, eSliceMode);
   1866     status = false;
   1867     break;
   1868   }
   1869   DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
   1870     multislice_cfg.mslice_size);
   1871 
   1872   if(status)
   1873   {
   1874     ioctl_msg.inputparam = (void*)&multislice_cfg;
   1875     ioctl_msg.outputparam = NULL;
   1876     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0)
   1877     {
   1878       DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
   1879       status = false;
   1880     }
   1881   }
   1882   return status;
   1883 }
   1884