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