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