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