Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of 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 <sys/prctl.h>
     31 #include<unistd.h>
     32 #include <fcntl.h>
     33 #include "video_encoder_device.h"
     34 #include "omx_video_encoder.h"
     35 #include <media/hardware/HardwareAPI.h>
     36 #ifdef USE_ION
     37 #include <linux/msm_ion.h>
     38 #else
     39 #include <linux/android_pmem.h>
     40 #endif
     41 
     42 #define MPEG4_SP_START 0
     43 #define MPEG4_ASP_START (MPEG4_SP_START + 8)
     44 #define MPEG4_720P_LEVEL 6
     45 #define H263_BP_START 0
     46 #define H264_BP_START 0
     47 #define H264_HP_START (H264_BP_START + 13)
     48 #define H264_MP_START (H264_BP_START + 26)
     49 
     50 /* MPEG4 profile and level table*/
     51 static const unsigned int mpeg4_profile_level_table[][5]=
     52 {
     53     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
     54     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
     55     {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
     56     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
     57     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
     58     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
     59     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     60     {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     61     {0,0,0,0,0},
     62 
     63     {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     64     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     65     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     66     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     67     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     68     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     69     {0,0,0,0,0},
     70 };
     71 
     72 /* H264 profile and level table*/
     73 static const unsigned int h264_profile_level_table[][5]=
     74 {
     75      /*max mb per frame, max mb per sec, max bitrate, level, profile*/
     76     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
     77     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
     78     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
     79     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
     80     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
     81     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
     82     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
     83     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
     84     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
     85     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
     86     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
     87     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
     88     {0,0,0,0,0},
     89 
     90     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
     91     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
     92     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
     93     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
     94     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
     95     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
     96     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
     97     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
     98     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
     99     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
    100     {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
    101     {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
    102     {0,0,0,0,0},
    103 
    104     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
    105     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
    106     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
    107     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
    108     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
    109     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
    110     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
    111     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
    112     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
    113     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
    114     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
    115     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
    116     {0,0,0,0,0}
    117 
    118 };
    119 
    120 /* H263 profile and level table*/
    121 static const unsigned int h263_profile_level_table[][5]=
    122 {
    123     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    124     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
    125     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
    126     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
    127     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
    128     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
    129     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
    130     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
    131     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    132     {0,0,0,0,0}
    133 };
    134 
    135 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    136 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    137 
    138 #ifdef INPUT_BUFFER_LOG
    139 FILE *inputBufferFile1;
    140 char inputfilename [] = "/data/input.yuv";
    141 #endif
    142 #ifdef OUTPUT_BUFFER_LOG
    143 FILE *outputBufferFile1;
    144 char outputfilename [] = "/data/output-bitstream.\0\0\0\0";
    145 #endif
    146 //constructor
    147 venc_dev::venc_dev(class omx_venc *venc_class)
    148 {
    149   m_max_allowed_bitrate_check = false;
    150   m_eLevel = 0;
    151   m_eProfile = 0;
    152   pthread_mutex_init(&loaded_start_stop_mlock, NULL);
    153   pthread_cond_init (&loaded_start_stop_cond, NULL);
    154   venc_encoder = reinterpret_cast<omx_venc*>(venc_class);
    155   DEBUG_PRINT_LOW("venc_dev constructor");
    156 }
    157 
    158 venc_dev::~venc_dev()
    159 {
    160   pthread_cond_destroy(&loaded_start_stop_cond);
    161   pthread_mutex_destroy(&loaded_start_stop_mlock);
    162   DEBUG_PRINT_LOW("venc_dev distructor");
    163 }
    164 
    165 void* async_venc_message_thread (void *input)
    166 {
    167   struct venc_ioctl_msg ioctl_msg ={NULL,NULL};
    168   struct venc_timeout timeout;
    169   struct venc_msg venc_msg;
    170   int error_code = 0;
    171   omx_venc *omx = reinterpret_cast<omx_venc*>(input);
    172 
    173   prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
    174   timeout.millisec = VEN_TIMEOUT_INFINITE;
    175   while(1)
    176   {
    177     ioctl_msg.in = NULL;
    178     ioctl_msg.out = (void*)&venc_msg;
    179 
    180     /*Wait for a message from the video decoder driver*/
    181     error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg);
    182     if (error_code == -512)  // ERESTARTSYS
    183     {
    184         DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!");
    185     }
    186     else if (error_code <0)
    187     {
    188         DEBUG_PRINT_ERROR("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed");
    189         break;
    190     }
    191     else if(omx->async_message_process(input,&venc_msg) < 0)
    192     {
    193         DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message");
    194         break;
    195     }
    196   }
    197   DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n");
    198   return NULL;
    199 }
    200 
    201 bool venc_dev::venc_open(OMX_U32 codec)
    202 {
    203   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    204   int r;
    205   unsigned int   alignment = 0,buffer_size = 0, temp =0;
    206   OMX_STRING device_name = "/dev/msm_vidc_enc";
    207   DEBUG_PRINT_ERROR("\n Is component secure %d",
    208                   venc_encoder->is_secure_session());
    209   if(venc_encoder->is_secure_session())
    210     device_name = "/dev/msm_vidc_enc_sec";
    211   m_nDriver_fd = open (device_name,O_RDWR|O_NONBLOCK);
    212   if(m_nDriver_fd == 0)
    213   {
    214     DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n");
    215     m_nDriver_fd = open (device_name,O_RDWR|O_NONBLOCK);
    216   }
    217 
    218   if((int)m_nDriver_fd < 0)
    219   {
    220     DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n");
    221     return false;
    222   }
    223 
    224   DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd);
    225 #ifdef SINGLE_ENCODER_INSTANCE
    226   OMX_U32 num_instances = 0;
    227   ioctl_msg.in = NULL;
    228   ioctl_msg.out = &num_instances;
    229   if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < 0 )
    230   {
    231     DEBUG_PRINT_ERROR("\nERROR: Request number of encoder instances failed");
    232   }
    233   else if (num_instances > 1)
    234   {
    235     DEBUG_PRINT_ERROR("\nSecond encoder instance rejected!");
    236     venc_close();
    237     return false;
    238   }
    239 #endif
    240   // set the basic configuration of the video encoder driver
    241   m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
    242   m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
    243   m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
    244   m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
    245   m_sVenc_cfg.fps_num = 30;
    246   m_sVenc_cfg.fps_den = 1;
    247   m_sVenc_cfg.targetbitrate = 64000;
    248 #ifdef MAX_RES_1080P
    249   m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
    250 #else
    251   m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12;
    252 #endif
    253   if(codec == OMX_VIDEO_CodingMPEG4)
    254   {
    255     m_sVenc_cfg.codectype = VEN_CODEC_MPEG4;
    256     codec_profile.profile = VEN_PROFILE_MPEG4_SP;
    257     profile_level.level = VEN_LEVEL_MPEG4_2;
    258 #ifdef OUTPUT_BUFFER_LOG
    259     strcat(outputfilename, "m4v");
    260 #endif
    261   }
    262   else if(codec == OMX_VIDEO_CodingH263)
    263   {
    264     m_sVenc_cfg.codectype = VEN_CODEC_H263;
    265     codec_profile.profile = VEN_PROFILE_H263_BASELINE;
    266     profile_level.level = VEN_LEVEL_H263_20;
    267 #ifdef OUTPUT_BUFFER_LOG
    268     strcat(outputfilename, "263");
    269 #endif
    270   }
    271   if(codec == OMX_VIDEO_CodingAVC)
    272   {
    273     m_sVenc_cfg.codectype = VEN_CODEC_H264;
    274     codec_profile.profile = VEN_PROFILE_H264_BASELINE;
    275     profile_level.level = VEN_LEVEL_H264_1p1;
    276 #ifdef OUTPUT_BUFFER_LOG
    277     strcat(outputfilename, "264");
    278 #endif
    279   }
    280   ioctl_msg.in = (void*)&m_sVenc_cfg;
    281   ioctl_msg.out = NULL;
    282   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 )
    283   {
    284     DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed");
    285     return false;
    286   }
    287 #ifdef INPUT_BUFFER_LOG
    288   inputBufferFile1 = fopen (inputfilename, "ab");
    289 #endif
    290 #ifdef OUTPUT_BUFFER_LOG
    291   outputBufferFile1 = fopen (outputfilename, "ab");
    292 #endif
    293   // Get the I/P and O/P buffer requirements
    294   ioctl_msg.in = NULL;
    295   ioctl_msg.out = (void*)&m_sInput_buff_property;
    296   if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    297   {
    298     DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
    299     return false;
    300   }
    301   ioctl_msg.in = NULL;
    302   ioctl_msg.out = (void*)&m_sOutput_buff_property;
    303   if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    304   {
    305     DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
    306     return false;
    307   }
    308 
    309   m_profile_set = false;
    310   m_level_set = false;
    311   if(venc_set_profile_level(0, 0))
    312   {
    313     DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success",
    314         __func__);
    315   }
    316   recon_buffers_count = MAX_RECON_BUFFERS;
    317   return true;
    318 }
    319 
    320 void venc_dev::venc_close()
    321 {
    322   DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd);
    323   if((int)m_nDriver_fd >= 0)
    324   {
    325     DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
    326     (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
    327         NULL);
    328     DEBUG_PRINT_LOW("\nCalling close()\n");
    329     close(m_nDriver_fd);
    330     m_nDriver_fd = -1;
    331   }
    332 #ifdef INPUT_BUFFER_LOG
    333   fclose (inputBufferFile1);
    334 #endif
    335 #ifdef OUTPUT_BUFFER_LOG
    336   fclose (outputBufferFile1);
    337 #endif
    338 }
    339 
    340 bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
    341                                 unsigned long *actual_buff_count,
    342                                 unsigned long *buff_size,
    343                                 unsigned long port)
    344 {
    345   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    346   unsigned long temp_count = 0;
    347 
    348   if(port == 0)
    349   {
    350     if(*actual_buff_count > m_sInput_buff_property.mincount)
    351     {
    352       temp_count = m_sInput_buff_property.actualcount;
    353       m_sInput_buff_property.actualcount = *actual_buff_count;
    354       ioctl_msg.in = (void*)&m_sInput_buff_property;
    355       ioctl_msg.out = NULL;
    356       if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    357       {
    358         DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed");
    359         m_sInput_buff_property.actualcount = temp_count;
    360         return false;
    361       }
    362       DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count);
    363     }
    364   }
    365   else
    366   {
    367     if(*actual_buff_count > m_sOutput_buff_property.mincount)
    368     {
    369 	  temp_count = m_sOutput_buff_property.actualcount;
    370       m_sOutput_buff_property.actualcount = *actual_buff_count;
    371       ioctl_msg.in = (void*)&m_sOutput_buff_property;
    372       ioctl_msg.out = NULL;
    373       if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    374       {
    375         DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed");
    376 		m_sOutput_buff_property.actualcount = temp_count;
    377         return false;
    378       }
    379       DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count);
    380     }
    381   }
    382 
    383   return true;
    384 
    385 }
    386 
    387 bool venc_dev::venc_loaded_start()
    388 {
    389   struct timespec ts;
    390   int status = 0;
    391   if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0)
    392   {
    393     DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed");
    394     return false;
    395   }
    396   if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
    397   {
    398     DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
    399     return false;
    400   }
    401   ts.tv_sec += 1;
    402   pthread_mutex_lock(&loaded_start_stop_mlock);
    403   DEBUG_PRINT_LOW("%s: wait on start done", __func__);
    404   status = pthread_cond_timedwait(&loaded_start_stop_cond,
    405                 &loaded_start_stop_mlock, &ts);
    406   if (status != 0)
    407   {
    408     DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
    409         status, strerror(status));
    410     pthread_mutex_unlock(&loaded_start_stop_mlock);
    411     return false;
    412   }
    413   DEBUG_PRINT_LOW("%s: wait over on start done", __func__);
    414   pthread_mutex_unlock(&loaded_start_stop_mlock);
    415   DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__);
    416   return true;
    417 }
    418 
    419 bool venc_dev::venc_loaded_stop()
    420 {
    421   struct timespec ts;
    422   int status = 0;
    423   if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0)
    424   {
    425     DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed");
    426     return false;
    427   }
    428   if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
    429   {
    430     DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__);
    431     return false;
    432   }
    433   ts.tv_sec += 1;
    434   pthread_mutex_lock(&loaded_start_stop_mlock);
    435   DEBUG_PRINT_LOW("%s: wait on stop done", __func__);
    436   status = pthread_cond_timedwait(&loaded_start_stop_cond,
    437                 &loaded_start_stop_mlock, &ts);
    438   if (status != 0)
    439   {
    440     DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__,
    441         status, strerror(status));
    442     pthread_mutex_unlock(&loaded_start_stop_mlock);
    443     return false;
    444   }
    445   DEBUG_PRINT_LOW("%s: wait over on stop done", __func__);
    446   pthread_mutex_unlock(&loaded_start_stop_mlock);
    447   DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__);
    448   return true;
    449 }
    450 
    451 bool venc_dev::venc_loaded_start_done()
    452 {
    453   pthread_mutex_lock(&loaded_start_stop_mlock);
    454   DEBUG_PRINT_LOW("%s: signal start done", __func__);
    455   pthread_cond_signal(&loaded_start_stop_cond);
    456   pthread_mutex_unlock(&loaded_start_stop_mlock);
    457   return true;
    458 }
    459 
    460 bool venc_dev::venc_loaded_stop_done()
    461 {
    462   pthread_mutex_lock(&loaded_start_stop_mlock);
    463   DEBUG_PRINT_LOW("%s: signal stop done", __func__);
    464   pthread_cond_signal(&loaded_start_stop_cond);
    465   pthread_mutex_unlock(&loaded_start_stop_mlock);
    466   return true;
    467 }
    468 
    469 bool venc_dev::venc_get_seq_hdr(void *buffer,
    470     unsigned buffer_size, unsigned *header_len)
    471 {
    472   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    473   int i = 0;
    474   DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr");
    475   venc_seqheader seq_in, seq_out;
    476   seq_in.hdrlen = 0;
    477   seq_in.bufsize = buffer_size;
    478   seq_in.hdrbufptr = (unsigned char*)buffer;
    479   if (seq_in.hdrbufptr == NULL) {
    480     DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed");
    481     return false;
    482   }
    483   DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr,
    484     seq_in.bufsize, seq_in.hdrlen);
    485 
    486   ioctl_msg.in = (void*)&seq_in;
    487   ioctl_msg.out = (void*)&seq_out;
    488   if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0)
    489   {
    490     DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed");
    491     return false;
    492   }
    493   if (seq_out.hdrlen == 0) {
    494     DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header");
    495     DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
    496       seq_out.bufsize, seq_out.hdrlen);
    497     return false;
    498   }
    499   *header_len = seq_out.hdrlen;
    500   DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr,
    501     seq_out.bufsize, seq_out.hdrlen);
    502 
    503   return true;
    504 }
    505 
    506 bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
    507                                 unsigned long *actual_buff_count,
    508                                 unsigned long *buff_size,
    509                                 unsigned long port)
    510 {
    511   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    512 
    513   if(port == 0)
    514   {
    515     ioctl_msg.in = NULL;
    516     ioctl_msg.out = (void*)&m_sInput_buff_property;
    517     if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    518     {
    519       DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed");
    520       return false;
    521     }
    522     *min_buff_count = m_sInput_buff_property.mincount;
    523     *actual_buff_count = m_sInput_buff_property.actualcount;
    524 #ifdef USE_ION
    525     // For ION memory allocations of the allocated buffer size
    526     // must be 4k aligned, hence aligning the input buffer
    527     // size to 4k.
    528     m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095)
    529                                        & (~4095);
    530 #endif
    531     *buff_size = m_sInput_buff_property.datasize;
    532   }
    533   else
    534   {
    535     ioctl_msg.in = NULL;
    536     ioctl_msg.out = (void*)&m_sOutput_buff_property;
    537     if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    538     {
    539       DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed");
    540       return false;
    541     }
    542     *min_buff_count = m_sOutput_buff_property.mincount;
    543     *actual_buff_count = m_sOutput_buff_property.actualcount;
    544     *buff_size = m_sOutput_buff_property.datasize;
    545   }
    546 
    547   return true;
    548 
    549 }
    550 
    551 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
    552 {
    553   venc_ioctl_msg ioctl_msg = {NULL,NULL};
    554   DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n");
    555   switch(index)
    556   {
    557   case OMX_IndexParamPortDefinition:
    558     {
    559       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
    560       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
    561       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n");
    562       if(portDefn->nPortIndex == PORT_INDEX_IN)
    563       {
    564 
    565         if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0))
    566         {
    567           return false;
    568         }
    569 
    570         if(!venc_set_color_format(portDefn->format.video.eColorFormat))
    571         {
    572           return false;
    573         }
    574 
    575         DEBUG_PRINT_LOW("\n Basic parameter has changed");
    576         m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
    577         m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
    578 
    579         ioctl_msg.in = (void*)&m_sVenc_cfg;
    580         ioctl_msg.out = NULL;
    581         if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
    582             DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed");
    583             return false;
    584         }
    585 
    586         DEBUG_PRINT_LOW("\n Updating the buffer count/size for the new resolution");
    587         ioctl_msg.in = NULL;
    588         ioctl_msg.out = (void*)&m_sInput_buff_property;
    589         if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
    590             DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed");
    591             return false;
    592         }
    593         DEBUG_PRINT_LOW("\n Got updated m_sInput_buff_property values: "
    594                         "datasize = %u, maxcount = %u, actualcnt = %u, "
    595                         "mincount = %u", m_sInput_buff_property.datasize,
    596                         m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount,
    597                         m_sInput_buff_property.mincount);
    598 
    599         ioctl_msg.in = NULL;
    600         ioctl_msg.out = (void*)&m_sOutput_buff_property;
    601         if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
    602             DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed");
    603             return false;
    604         }
    605 
    606         DEBUG_PRINT_LOW("\n Got updated m_sOutput_buff_property values: "
    607                         "datasize = %u, maxcount = %u, actualcnt = %u, "
    608                         "mincount = %u", m_sOutput_buff_property.datasize,
    609                         m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount,
    610                         m_sOutput_buff_property.mincount);
    611         ioctl_msg.in = (void*)&m_sOutput_buff_property;
    612         ioctl_msg.out = NULL;
    613 
    614         if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
    615             DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed");
    616             return false;
    617         }
    618 
    619         if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) &&
    620            (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) {
    621             m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
    622             ioctl_msg.in = (void*)&m_sInput_buff_property;
    623             ioctl_msg.out = NULL;
    624             if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) {
    625               DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed");
    626               return false;
    627             }
    628         }
    629         if(m_sInput_buff_property.datasize != portDefn->nBufferSize) {
    630             DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u],"
    631                               "Driver's updated i/p bufsize = %u", portDefn->nBufferSize,
    632                               m_sInput_buff_property.datasize);
    633         }
    634         m_level_set = false;
    635         if(venc_set_profile_level(0, 0)) {
    636           DEBUG_PRINT_HIGH("\n %s(): Profile/Level setting success", __func__);
    637         }
    638       }
    639       else if(portDefn->nPortIndex == PORT_INDEX_OUT)
    640       {
    641         if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0))
    642         {
    643           return false;
    644         }
    645 
    646         if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
    647             &&
    648             (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual)
    649             &&
    650             (m_sOutput_buff_property.datasize == portDefn->nBufferSize)
    651           )
    652         {
    653           m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
    654           ioctl_msg.in = (void*)&m_sOutput_buff_property;
    655           ioctl_msg.out = NULL;
    656           if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
    657           {
    658             DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
    659             return false;
    660           }
    661         }
    662         else
    663         {
    664           DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed");
    665           return false;
    666         }
    667       }
    668       else
    669       {
    670         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
    671       }
    672       break;
    673     }
    674   case OMX_IndexParamVideoPortFormat:
    675     {
    676       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
    677       portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
    678       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n");
    679 
    680       if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
    681       {
    682         if(!venc_set_color_format(portFmt->eColorFormat))
    683         {
    684           return false;
    685         }
    686       }
    687       else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    688       {
    689         if(!venc_set_encode_framerate(portFmt->xFramerate, 0))
    690         {
    691           return false;
    692         }
    693       }
    694       else
    695       {
    696         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
    697       }
    698       break;
    699     }
    700   case OMX_IndexParamVideoBitrate:
    701     {
    702       OMX_VIDEO_PARAM_BITRATETYPE* pParam;
    703       pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
    704       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n");
    705 
    706       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    707       {
    708         if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0))
    709         {
    710           DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed");
    711           return false;
    712         }
    713         if(!venc_set_ratectrl_cfg(pParam->eControlRate))
    714         {
    715           DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed");
    716           return false;
    717         }
    718       }
    719       else
    720       {
    721         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
    722       }
    723       break;
    724     }
    725   case OMX_IndexParamVideoMpeg4:
    726     {
    727       OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
    728       OMX_U32 bFrames = 0;
    729 
    730       pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
    731       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n");
    732       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    733       {
    734         if(!venc_set_voptiming_cfg(pParam->nTimeIncRes))
    735         {
    736           DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed");
    737           return false;
    738         }
    739         m_profile_set = false;
    740         m_level_set = false;
    741         if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
    742         {
    743           DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
    744           return false;
    745         }
    746 #ifdef MAX_RES_1080P
    747         else {
    748           if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
    749           {
    750             if(pParam->nBFrames)
    751             {
    752               DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
    753               bFrames = 1;
    754             }
    755           }
    756         else
    757           {
    758             if(pParam->nBFrames)
    759             {
    760               DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
    761               bFrames = 0;
    762             }
    763           }
    764         }
    765 #endif
    766         if(!venc_set_intra_period (pParam->nPFrames,bFrames))
    767         {
    768           DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
    769           return false;
    770         }
    771         if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing))
    772         {
    773           DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config");
    774           return false;
    775         }
    776       }
    777       else
    778       {
    779         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
    780       }
    781       break;
    782     }
    783   case OMX_IndexParamVideoH263:
    784     {
    785       OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
    786       DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n");
    787       OMX_U32 bFrames = 0;
    788       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    789       {
    790         m_profile_set = false;
    791         m_level_set = false;
    792         if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel))
    793         {
    794           DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level");
    795           return false;
    796         }
    797         if (pParam->nBFrames)
    798           DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263");
    799 
    800         if(venc_set_intra_period (pParam->nPFrames, bFrames) == false)
    801         {
    802           DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
    803           return false;
    804         }
    805       }
    806       else
    807       {
    808         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263");
    809       }
    810       break;
    811     }
    812   case OMX_IndexParamVideoAvc:
    813     {
    814       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n");
    815       OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
    816       OMX_U32 bFrames = 0;
    817 
    818       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    819       {
    820         DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n",
    821             pParam->eProfile,pParam->eLevel);
    822 
    823         m_profile_set = false;
    824         m_level_set = false;
    825 
    826         if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel))
    827         {
    828           DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d",
    829                             pParam->eProfile, pParam->eLevel);
    830           return false;
    831         }
    832 #ifdef MAX_RES_1080P
    833         else {
    834           if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline)
    835           {
    836             if(pParam->nBFrames)
    837             {
    838               DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
    839               bFrames = 1;
    840             }
    841           }
    842         else
    843           {
    844             if(pParam->nBFrames)
    845             {
    846               DEBUG_PRINT_ERROR("Warning: B frames not supported\n");
    847               bFrames = 0;
    848             }
    849           }
    850         }
    851 #endif
    852         if(!venc_set_intra_period (pParam->nPFrames, bFrames))
    853         {
    854           DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
    855           return false;
    856         }
    857         if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc))
    858         {
    859           DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed");
    860           return false;
    861         }
    862         if(!venc_set_inloop_filter (pParam->eLoopFilterMode))
    863         {
    864           DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed");
    865           return false;
    866         }
    867         if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing))
    868         {
    869           DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config");
    870           return false;
    871         }
    872       }
    873       else
    874       {
    875         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
    876       }
    877       //TBD, lot of other variables to be updated, yet to decide
    878       break;
    879     }
    880   case OMX_IndexParamVideoIntraRefresh:
    881     {
    882       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n");
    883       OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
    884         (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
    885       if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    886       {
    887         if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false)
    888         {
    889           DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
    890           return false;
    891         }
    892       }
    893       else
    894       {
    895         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
    896       }
    897       break;
    898     }
    899   case OMX_IndexParamVideoErrorCorrection:
    900     {
    901       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n");
    902       OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
    903         (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
    904       if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    905       {
    906         if(venc_set_error_resilience(error_resilience) == false)
    907         {
    908           DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed");
    909           return false;
    910         }
    911       }
    912       else
    913       {
    914         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
    915       }
    916       break;
    917     }
    918   case OMX_IndexParamVideoProfileLevelCurrent:
    919     {
    920       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n");
    921       OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
    922       (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
    923       if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    924       {
    925         m_profile_set = false;
    926         m_level_set = false;
    927         if(!venc_set_profile_level (profile_level->eProfile,
    928                                    profile_level->eLevel))
    929         {
    930           DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level");
    931           return false;
    932         }
    933       }
    934       else
    935       {
    936         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
    937       }
    938       break;
    939     }
    940   case OMX_IndexParamVideoQuantization:
    941     {
    942       DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n");
    943       OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
    944         (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
    945       if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
    946       {
    947         if(venc_set_session_qp (session_qp->nQpI,
    948                                 session_qp->nQpP) == false)
    949         {
    950           DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed");
    951           return false;
    952         }
    953       }
    954       else
    955       {
    956         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
    957       }
    958       break;
    959     }
    960   case OMX_ExtraDataVideoEncoderSliceInfo:
    961     {
    962       DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
    963       OMX_U32 extra_data = *(OMX_U32 *)paramData;
    964       if(venc_set_extradata(extra_data) == false)
    965       {
    966          DEBUG_PRINT_ERROR("ERROR: Setting "
    967             "OMX_QcomIndexParamIndexExtraDataType failed");
    968          return false;
    969       }
    970       break;
    971     }
    972   case OMX_QcomIndexEnableSliceDeliveryMode:
    973     {
    974        QOMX_EXTNINDEX_PARAMTYPE* pParam =
    975           (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
    976        if(pParam->nPortIndex == PORT_INDEX_OUT)
    977        {
    978          if(venc_set_slice_delivery_mode(pParam->bEnable) == false)
    979          {
    980            DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
    981            return OMX_ErrorUnsupportedSetting;
    982          }
    983        }
    984        else
    985        {
    986          DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
    987             "called on wrong port(%d)", pParam->nPortIndex);
    988          return OMX_ErrorBadPortIndex;
    989        }
    990        break;
    991     }
    992   case OMX_QcomIndexParamSequenceHeaderWithIDR:
    993     {
    994        PrependSPSPPSToIDRFramesParams * pParam =
    995           (PrependSPSPPSToIDRFramesParams *)paramData;
    996 
    997        if(venc_set_inband_video_header(pParam->bEnable) == false)
    998        {
    999          DEBUG_PRINT_ERROR("Setting inband sps/pps failed");
   1000          return false;
   1001        }
   1002        break;
   1003     }
   1004   case OMX_QcomIndexParamEnableVUIStreamRestrictFlag:
   1005     {
   1006        QOMX_VUI_BITSTREAM_RESTRICT *pParam =
   1007           (QOMX_VUI_BITSTREAM_RESTRICT *)paramData;
   1008 
   1009        if(venc_set_bitstream_restrict_in_vui(pParam->bEnable) == false)
   1010        {
   1011          DEBUG_PRINT_ERROR("Setting bitstream_restrict flag in VUI failed");
   1012          return false;
   1013        }
   1014        break;
   1015     }
   1016   case OMX_IndexParamVideoSliceFMO:
   1017   default:
   1018 	  DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u",
   1019       index);
   1020     break;
   1021     //case
   1022   }
   1023 
   1024   return true;
   1025 }
   1026 
   1027 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
   1028 {
   1029   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1030   DEBUG_PRINT_LOW("\n Inside venc_set_config");
   1031 
   1032   switch(index)
   1033   {
   1034   case OMX_IndexConfigVideoBitrate:
   1035     {
   1036       OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
   1037         configData;
   1038       if(m_max_allowed_bitrate_check &&
   1039          !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate))
   1040       {
   1041         DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed");
   1042         return false;
   1043       }
   1044       DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate");
   1045       if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
   1046       {
   1047         if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false)
   1048         {
   1049           DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed");
   1050           return false;
   1051         }
   1052       }
   1053       else
   1054       {
   1055         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
   1056       }
   1057       break;
   1058     }
   1059   case OMX_IndexConfigVideoFramerate:
   1060     {
   1061       OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
   1062         configData;
   1063       DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate");
   1064       if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
   1065       {
   1066         if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false)
   1067         {
   1068           DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
   1069           return false;
   1070         }
   1071       }
   1072       else
   1073       {
   1074         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
   1075       }
   1076       break;
   1077     }
   1078   case QOMX_IndexConfigVideoIntraperiod:
   1079     {
   1080       DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n");
   1081       QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
   1082       (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
   1083       if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
   1084       {
   1085         if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false)
   1086         {
   1087           DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
   1088           return false;
   1089         }
   1090       }
   1091       break;
   1092     }
   1093   case OMX_IndexConfigVideoIntraVOPRefresh:
   1094     {
   1095       OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
   1096         configData;
   1097       DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
   1098       if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT)
   1099       {
   1100         if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false)
   1101         {
   1102           DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed");
   1103           return false;
   1104         }
   1105       }
   1106       else
   1107       {
   1108         DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
   1109       }
   1110       break;
   1111     }
   1112   case OMX_IndexConfigCommonRotate:
   1113     {
   1114       OMX_CONFIG_ROTATIONTYPE *config_rotation =
   1115          reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
   1116       venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1117       OMX_U32 nFrameWidth;
   1118 
   1119       DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims");
   1120       nFrameWidth = m_sVenc_cfg.input_width;
   1121       m_sVenc_cfg.input_width  = m_sVenc_cfg.input_height;
   1122       m_sVenc_cfg.input_height = nFrameWidth;
   1123       ioctl_msg.in = (void*)&m_sVenc_cfg;
   1124       ioctl_msg.out = NULL;
   1125       if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) {
   1126           DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed");
   1127           return false;
   1128       }
   1129       break;
   1130     }
   1131   default:
   1132     DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index);
   1133     break;
   1134   }
   1135 
   1136   return true;
   1137 }
   1138 
   1139 unsigned venc_dev::venc_stop( void)
   1140 {
   1141 #ifdef MAX_RES_1080P
   1142     pmem_free();
   1143 #endif
   1144   return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL);
   1145 }
   1146 
   1147 unsigned venc_dev::venc_pause(void)
   1148 {
   1149   return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL);
   1150 }
   1151 
   1152 unsigned venc_dev::venc_resume(void)
   1153 {
   1154   return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ;
   1155 }
   1156 
   1157 unsigned venc_dev::venc_start_done(void)
   1158 {
   1159   return 0;
   1160 }
   1161 
   1162 unsigned venc_dev::venc_stop_done(void)
   1163 {
   1164   return 0;
   1165 }
   1166 
   1167 unsigned venc_dev::venc_start(void)
   1168 {
   1169   DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start",
   1170         __func__);
   1171   if (!venc_set_profile_level(0, 0))
   1172   {
   1173     DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET",
   1174       __func__);
   1175   }
   1176   else
   1177   {
   1178     DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET",
   1179       __func__, codec_profile.profile, profile_level.level);
   1180   }
   1181 
   1182   if(m_max_allowed_bitrate_check &&
   1183      !venc_max_allowed_bitrate_check(bitrate.target_bitrate))
   1184   {
   1185     DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed");
   1186     return -1;
   1187   }
   1188 
   1189   venc_config_print();
   1190 
   1191 #ifdef MAX_RES_1080P
   1192   if((codec_profile.profile == VEN_PROFILE_MPEG4_SP) ||
   1193      (codec_profile.profile == VEN_PROFILE_H264_BASELINE) ||
   1194      (codec_profile.profile == VEN_PROFILE_H263_BASELINE))
   1195     recon_buffers_count = MAX_RECON_BUFFERS - 2;
   1196   else
   1197     recon_buffers_count = MAX_RECON_BUFFERS;
   1198 
   1199   if (!venc_allocate_recon_buffers())
   1200     return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
   1201   else
   1202   {
   1203     DEBUG_PRINT_ERROR("Failed in creating Recon buffers\n");
   1204     return -1;
   1205   }
   1206 #else
   1207     return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL);
   1208 #endif
   1209 }
   1210 
   1211 #ifdef MAX_RES_1080P
   1212 OMX_U32 venc_dev::venc_allocate_recon_buffers()
   1213 {
   1214   OMX_U32 yuv_size;
   1215   struct venc_ioctl_msg ioctl_msg;
   1216   struct venc_recon_buff_size recon_buff_size;
   1217 
   1218   recon_buff_size.width =  ((m_sVenc_cfg.input_width + 15) / 16) * 16;
   1219   recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16;
   1220 
   1221   DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d\n", m_sVenc_cfg.input_width,
   1222                     m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height);
   1223 
   1224   ioctl_msg.in = NULL;
   1225   ioctl_msg.out = (void*)&recon_buff_size;
   1226 
   1227   if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0)
   1228   {
   1229     DEBUG_PRINT_ERROR("\n VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" ,
   1230       recon_buff_size.width, recon_buff_size.height);
   1231     return OMX_ErrorInsufficientResources;
   1232   }
   1233 
   1234   DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d\n",
   1235                    m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width,
   1236                    recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment,
   1237                    recon_buffers_count);
   1238 
   1239   for(int i = 0; i < recon_buffers_count; i++)
   1240   {
   1241     if(pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i))
   1242     {
   1243       DEBUG_PRINT_ERROR("Error returned in allocating recon buffers\n");
   1244       return -1;
   1245     }
   1246   }
   1247   return 0;
   1248 }
   1249 OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count)
   1250 {
   1251   OMX_U32 pmem_fd = -1;
   1252   OMX_U32 width, height;
   1253   void *buf_addr = NULL;
   1254   struct venc_ioctl_msg ioctl_msg;
   1255   struct venc_recon_addr recon_addr;
   1256   int rc = 0;
   1257 
   1258 #ifdef USE_ION
   1259   recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY | O_DSYNC);
   1260   if(recon_buff[count].ion_device_fd < 0)
   1261   {
   1262       DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
   1263       return -1;
   1264   }
   1265 
   1266   recon_buff[count].alloc_data.flags = 0;
   1267   recon_buff[count].alloc_data.len = size;
   1268   recon_buff[count].alloc_data.heap_mask = (ION_HEAP(MEM_HEAP_ID) |
   1269                   (venc_encoder->is_secure_session() ? ION_SECURE
   1270                    : ION_HEAP(ION_IOMMU_HEAP_ID)));
   1271   recon_buff[count].alloc_data.align = clip2(alignment);
   1272   if (recon_buff[count].alloc_data.align != 8192)
   1273     recon_buff[count].alloc_data.align = 8192;
   1274 
   1275   rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data);
   1276   if(rc || !recon_buff[count].alloc_data.handle) {
   1277          DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
   1278          recon_buff[count].alloc_data.handle=NULL;
   1279          return -1;
   1280   }
   1281 
   1282   recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle;
   1283   rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd);
   1284   if(rc) {
   1285         DEBUG_PRINT_ERROR("\n ION MAP failed ");
   1286         recon_buff[count].ion_alloc_fd.fd =-1;
   1287         recon_buff[count].ion_alloc_fd.fd =-1;
   1288         return -1;
   1289   }
   1290   pmem_fd = recon_buff[count].ion_alloc_fd.fd;
   1291 #else
   1292   struct pmem_allocation allocation;
   1293   pmem_fd = open(MEM_DEVICE, O_RDWR);
   1294 
   1295   if ((int)(pmem_fd) < 0)
   1296   {
   1297 	DEBUG_PRINT_ERROR("\n Failed to get an pmem handle");
   1298 	return -1;
   1299   }
   1300 
   1301   allocation.size = size;
   1302   allocation.align = clip2(alignment);
   1303 
   1304   if (allocation.align != 8192)
   1305     allocation.align = 8192;
   1306 
   1307   if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
   1308   {
   1309     DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
   1310       allocation.align, allocation.size);
   1311     return -1;
   1312   }
   1313 #endif
   1314   if(!venc_encoder->is_secure_session()) {
   1315     buf_addr = mmap(NULL, size,
   1316                  PROT_READ | PROT_WRITE,
   1317                  MAP_SHARED, pmem_fd, 0);
   1318 
   1319     if (buf_addr == (void*) MAP_FAILED)
   1320     {
   1321       close(pmem_fd);
   1322       pmem_fd = -1;
   1323       DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr);
   1324   #ifdef USE_ION
   1325       if(ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE,
   1326          &recon_buff[count].alloc_data.handle)) {
   1327         DEBUG_PRINT_ERROR("ion recon buffer free failed");
   1328       }
   1329       recon_buff[count].alloc_data.handle = NULL;
   1330       recon_buff[count].ion_alloc_fd.fd =-1;
   1331       close(recon_buff[count].ion_device_fd);
   1332       recon_buff[count].ion_device_fd =-1;
   1333   #endif
   1334       return -1;
   1335     }
   1336   }
   1337 
   1338   DEBUG_PRINT_HIGH("\n Allocated virt:%p, FD: %d of size %d \n", buf_addr, pmem_fd, size);
   1339 
   1340   recon_addr.buffer_size = size;
   1341   recon_addr.pmem_fd = pmem_fd;
   1342   recon_addr.offset = 0;
   1343   if(!venc_encoder->is_secure_session())
   1344     recon_addr.pbuffer = (unsigned char *)buf_addr;
   1345   else
   1346     recon_addr.pbuffer = (unsigned char *)(pmem_fd + 1);
   1347 
   1348   ioctl_msg.in = (void*)&recon_addr;
   1349   ioctl_msg.out = NULL;
   1350 
   1351   if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0)
   1352   {
   1353     DEBUG_PRINT_ERROR("Failed to set the Recon_buffers\n");
   1354     return -1;
   1355   }
   1356 
   1357   recon_buff[count].virtual_address = (unsigned char *) buf_addr;
   1358   recon_buff[count].size = size;
   1359   recon_buff[count].offset = 0;
   1360   recon_buff[count].pmem_fd = pmem_fd;
   1361 
   1362   DEBUG_PRINT_ERROR("\n Allocated virt:%p, FD: %d of size %d at index: %d\n", recon_buff[count].virtual_address,
   1363                      recon_buff[count].pmem_fd, recon_buff[count].size, count);
   1364   return 0;
   1365 }
   1366 
   1367 OMX_U32 venc_dev::pmem_free()
   1368 {
   1369   int cnt = 0;
   1370   struct venc_ioctl_msg ioctl_msg;
   1371   struct venc_recon_addr recon_addr;
   1372   for (cnt = 0; cnt < recon_buffers_count; cnt++)
   1373   {
   1374     if(recon_buff[cnt].pmem_fd)
   1375     {
   1376       recon_addr.pbuffer = recon_buff[cnt].virtual_address;
   1377       recon_addr.offset = recon_buff[cnt].offset;
   1378       recon_addr.pmem_fd = recon_buff[cnt].pmem_fd;
   1379       recon_addr.buffer_size = recon_buff[cnt].size;
   1380       ioctl_msg.in = (void*)&recon_addr;
   1381       ioctl_msg.out = NULL;
   1382       if(ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0)
   1383         DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed");
   1384       if(!venc_encoder->is_secure_session())
   1385         munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size);
   1386       close(recon_buff[cnt].pmem_fd);
   1387 #ifdef USE_ION
   1388       if(ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE,
   1389          &recon_buff[cnt].alloc_data.handle)) {
   1390         DEBUG_PRINT_ERROR("ion recon buffer free failed");
   1391       }
   1392       recon_buff[cnt].alloc_data.handle = NULL;
   1393       recon_buff[cnt].ion_alloc_fd.fd =-1;
   1394       close(recon_buff[cnt].ion_device_fd);
   1395       recon_buff[cnt].ion_device_fd =-1;
   1396 #endif
   1397       DEBUG_PRINT_LOW("\n cleaning Index %d of size %d \n",cnt,recon_buff[cnt].size);
   1398       recon_buff[cnt].pmem_fd = -1;
   1399       recon_buff[cnt].virtual_address = NULL;
   1400       recon_buff[cnt].offset = 0;
   1401       recon_buff[cnt].alignment = 0;
   1402       recon_buff[cnt].size = 0;
   1403     }
   1404   }
   1405   return 0;
   1406 }
   1407 #endif
   1408 
   1409 void venc_dev::venc_config_print()
   1410 {
   1411 
   1412   DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %d, Profile %d, level : %d",
   1413                    m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
   1414 
   1415   DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %d, Height:%d, Fps: %d",
   1416                    m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
   1417                    m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
   1418 
   1419   DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d",
   1420                    bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
   1421 
   1422   DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %d, qpP: %d, qpb: 0",
   1423                    session_qp.iframeqp, session_qp.pframqp);
   1424 
   1425   DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d",
   1426                    voptimecfg.voptime_resolution, multislice.mslice_mode,
   1427                    multislice.mslice_size);
   1428 
   1429   DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %d",
   1430                    entropy.longentropysel, entropy.cabacmodel);
   1431 
   1432   DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d\n",
   1433                    dbkfilter.db_mode, dbkfilter.slicealpha_offset,
   1434                    dbkfilter.slicebeta_offset);
   1435 
   1436   DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %d, HEC: %d\n",
   1437                    intra_refresh.mbcount, hec.header_extension);
   1438 }
   1439 
   1440 unsigned venc_dev::venc_flush( unsigned port)
   1441 {
   1442   struct venc_ioctl_msg ioctl_msg;
   1443   struct venc_bufferflush buffer_index;
   1444 
   1445   if(port == PORT_INDEX_IN)
   1446   {
   1447     DEBUG_PRINT_HIGH("Calling Input Flush");
   1448     buffer_index.flush_mode = VEN_FLUSH_INPUT;
   1449     ioctl_msg.in = (void*)&buffer_index;
   1450     ioctl_msg.out = NULL;
   1451 
   1452     return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
   1453   }
   1454   else if(port == PORT_INDEX_OUT)
   1455   {
   1456     DEBUG_PRINT_HIGH("Calling Output Flush");
   1457     buffer_index.flush_mode = VEN_FLUSH_OUTPUT;
   1458     ioctl_msg.in = (void*)&buffer_index;
   1459     ioctl_msg.out = NULL;
   1460     return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg);
   1461   }
   1462   else
   1463   {
   1464     return -1;
   1465   }
   1466 }
   1467 
   1468 //allocating I/P memory from pmem and register with the device
   1469 
   1470 
   1471 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned)
   1472 {
   1473   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1474   struct pmem *pmem_tmp;
   1475   struct venc_bufferpayload dev_buffer = {0};
   1476   struct venc_allocatorproperty buff_alloc_property = {0};
   1477 
   1478   pmem_tmp = (struct pmem *)buf_addr;
   1479 
   1480   DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
   1481 
   1482   if(port == PORT_INDEX_IN)
   1483   {
   1484     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   1485     dev_buffer.fd  = pmem_tmp->fd;
   1486     dev_buffer.maped_size = pmem_tmp->size;
   1487     dev_buffer.sz = pmem_tmp->size;
   1488     dev_buffer.offset = pmem_tmp->offset;
   1489 
   1490     if((m_sVenc_cfg.input_height %16 !=0) || (m_sVenc_cfg.input_width%16 != 0))
   1491     {
   1492       unsigned long ht = m_sVenc_cfg.input_height;
   1493       unsigned long wd = m_sVenc_cfg.input_width;
   1494       unsigned int luma_size, luma_size_2k;
   1495 
   1496       ht = (ht + 15) & ~15;
   1497       wd = (wd + 15) & ~15;
   1498 
   1499       luma_size = ht * wd;
   1500       luma_size_2k = (luma_size + 2047) & ~2047;
   1501 
   1502       dev_buffer.sz = luma_size_2k + ((luma_size/2 + 2047) & ~2047);
   1503 #ifdef USE_ION
   1504       ioctl_msg.in = NULL;
   1505       ioctl_msg.out = (void*)&buff_alloc_property;
   1506       if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0)
   1507       {
   1508          DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:get input buffer failed ");
   1509          return false;
   1510       }
   1511       if(buff_alloc_property.alignment < 4096)
   1512       {
   1513          dev_buffer.sz = ((dev_buffer.sz + 4095) & ~4095);
   1514       }
   1515       else
   1516       {
   1517          dev_buffer.sz = ((dev_buffer.sz + (buff_alloc_property.alignment - 1)) &
   1518                                            ~(buff_alloc_property.alignment - 1));
   1519       }
   1520 #endif
   1521       dev_buffer.maped_size = dev_buffer.sz;
   1522     }
   1523 
   1524     ioctl_msg.in  = (void*)&dev_buffer;
   1525     ioctl_msg.out = NULL;
   1526 
   1527     DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
   1528                 dev_buffer.pbuffer, \
   1529                 dev_buffer.fd, \
   1530                 dev_buffer.offset, \
   1531                 dev_buffer.maped_size);
   1532 
   1533     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0)
   1534     {
   1535       DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed ");
   1536       return false;
   1537     }
   1538   }
   1539   else if(port == PORT_INDEX_OUT)
   1540   {
   1541     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   1542     dev_buffer.fd  = pmem_tmp->fd;
   1543     dev_buffer.sz = pmem_tmp->size;
   1544     dev_buffer.maped_size = pmem_tmp->size;
   1545     dev_buffer.offset = pmem_tmp->offset;
   1546     ioctl_msg.in  = (void*)&dev_buffer;
   1547     ioctl_msg.out = NULL;
   1548 
   1549     DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
   1550                 dev_buffer.pbuffer, \
   1551                 dev_buffer.fd, \
   1552                 dev_buffer.offset, \
   1553                 dev_buffer.maped_size);
   1554 
   1555     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0)
   1556     {
   1557       DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed ");
   1558       return false;
   1559     }
   1560   }
   1561   else
   1562   {
   1563     DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index ");
   1564     return false;
   1565   }
   1566 
   1567   return true;
   1568 }
   1569 
   1570 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
   1571 {
   1572   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1573   struct pmem *pmem_tmp;
   1574   struct venc_bufferpayload dev_buffer = {0};
   1575 
   1576   pmem_tmp = (struct pmem *)buf_addr;
   1577 
   1578   DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp);
   1579 
   1580   if(port == PORT_INDEX_IN)
   1581   {
   1582     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   1583     dev_buffer.fd  = pmem_tmp->fd;
   1584     dev_buffer.maped_size = pmem_tmp->size;
   1585     dev_buffer.sz = pmem_tmp->size;
   1586     dev_buffer.offset = pmem_tmp->offset;
   1587     ioctl_msg.in  = (void*)&dev_buffer;
   1588     ioctl_msg.out = NULL;
   1589 
   1590     DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
   1591                 dev_buffer.pbuffer, \
   1592                 dev_buffer.fd, \
   1593                 dev_buffer.offset, \
   1594                 dev_buffer.maped_size);
   1595 
   1596     if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0)
   1597     {
   1598       DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed ");
   1599       return false;
   1600     }
   1601   }
   1602   else if(port == PORT_INDEX_OUT)
   1603   {
   1604     dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   1605     dev_buffer.fd  = pmem_tmp->fd;
   1606     dev_buffer.sz = pmem_tmp->size;
   1607     dev_buffer.maped_size = pmem_tmp->size;
   1608     dev_buffer.offset = pmem_tmp->offset;
   1609     ioctl_msg.in  = (void*)&dev_buffer;
   1610     ioctl_msg.out = NULL;
   1611 
   1612     DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \
   1613                 dev_buffer.pbuffer, \
   1614                 dev_buffer.fd, \
   1615                 dev_buffer.offset, \
   1616                 dev_buffer.maped_size);
   1617 
   1618     if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0)
   1619     {
   1620       DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed ");
   1621       return false;
   1622     }
   1623   }
   1624   else
   1625   {
   1626     DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index ");
   1627     return false;
   1628   }
   1629 
   1630   return true;
   1631 }
   1632 
   1633 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
   1634 {
   1635   struct venc_buffer frameinfo;
   1636   struct pmem *temp_buffer;
   1637   struct venc_ioctl_msg ioctl_msg;
   1638   struct OMX_BUFFERHEADERTYPE *bufhdr;
   1639 
   1640   if(buffer == NULL)
   1641   {
   1642     DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL");
   1643     return false;
   1644   }
   1645   bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
   1646 
   1647   DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen);
   1648 
   1649   if(pmem_data_buf)
   1650   {
   1651     DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
   1652     frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
   1653   }
   1654   else
   1655   {
   1656     DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
   1657     frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
   1658   }
   1659 
   1660   frameinfo.clientdata = (void *) buffer;
   1661   frameinfo.sz = bufhdr->nFilledLen;
   1662   frameinfo.len = bufhdr->nFilledLen;
   1663   frameinfo.flags = bufhdr->nFlags;
   1664   frameinfo.offset = bufhdr->nOffset;
   1665   frameinfo.timestamp = bufhdr->nTimeStamp;
   1666   DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp);
   1667   ioctl_msg.in = &frameinfo;
   1668   ioctl_msg.out = NULL;
   1669 
   1670   DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
   1671       bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
   1672   if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
   1673   {
   1674     /*Generate an async error and move to invalid state*/
   1675     return false;
   1676   }
   1677 #ifdef INPUT_BUFFER_LOG
   1678 #ifdef MAX_RES_1080P
   1679 
   1680   int y_size = 0;
   1681   int c_offset = 0;
   1682   unsigned char *buf_addr = NULL;
   1683 
   1684   y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height;
   1685   //chroma offset is y_size aligned to the 2k boundary
   1686   c_offset= (y_size + 2047) & (~(2047));
   1687 
   1688   if(pmem_data_buf)
   1689   {
   1690     DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
   1691     buf_addr = (OMX_U8 *)pmem_data_buf;
   1692   }
   1693   else
   1694   {
   1695     DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
   1696     buf_addr = (unsigned char *)mmap(NULL,
   1697           ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2],
   1698           PROT_READ|PROT_WRITE, MAP_SHARED,
   1699           ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[0], 0);
   1700   }
   1701 
   1702   if(inputBufferFile1)
   1703   {
   1704     fwrite((const char *)buf_addr, y_size, 1,inputBufferFile1);
   1705     fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1,inputBufferFile1);
   1706   }
   1707 
   1708   munmap (buf_addr, ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2]);
   1709 #else
   1710   if(inputBufferFile1)
   1711   {
   1712     fwrite((const char *)frameinfo.ptrbuffer, frameinfo.len, 1,inputBufferFile1);
   1713   }
   1714 #endif
   1715 
   1716 #endif
   1717   return true;
   1718 }
   1719 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned)
   1720 {
   1721   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1722   struct pmem *temp_buffer = NULL;
   1723   struct venc_buffer  frameinfo;
   1724   struct OMX_BUFFERHEADERTYPE *bufhdr;
   1725 
   1726   if(buffer == NULL)
   1727   {
   1728     return false;
   1729   }
   1730   bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
   1731 
   1732   if(pmem_data_buf)
   1733   {
   1734     DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
   1735     frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
   1736   }
   1737   else
   1738   {
   1739     DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
   1740     frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
   1741   }
   1742 
   1743   frameinfo.clientdata = buffer;
   1744   frameinfo.sz = bufhdr->nAllocLen;
   1745   frameinfo.flags = bufhdr->nFlags;
   1746   frameinfo.offset = bufhdr->nOffset;
   1747 
   1748   ioctl_msg.in = &frameinfo;
   1749   ioctl_msg.out = NULL;
   1750   DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u",
   1751       bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len);
   1752   if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
   1753   {
   1754     DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
   1755     return false;
   1756   }
   1757 
   1758   return true;
   1759 }
   1760 
   1761 bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable)
   1762 {
   1763   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1764   DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable);
   1765   if(multislice.mslice_mode == VEN_MSLICE_CNT_MB)
   1766   {
   1767     if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0)
   1768     {
   1769       DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
   1770       return false;
   1771     }
   1772   }
   1773   else
   1774   {
   1775     DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set "
   1776        "slice delivery mode to the driver.", multislice.mslice_mode);
   1777   }
   1778   return true;
   1779 }
   1780 
   1781 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
   1782 {
   1783   venc_ioctl_msg ioctl_msg = {(void *)&enable, NULL};
   1784   DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
   1785   if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_SPS_PPS_FOR_IDR, (void *)&ioctl_msg) < 0)
   1786   {
   1787     DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
   1788     return false;
   1789   }
   1790   return true;
   1791 }
   1792 
   1793 bool venc_dev::venc_set_bitstream_restrict_in_vui(OMX_BOOL enable)
   1794 {
   1795   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   1796   DEBUG_PRINT_HIGH("Set bistream_restrict in vui: %d", enable);
   1797   if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_VUI_BITSTREAM_RESTRICT_FLAG, (void *)&ioctl_msg) < 0)
   1798   {
   1799     DEBUG_PRINT_ERROR("Request for setting bitstream_restrict flag in VUI failed");
   1800     return false;
   1801   }
   1802   return true;
   1803 }
   1804 
   1805 bool venc_dev::venc_set_extradata(OMX_U32 extra_data)
   1806 {
   1807   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1808   DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data);
   1809   ioctl_msg.in = (void*)&extra_data;
   1810   ioctl_msg.out = NULL;
   1811   if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0)
   1812   {
   1813     DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
   1814     return false;
   1815   }
   1816 
   1817   return true;
   1818 }
   1819 
   1820 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp)
   1821 {
   1822   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1823   struct venc_sessionqp qp = {0, 0};
   1824   DEBUG_PRINT_LOW("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp,
   1825     p_frame_qp);
   1826 
   1827   qp.iframeqp = i_frame_qp;
   1828   qp.pframqp = p_frame_qp;
   1829 
   1830   ioctl_msg.in = (void*)&qp;
   1831   ioctl_msg.out = NULL;
   1832   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0)
   1833   {
   1834     DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed");
   1835     return false;
   1836   }
   1837 
   1838   session_qp.iframeqp = i_frame_qp;
   1839   session_qp.pframqp = p_frame_qp;
   1840 
   1841   return true;
   1842 }
   1843 
   1844 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
   1845 {
   1846   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   1847   struct venc_profile requested_profile;
   1848   struct ven_profilelevel requested_level;
   1849   unsigned const int *profile_tbl = NULL;
   1850   unsigned long mb_per_frame = 0, mb_per_sec = 0;
   1851   DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d",
   1852     eProfile, eLevel);
   1853   mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
   1854                   ((m_sVenc_cfg.input_width + 15) >> 4);
   1855   if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set)
   1856   {
   1857     DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start");
   1858     return true;
   1859   }
   1860 
   1861   if(eProfile && eLevel)
   1862   {
   1863     /* non-zero values will be set by user, saving the same*/
   1864     m_eProfile = eProfile;
   1865     m_eLevel = eLevel;
   1866     DEBUG_PRINT_HIGH("Profile/Level set equal to %d/%d",m_eProfile, m_eLevel);
   1867   }
   1868 
   1869   DEBUG_PRINT_LOW("\n Validating Profile/Level from table");
   1870   if(!venc_validate_profile_level(&eProfile, &eLevel))
   1871   {
   1872     DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed");
   1873     return false;
   1874   }
   1875 
   1876   if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
   1877   {
   1878     DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and "
   1879       "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile,
   1880       OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
   1881     if(eProfile == OMX_VIDEO_MPEG4ProfileSimple)
   1882     {
   1883       requested_profile.profile = VEN_PROFILE_MPEG4_SP;
   1884       profile_tbl = (unsigned int const *)
   1885           (&mpeg4_profile_level_table[MPEG4_SP_START]);
   1886       profile_tbl += MPEG4_720P_LEVEL*5;
   1887     }
   1888     else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
   1889     {
   1890       requested_profile.profile = VEN_PROFILE_MPEG4_ASP;
   1891       profile_tbl = (unsigned int const *)
   1892           (&mpeg4_profile_level_table[MPEG4_ASP_START]);
   1893       profile_tbl += MPEG4_720P_LEVEL*5;
   1894     }
   1895     else
   1896     {
   1897       DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u",
   1898         eProfile);
   1899       return false;
   1900     }
   1901 
   1902     DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
   1903       "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
   1904       "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
   1905       OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
   1906 
   1907     if(mb_per_frame >= 3600)
   1908     {
   1909       if(requested_profile.profile == VEN_PROFILE_MPEG4_ASP)
   1910         requested_level.level = VEN_LEVEL_MPEG4_5;
   1911       if(requested_profile.profile == VEN_PROFILE_MPEG4_SP)
   1912         requested_level.level = VEN_LEVEL_MPEG4_6;
   1913     }
   1914     else
   1915     {
   1916       switch(eLevel)
   1917       {
   1918       case OMX_VIDEO_MPEG4Level0:
   1919         requested_level.level = VEN_LEVEL_MPEG4_0;
   1920         break;
   1921       case OMX_VIDEO_MPEG4Level1:
   1922         requested_level.level = VEN_LEVEL_MPEG4_1;
   1923         break;
   1924       case OMX_VIDEO_MPEG4Level2:
   1925         requested_level.level = VEN_LEVEL_MPEG4_2;
   1926         break;
   1927       case OMX_VIDEO_MPEG4Level3:
   1928         requested_level.level = VEN_LEVEL_MPEG4_3;
   1929         break;
   1930       case OMX_VIDEO_MPEG4Level4a:
   1931         requested_level.level = VEN_LEVEL_MPEG4_4;
   1932         break;
   1933       case OMX_VIDEO_MPEG4Level5:
   1934         mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den);
   1935 		if((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) &&
   1936            (mb_per_sec >= profile_tbl[1]))
   1937         {
   1938           DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution");
   1939           requested_level.level = VEN_LEVEL_MPEG4_6;
   1940         }
   1941         else
   1942         {
   1943           DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution");
   1944           requested_level.level = VEN_LEVEL_MPEG4_5;
   1945         }
   1946         break;
   1947       default:
   1948         return false;
   1949         // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
   1950         break;
   1951       }
   1952     }
   1953   }
   1954   else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
   1955   {
   1956     if(eProfile == OMX_VIDEO_H263ProfileBaseline)
   1957     {
   1958       requested_profile.profile = VEN_PROFILE_H263_BASELINE;
   1959     }
   1960     else
   1961     {
   1962       DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u",
   1963         requested_profile.profile);
   1964       return false;
   1965     }
   1966     //profile level
   1967     switch(eLevel)
   1968     {
   1969     case OMX_VIDEO_H263Level10:
   1970       requested_level.level = VEN_LEVEL_H263_10;
   1971       break;
   1972     case OMX_VIDEO_H263Level20:
   1973       requested_level.level = VEN_LEVEL_H263_20;
   1974       break;
   1975     case OMX_VIDEO_H263Level30:
   1976       requested_level.level = VEN_LEVEL_H263_30;
   1977       break;
   1978     case OMX_VIDEO_H263Level40:
   1979       requested_level.level = VEN_LEVEL_H263_40;
   1980       break;
   1981     case OMX_VIDEO_H263Level45:
   1982       requested_level.level = VEN_LEVEL_H263_45;
   1983       break;
   1984     case OMX_VIDEO_H263Level50:
   1985       requested_level.level = VEN_LEVEL_H263_50;
   1986       break;
   1987     case OMX_VIDEO_H263Level60:
   1988       requested_level.level = VEN_LEVEL_H263_60;
   1989       break;
   1990     case OMX_VIDEO_H263Level70:
   1991       requested_level.level = VEN_LEVEL_H263_70;
   1992       break;
   1993     default:
   1994       return false;
   1995       break;
   1996     }
   1997   }
   1998   else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
   1999   {
   2000     if(eProfile == OMX_VIDEO_AVCProfileBaseline)
   2001     {
   2002       requested_profile.profile = VEN_PROFILE_H264_BASELINE;
   2003     }
   2004     else if(eProfile == OMX_VIDEO_AVCProfileMain)
   2005     {
   2006       requested_profile.profile = VEN_PROFILE_H264_MAIN;
   2007     }
   2008     else if(eProfile == OMX_VIDEO_AVCProfileHigh)
   2009     {
   2010       requested_profile.profile = VEN_PROFILE_H264_HIGH;
   2011     }
   2012     else
   2013     {
   2014       DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u",
   2015         requested_profile.profile);
   2016       return false;
   2017     }
   2018     //profile level
   2019     switch(eLevel)
   2020     {
   2021     case OMX_VIDEO_AVCLevel1:
   2022       requested_level.level = VEN_LEVEL_H264_1;
   2023       break;
   2024     case OMX_VIDEO_AVCLevel1b:
   2025       requested_level.level = VEN_LEVEL_H264_1b;
   2026       break;
   2027     case OMX_VIDEO_AVCLevel11:
   2028       requested_level.level = VEN_LEVEL_H264_1p1;
   2029       break;
   2030     case OMX_VIDEO_AVCLevel12:
   2031       requested_level.level = VEN_LEVEL_H264_1p2;
   2032       break;
   2033     case OMX_VIDEO_AVCLevel13:
   2034       requested_level.level = VEN_LEVEL_H264_1p3;
   2035       break;
   2036     case OMX_VIDEO_AVCLevel2:
   2037       requested_level.level = VEN_LEVEL_H264_2;
   2038       break;
   2039     case OMX_VIDEO_AVCLevel21:
   2040       requested_level.level = VEN_LEVEL_H264_2p1;
   2041       break;
   2042     case OMX_VIDEO_AVCLevel22:
   2043       requested_level.level = VEN_LEVEL_H264_2p2;
   2044       break;
   2045     case OMX_VIDEO_AVCLevel3:
   2046       requested_level.level = VEN_LEVEL_H264_3;
   2047       break;
   2048     case OMX_VIDEO_AVCLevel31:
   2049       requested_level.level = VEN_LEVEL_H264_3p1;
   2050       break;
   2051     case OMX_VIDEO_AVCLevel32:
   2052       requested_level.level = VEN_LEVEL_H264_3p2;
   2053       break;
   2054     case OMX_VIDEO_AVCLevel4:
   2055       requested_level.level = VEN_LEVEL_H264_4;
   2056       break;
   2057     default :
   2058       DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %u",
   2059         requested_level.level);
   2060       return false;
   2061       break;
   2062     }
   2063   }
   2064   if(!m_profile_set)
   2065   {
   2066     ioctl_msg.in = (void*)&requested_profile;
   2067     ioctl_msg.out = NULL;
   2068     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0)
   2069     {
   2070       DEBUG_PRINT_ERROR("\nERROR: Request for setting profile failed");
   2071       return false;
   2072     }
   2073     codec_profile.profile = requested_profile.profile;
   2074     m_profile_set = true;
   2075   }
   2076 
   2077   if(!m_level_set)
   2078   {
   2079     ioctl_msg.in = (void*)&requested_level;
   2080     ioctl_msg.out = NULL;
   2081     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0)
   2082     {
   2083       DEBUG_PRINT_ERROR("\nERROR: Request for setting profile level failed");
   2084       return false;
   2085     }
   2086     profile_level.level = requested_level.level;
   2087     m_level_set = true;
   2088   }
   2089 
   2090   return true;
   2091 }
   2092 
   2093 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
   2094 {
   2095   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   2096   struct venc_voptimingcfg vop_timing_cfg;
   2097 
   2098   DEBUG_PRINT_LOW("\n venc_set_voptiming_cfg: TimeRes = %u",
   2099     TimeIncRes);
   2100 
   2101   vop_timing_cfg.voptime_resolution = TimeIncRes;
   2102 
   2103   ioctl_msg.in = (void*)&vop_timing_cfg;
   2104   ioctl_msg.out = NULL;
   2105   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0)
   2106   {
   2107     DEBUG_PRINT_ERROR("\nERROR: Request for setting Vop Timing failed");
   2108     return false;
   2109   }
   2110 
   2111   voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
   2112   return true;
   2113 }
   2114 
   2115 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
   2116 {
   2117   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   2118   struct venc_intraperiod intraperiod_cfg;
   2119 
   2120   DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u",
   2121     nPFrames);
   2122   intraperiod_cfg.num_pframes = nPFrames;
   2123   if((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) ||
   2124      (codec_profile.profile == VEN_PROFILE_H264_MAIN) ||
   2125      (codec_profile.profile == VEN_PROFILE_H264_HIGH))
   2126   {
   2127 #ifdef MAX_RES_1080P
   2128     if (nBFrames)
   2129     {
   2130       DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported");
   2131       intraperiod_cfg.num_bframes = 1;
   2132     }
   2133     else
   2134       intraperiod_cfg.num_bframes = 0;
   2135 #else
   2136     if(nBFrames)
   2137     {
   2138       DEBUG_PRINT_ERROR("B frames not supported");
   2139       intraperiod_cfg.num_bframes = 0;
   2140     }
   2141     else
   2142     {
   2143       DEBUG_PRINT_ERROR("B frames not supported");
   2144       intraperiod_cfg.num_bframes = 0;
   2145     }
   2146 #endif
   2147   }
   2148   else
   2149     intraperiod_cfg.num_bframes = 0;
   2150 
   2151   DEBUG_PRINT_ERROR("\n venc_set_intra_period: nPFrames = %u nBFrames = %u",
   2152                     intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes);
   2153   ioctl_msg.in = (void*)&intraperiod_cfg;
   2154   ioctl_msg.out = NULL;
   2155   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0)
   2156   {
   2157     DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed");
   2158     return false;
   2159   }
   2160 
   2161   intra_period.num_pframes = intraperiod_cfg.num_pframes;
   2162   intra_period.num_bframes = intraperiod_cfg.num_bframes;
   2163   return true;
   2164 }
   2165 
   2166 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
   2167 {
   2168   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   2169   struct venc_entropycfg entropy_cfg;
   2170 
   2171   memset(&entropy_cfg,0,sizeof(entropy_cfg));
   2172   DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level);
   2173 
   2174   if(enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)){
   2175     entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC;
   2176       if (i_cabac_level == 0) {
   2177          entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
   2178       }
   2179 #ifdef MAX_RES_1080P
   2180       else
   2181       {
   2182         DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to  model 0",i_cabac_level);
   2183         entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0;
   2184       }
   2185 #else
   2186       else if (i_cabac_level == 1) {
   2187          entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1;
   2188       }
   2189       else if (i_cabac_level == 2) {
   2190          entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2;
   2191       }
   2192 #endif
   2193   }
   2194   else if(!enable){
   2195     entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC;
   2196     }
   2197   else{
   2198     DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile");
   2199     return false;
   2200   }
   2201 
   2202   ioctl_msg.in = (void*)&entropy_cfg;
   2203   ioctl_msg.out = NULL;
   2204   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0)
   2205   {
   2206     DEBUG_PRINT_ERROR("\nERROR: Request for setting entropy config failed");
   2207     return false;
   2208   }
   2209   entropy.longentropysel = entropy_cfg.longentropysel;
   2210   entropy.cabacmodel  = entropy_cfg.cabacmodel;
   2211   return true;
   2212 }
   2213 
   2214 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
   2215 {
   2216  venc_ioctl_msg ioctl_msg = {NULL, NULL};
   2217   bool status = true;
   2218   struct venc_multiclicecfg multislice_cfg;
   2219 
   2220   if((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)){
   2221     multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB;
   2222     multislice_cfg.mslice_size = nSlicesize;
   2223     }
   2224   else{
   2225     multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
   2226     multislice_cfg.mslice_size = 0;
   2227   }
   2228 
   2229   DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
   2230                   multislice_cfg.mslice_size);
   2231 
   2232   ioctl_msg.in = (void*)&multislice_cfg;
   2233   ioctl_msg.out = NULL;
   2234   if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0)
   2235   {
   2236     DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
   2237     status = false;
   2238   }
   2239   else
   2240   {
   2241     multislice.mslice_mode = multislice_cfg.mslice_mode;
   2242     multislice.mslice_size = nSlicesize;
   2243   }
   2244   return status;
   2245 }
   2246 
   2247 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
   2248 {
   2249  venc_ioctl_msg ioctl_msg = {NULL, NULL};
   2250   bool status = true;
   2251   struct venc_intrarefresh intraRefresh_cfg;
   2252 
   2253   // There is no disabled mode.  Disabled mode is indicated by a 0 count.
   2254   if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax)
   2255   {
   2256     intraRefresh_cfg.irmode = VEN_IR_OFF;
   2257     intraRefresh_cfg.mbcount = 0;
   2258   }
   2259   else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
   2260            (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8)))
   2261   {
   2262     intraRefresh_cfg.irmode = VEN_IR_CYCLIC;
   2263     intraRefresh_cfg.mbcount = irMBs;
   2264   }
   2265   else
   2266   {
   2267     DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:"
   2268                       "mb count: %d, mb mode:%d", irMBs, ir_mode);
   2269     return false;
   2270   }
   2271 
   2272   ioctl_msg.in = (void*)&intraRefresh_cfg;
   2273   ioctl_msg.out = NULL;
   2274   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0)
   2275   {
   2276     DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra Refresh failed");
   2277     status = false;
   2278   }
   2279   else
   2280   {
   2281     intra_refresh.irmode = intraRefresh_cfg.irmode;
   2282     intra_refresh.mbcount = intraRefresh_cfg.mbcount;
   2283   }
   2284   return status;
   2285 }
   2286 
   2287 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
   2288 {
   2289    venc_ioctl_msg ioctl_msg = {NULL, NULL};
   2290    bool status = true;
   2291    struct venc_headerextension hec_cfg;
   2292    struct venc_multiclicecfg multislice_cfg;
   2293 
   2294    if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) {
   2295       if (error_resilience->bEnableHEC) {
   2296          hec_cfg.header_extension = 1;
   2297       }
   2298       else {
   2299          hec_cfg.header_extension = 0;
   2300       }
   2301 
   2302       ioctl_msg.in = (void*)&hec_cfg;
   2303       ioctl_msg.out = NULL;
   2304       if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) {
   2305          DEBUG_PRINT_ERROR("\nERROR: Request for setting HEader Error correction failed");
   2306          return false;
   2307       }
   2308       hec.header_extension = error_resilience->bEnableHEC;
   2309    }
   2310 
   2311    if (error_resilience->bEnableRVLC) {
   2312      DEBUG_PRINT_ERROR("\n RVLC is not Supported");
   2313      return false;
   2314    }
   2315 
   2316    if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
   2317        (error_resilience->bEnableDataPartitioning)) {
   2318      DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264");
   2319      return false;
   2320      }
   2321 
   2322    if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
   2323             (error_resilience->nResynchMarkerSpacing)) {
   2324      multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
   2325        multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing;
   2326      }
   2327    else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 &&
   2328             error_resilience->bEnableDataPartitioning) {
   2329       multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
   2330       multislice_cfg.mslice_size = 0;
   2331       }
   2332       else {
   2333         multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
   2334         multislice_cfg.mslice_size = 0;
   2335         }
   2336    DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode,
   2337                    multislice_cfg.mslice_size);
   2338    ioctl_msg.in = (void*)&multislice_cfg;
   2339    ioctl_msg.out = NULL;
   2340    if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) {
   2341       DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed");
   2342       status = false;
   2343    }
   2344    else
   2345    {
   2346      multislice.mslice_mode = multislice_cfg.mslice_mode ;
   2347      multislice.mslice_size = multislice_cfg.mslice_size;
   2348 
   2349    }
   2350    return status;
   2351 }
   2352 
   2353 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
   2354 {
   2355   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   2356   struct venc_dbcfg filter_cfg;
   2357 
   2358   memset(&filter_cfg, 0, sizeof(filter_cfg));
   2359   DEBUG_PRINT_LOW("\n venc_set_inloop_filter: %u",loopfilter);
   2360 
   2361   if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){
   2362     filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY;
   2363   }
   2364   else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){
   2365     filter_cfg.db_mode = VEN_DB_DISABLE;
   2366   }
   2367   else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){
   2368     filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY;
   2369   }
   2370   filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0;
   2371 
   2372   ioctl_msg.in = (void*)&filter_cfg;
   2373   ioctl_msg.out = NULL;
   2374   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0)
   2375   {
   2376     DEBUG_PRINT_ERROR("\nERROR: Request for setting inloop filter failed");
   2377     return false;
   2378   }
   2379 
   2380   dbkfilter.db_mode = filter_cfg.db_mode;
   2381   dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
   2382   return true;
   2383 }
   2384 
   2385 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
   2386 {
   2387   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   2388   struct venc_targetbitrate bitrate_cfg;
   2389 
   2390   DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u",
   2391     nTargetBitrate);
   2392   bitrate_cfg.target_bitrate = nTargetBitrate ;
   2393   ioctl_msg.in = (void*)&bitrate_cfg;
   2394   ioctl_msg.out = NULL;
   2395   if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0)
   2396   {
   2397     DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed");
   2398     return false;
   2399   }
   2400   m_sVenc_cfg.targetbitrate = nTargetBitrate;
   2401   bitrate.target_bitrate = nTargetBitrate;
   2402   if(!config)
   2403   {
   2404     m_level_set = false;
   2405     if(venc_set_profile_level(0, 0))
   2406     {
   2407       DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d\n",profile_level.level);
   2408     }
   2409   }
   2410   return true;
   2411 }
   2412 
   2413 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
   2414 {
   2415   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   2416   struct venc_framerate frame_rate_cfg;
   2417 
   2418   Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
   2419 
   2420   DEBUG_PRINT_LOW("\n venc_set_encode_framerate: framerate(Q16) = %u,NR: %d, DR: %d",
   2421                   encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
   2422 
   2423   ioctl_msg.in = (void*)&frame_rate_cfg;
   2424   ioctl_msg.out = NULL;
   2425   if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE,
   2426       (void*)&ioctl_msg) < 0)
   2427   {
   2428     DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed");
   2429     return false;
   2430   }
   2431 
   2432   m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
   2433   m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
   2434   if(!config)
   2435   {
   2436     m_level_set = false;
   2437     if(venc_set_profile_level(0, 0))
   2438     {
   2439       DEBUG_PRINT_LOW("Calling set level (Framerate) with %d\n",profile_level.level);
   2440     }
   2441   }
   2442   return true;
   2443 }
   2444 
   2445 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
   2446 {
   2447   venc_ioctl_msg ioctl_msg = {NULL, NULL};
   2448   DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format);
   2449 
   2450   if(color_format == OMX_COLOR_FormatYUV420SemiPlanar)
   2451   {
   2452 #ifdef MAX_RES_1080P
   2453   m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
   2454 #else
   2455     m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
   2456 #endif
   2457   }
   2458   else
   2459   {
   2460     DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format);
   2461 #ifdef MAX_RES_1080P
   2462     m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA;
   2463 #else
   2464     m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12;
   2465 #endif
   2466     DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set");
   2467   }
   2468   ioctl_msg.in = (void*)&m_sVenc_cfg;
   2469   ioctl_msg.out = NULL;
   2470   if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0)
   2471   {
   2472     DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed");
   2473     return false;
   2474   }
   2475   return true;
   2476 }
   2477 
   2478 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
   2479 {
   2480   DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
   2481   if(intra_vop_refresh == OMX_TRUE)
   2482   {
   2483     if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0)
   2484     {
   2485       DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed");
   2486       return false;
   2487     }
   2488   }
   2489   else
   2490   {
   2491     DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect");
   2492   }
   2493   return true;
   2494 }
   2495 
   2496 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
   2497 {
   2498   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   2499   bool status = true;
   2500   struct venc_ratectrlcfg ratectrl_cfg;
   2501 
   2502   //rate control
   2503   switch(eControlRate)
   2504   {
   2505   case OMX_Video_ControlRateDisable:
   2506     ratectrl_cfg.rcmode = VEN_RC_OFF;
   2507     break;
   2508   case OMX_Video_ControlRateVariableSkipFrames:
   2509     ratectrl_cfg.rcmode = VEN_RC_VBR_VFR;
   2510     break;
   2511   case OMX_Video_ControlRateVariable:
   2512     ratectrl_cfg.rcmode = VEN_RC_VBR_CFR;
   2513     break;
   2514   case OMX_Video_ControlRateConstantSkipFrames:
   2515     ratectrl_cfg.rcmode = VEN_RC_CBR_VFR;
   2516     break;
   2517   case OMX_Video_ControlRateConstant:
   2518     ratectrl_cfg.rcmode = VEN_RC_CBR_CFR;
   2519     break;
   2520   default:
   2521     status = false;
   2522     break;
   2523   }
   2524 
   2525   if(status)
   2526   {
   2527     ioctl_msg.in = (void*)&ratectrl_cfg;
   2528     ioctl_msg.out = NULL;
   2529     if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0)
   2530     {
   2531       DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed");
   2532       status = false;
   2533     }
   2534     else
   2535       rate_ctrl.rcmode = ratectrl_cfg.rcmode;
   2536   }
   2537   return status;
   2538 }
   2539 
   2540 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
   2541 {
   2542   bool status = true;
   2543   if(eProfile == NULL || eLevel == NULL)
   2544   {
   2545     return false;
   2546   }
   2547 
   2548   if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
   2549   {
   2550     switch(codec_profile.profile)
   2551     {
   2552     case VEN_PROFILE_MPEG4_SP:
   2553       *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2554       break;
   2555     case VEN_PROFILE_MPEG4_ASP:
   2556       *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   2557       break;
   2558     default:
   2559       *eProfile = OMX_VIDEO_MPEG4ProfileMax;
   2560       status = false;
   2561       break;
   2562     }
   2563 
   2564     if(!status)
   2565     {
   2566       return status;
   2567     }
   2568 
   2569     //profile level
   2570     switch(profile_level.level)
   2571     {
   2572     case VEN_LEVEL_MPEG4_0:
   2573       *eLevel = OMX_VIDEO_MPEG4Level0;
   2574       break;
   2575     case VEN_LEVEL_MPEG4_1:
   2576       *eLevel = OMX_VIDEO_MPEG4Level1;
   2577       break;
   2578     case VEN_LEVEL_MPEG4_2:
   2579       *eLevel = OMX_VIDEO_MPEG4Level2;
   2580       break;
   2581     case VEN_LEVEL_MPEG4_3:
   2582       *eLevel = OMX_VIDEO_MPEG4Level3;
   2583       break;
   2584     case VEN_LEVEL_MPEG4_4:
   2585       *eLevel = OMX_VIDEO_MPEG4Level4a;
   2586       break;
   2587     case VEN_LEVEL_MPEG4_5:
   2588     case VEN_LEVEL_MPEG4_6:
   2589       *eLevel = OMX_VIDEO_MPEG4Level5;
   2590       break;
   2591     default:
   2592       *eLevel = OMX_VIDEO_MPEG4LevelMax;
   2593       status =  false;
   2594       break;
   2595     }
   2596   }
   2597   else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
   2598   {
   2599     if(codec_profile.profile == VEN_PROFILE_H263_BASELINE)
   2600     {
   2601       *eProfile = OMX_VIDEO_H263ProfileBaseline;
   2602     }
   2603     else
   2604     {
   2605       *eProfile = OMX_VIDEO_H263ProfileMax;
   2606       return false;
   2607     }
   2608     switch(profile_level.level)
   2609     {
   2610     case VEN_LEVEL_H263_10:
   2611       *eLevel = OMX_VIDEO_H263Level10;
   2612       break;
   2613     case VEN_LEVEL_H263_20:
   2614       *eLevel = OMX_VIDEO_H263Level20;
   2615       break;
   2616     case VEN_LEVEL_H263_30:
   2617       *eLevel = OMX_VIDEO_H263Level30;
   2618       break;
   2619     case VEN_LEVEL_H263_40:
   2620       *eLevel = OMX_VIDEO_H263Level40;
   2621       break;
   2622     case VEN_LEVEL_H263_45:
   2623       *eLevel = OMX_VIDEO_H263Level45;
   2624       break;
   2625     case VEN_LEVEL_H263_50:
   2626       *eLevel = OMX_VIDEO_H263Level50;
   2627       break;
   2628     case VEN_LEVEL_H263_60:
   2629       *eLevel = OMX_VIDEO_H263Level60;
   2630       break;
   2631     case VEN_LEVEL_H263_70:
   2632       *eLevel = OMX_VIDEO_H263Level70;
   2633       break;
   2634     default:
   2635       *eLevel = OMX_VIDEO_H263LevelMax;
   2636       status = false;
   2637       break;
   2638     }
   2639   }
   2640   else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
   2641   {
   2642     switch(codec_profile.profile)
   2643     {
   2644     case VEN_PROFILE_H264_BASELINE:
   2645       *eProfile = OMX_VIDEO_AVCProfileBaseline;
   2646       break;
   2647     case VEN_PROFILE_H264_MAIN:
   2648       *eProfile = OMX_VIDEO_AVCProfileMain;
   2649       break;
   2650     case VEN_PROFILE_H264_HIGH:
   2651       *eProfile = OMX_VIDEO_AVCProfileHigh;
   2652       break;
   2653     default:
   2654       *eProfile = OMX_VIDEO_AVCProfileMax;
   2655       status = false;
   2656       break;
   2657     }
   2658 
   2659     if(!status)
   2660     {
   2661       return status;
   2662     }
   2663 
   2664     switch(profile_level.level)
   2665     {
   2666     case VEN_LEVEL_H264_1:
   2667       *eLevel = OMX_VIDEO_AVCLevel1;
   2668       break;
   2669     case VEN_LEVEL_H264_1b:
   2670       *eLevel = OMX_VIDEO_AVCLevel1b;
   2671       break;
   2672     case VEN_LEVEL_H264_1p1:
   2673       *eLevel = OMX_VIDEO_AVCLevel11;
   2674       break;
   2675     case VEN_LEVEL_H264_1p2:
   2676       *eLevel = OMX_VIDEO_AVCLevel12;
   2677       break;
   2678     case VEN_LEVEL_H264_1p3:
   2679       *eLevel = OMX_VIDEO_AVCLevel13;
   2680       break;
   2681     case VEN_LEVEL_H264_2:
   2682       *eLevel = OMX_VIDEO_AVCLevel2;
   2683       break;
   2684     case VEN_LEVEL_H264_2p1:
   2685       *eLevel = OMX_VIDEO_AVCLevel21;
   2686       break;
   2687     case VEN_LEVEL_H264_2p2:
   2688       *eLevel = OMX_VIDEO_AVCLevel22;
   2689       break;
   2690     case VEN_LEVEL_H264_3:
   2691       *eLevel = OMX_VIDEO_AVCLevel3;
   2692       break;
   2693     case VEN_LEVEL_H264_3p1:
   2694       *eLevel = OMX_VIDEO_AVCLevel31;
   2695       break;
   2696     case VEN_LEVEL_H264_3p2:
   2697       *eLevel = OMX_VIDEO_AVCLevel32;
   2698       break;
   2699     case VEN_LEVEL_H264_4:
   2700       *eLevel = OMX_VIDEO_AVCLevel4;
   2701       break;
   2702 	  default :
   2703       *eLevel = OMX_VIDEO_AVCLevelMax;
   2704       status = false;
   2705       break;
   2706     }
   2707   }
   2708   return status;
   2709 }
   2710 
   2711 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
   2712 {
   2713   OMX_U32 new_profile = 0, new_level = 0;
   2714   unsigned const int *profile_tbl = NULL;
   2715   OMX_U32 mb_per_frame, mb_per_sec;
   2716   bool profile_level_found = false;
   2717 
   2718   DEBUG_PRINT_LOW("\n Init profile table for respective codec");
   2719   //validate the ht,width,fps,bitrate and set the appropriate profile and level
   2720   if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)
   2721   {
   2722       if(*eProfile == 0)
   2723       {
   2724         if(!m_profile_set)
   2725         {
   2726           *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2727         }
   2728         else
   2729         {
   2730           switch(codec_profile.profile)
   2731           {
   2732           case VEN_PROFILE_MPEG4_ASP:
   2733               *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   2734             break;
   2735           case VEN_PROFILE_MPEG4_SP:
   2736               *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2737             break;
   2738           default:
   2739             DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
   2740             return false;
   2741           }
   2742         }
   2743       }
   2744 
   2745       if(*eLevel == 0 && !m_level_set)
   2746       {
   2747         *eLevel = OMX_VIDEO_MPEG4LevelMax;
   2748       }
   2749 
   2750       if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple)
   2751       {
   2752         profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
   2753       }
   2754       else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
   2755       {
   2756         profile_tbl = (unsigned int const *)
   2757           (&mpeg4_profile_level_table[MPEG4_ASP_START]);
   2758       }
   2759       else
   2760       {
   2761         DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile);
   2762         return false;
   2763       }
   2764   }
   2765   else if(m_sVenc_cfg.codectype == VEN_CODEC_H264)
   2766   {
   2767       if(*eProfile == 0)
   2768       {
   2769         if(!m_profile_set)
   2770         {
   2771           *eProfile = OMX_VIDEO_AVCProfileBaseline;
   2772         }
   2773         else
   2774         {
   2775           switch(codec_profile.profile)
   2776           {
   2777           case VEN_PROFILE_H264_BASELINE:
   2778             *eProfile = OMX_VIDEO_AVCProfileBaseline;
   2779             break;
   2780           case VEN_PROFILE_H264_MAIN:
   2781             *eProfile = OMX_VIDEO_AVCProfileMain;
   2782             break;
   2783           case VEN_PROFILE_H264_HIGH:
   2784             *eProfile = OMX_VIDEO_AVCProfileHigh;
   2785             break;
   2786           default:
   2787             DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
   2788             return false;
   2789           }
   2790         }
   2791       }
   2792 
   2793       if(*eLevel == 0 && !m_level_set)
   2794       {
   2795         *eLevel = OMX_VIDEO_AVCLevelMax;
   2796       }
   2797 
   2798       if(*eProfile == OMX_VIDEO_AVCProfileBaseline)
   2799       {
   2800         profile_tbl = (unsigned int const *)h264_profile_level_table;
   2801       }
   2802       else if(*eProfile == OMX_VIDEO_AVCProfileHigh)
   2803       {
   2804         profile_tbl = (unsigned int const *)
   2805           (&h264_profile_level_table[H264_HP_START]);
   2806       }
   2807       else if(*eProfile == OMX_VIDEO_AVCProfileMain)
   2808       {
   2809         profile_tbl = (unsigned int const *)
   2810           (&h264_profile_level_table[H264_MP_START]);
   2811       }
   2812       else
   2813       {
   2814         DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile);
   2815         return false;
   2816       }
   2817   }
   2818   else if(m_sVenc_cfg.codectype == VEN_CODEC_H263)
   2819   {
   2820       if(*eProfile == 0)
   2821       {
   2822         if(!m_profile_set)
   2823         {
   2824           *eProfile = OMX_VIDEO_H263ProfileBaseline;
   2825         }
   2826         else
   2827         {
   2828           switch(codec_profile.profile)
   2829           {
   2830           case VEN_PROFILE_H263_BASELINE:
   2831             *eProfile = OMX_VIDEO_H263ProfileBaseline;
   2832             break;
   2833           default:
   2834             DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__);
   2835             return false;
   2836           }
   2837         }
   2838       }
   2839 
   2840       if(*eLevel == 0 && !m_level_set)
   2841       {
   2842         *eLevel = OMX_VIDEO_H263LevelMax;
   2843       }
   2844 
   2845       if(*eProfile == OMX_VIDEO_H263ProfileBaseline)
   2846       {
   2847         profile_tbl = (unsigned int const *)h263_profile_level_table;
   2848       }
   2849       else
   2850       {
   2851         DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile);
   2852         return false;
   2853       }
   2854   }
   2855   else
   2856   {
   2857     DEBUG_PRINT_LOW("\n Invalid codec type");
   2858     return false;
   2859   }
   2860 
   2861   mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)*
   2862                    ((m_sVenc_cfg.input_width + 15)>> 4);
   2863 
   2864   if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4))
   2865   {
   2866     if(codec_profile.profile == VEN_PROFILE_MPEG4_ASP)
   2867       profile_level.level = VEN_LEVEL_MPEG4_5;
   2868     if(codec_profile.profile == VEN_PROFILE_MPEG4_SP)
   2869       profile_level.level = VEN_LEVEL_MPEG4_6;
   2870     {
   2871       new_level = profile_level.level;
   2872       new_profile = codec_profile.profile;
   2873       return true;
   2874     }
   2875   }
   2876 
   2877   mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
   2878 
   2879   do{
   2880       if(mb_per_frame <= (int)profile_tbl[0])
   2881       {
   2882         if(mb_per_sec <= (int)profile_tbl[1])
   2883         {
   2884           if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2])
   2885           {
   2886               new_level = (int)profile_tbl[3];
   2887               new_profile = (int)profile_tbl[4];
   2888               profile_level_found = true;
   2889               DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level);
   2890               break;
   2891           }
   2892         }
   2893       }
   2894       profile_tbl = profile_tbl + 5;
   2895   }while(profile_tbl[0] != 0);
   2896 
   2897   if (profile_level_found != true)
   2898   {
   2899     DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n");
   2900     return false;
   2901   }
   2902 
   2903   if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
   2904      || (*eLevel == OMX_VIDEO_H263LevelMax))
   2905   {
   2906     *eLevel = new_level;
   2907   }
   2908   DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu"
   2909       "Level = %lu", __func__, *eProfile, *eLevel);
   2910 
   2911   return true;
   2912 }
   2913 
   2914 bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate)
   2915 {
   2916   unsigned const int *profile_tbl = NULL;
   2917 
   2918   switch(m_sVenc_cfg.codectype)
   2919   {
   2920     case VEN_CODEC_MPEG4:
   2921       if(m_eProfile == OMX_VIDEO_MPEG4ProfileSimple)
   2922       {
   2923         profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
   2924       }
   2925       else if(m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple)
   2926       {
   2927         profile_tbl = (unsigned int const *)
   2928           (&mpeg4_profile_level_table[MPEG4_ASP_START]);
   2929       }
   2930       else
   2931       {
   2932         DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile);
   2933         return false;
   2934       }
   2935       break;
   2936     case VEN_CODEC_H264:
   2937       if(m_eProfile == OMX_VIDEO_AVCProfileBaseline)
   2938       {
   2939         profile_tbl = (unsigned int const *)h264_profile_level_table;
   2940       }
   2941       else if(m_eProfile == OMX_VIDEO_AVCProfileHigh)
   2942       {
   2943         profile_tbl = (unsigned int const *)
   2944           (&h264_profile_level_table[H264_HP_START]);
   2945       }
   2946       else if(m_eProfile == OMX_VIDEO_AVCProfileMain)
   2947       {
   2948         profile_tbl = (unsigned int const *)
   2949           (&h264_profile_level_table[H264_MP_START]);
   2950       }
   2951       else
   2952       {
   2953         DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile);
   2954         return false;
   2955       }
   2956 
   2957       break;
   2958     case VEN_CODEC_H263:
   2959       if(m_eProfile == OMX_VIDEO_H263ProfileBaseline)
   2960       {
   2961         profile_tbl = (unsigned int const *)h263_profile_level_table;
   2962       }
   2963       else
   2964       {
   2965         DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile);
   2966         return false;
   2967       }
   2968       break;
   2969     default:
   2970       DEBUG_PRINT_ERROR("%s: unknown codec type", __func__);
   2971       return false;
   2972   }
   2973   while(profile_tbl[0] != 0)
   2974   {
   2975     if(profile_tbl[3] == m_eLevel)
   2976     {
   2977       if(nTargetBitrate > profile_tbl[2])
   2978       {
   2979          DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]"
   2980             " is %u", m_eProfile, m_eLevel, profile_tbl[2]);
   2981         return false;
   2982       }
   2983     }
   2984     profile_tbl += 5;
   2985   }
   2986   return true;
   2987 }
   2988 
   2989 #ifdef _ANDROID_ICS_
   2990 bool venc_dev::venc_set_meta_mode(bool mode)
   2991 {
   2992   venc_ioctl_msg ioctl_msg = {NULL,NULL};
   2993   ioctl_msg.in = &mode;
   2994   DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode);
   2995   if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0)
   2996   {
   2997     DEBUG_PRINT_ERROR(" Set meta buffer mode failed");
   2998     return false;
   2999   }
   3000   return true;
   3001 }
   3002 #endif
   3003